From cb7ae34c52006cb5fc224f416d7968813a9fc5d5 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Thu, 13 Nov 2025 23:58:07 +0100 Subject: [PATCH 1/5] Parser: Fix ERB control flow tags in attribute positions --- src/parser.c | 5 ++ test/parser/attributes_test.rb | 61 +++++++++++++ ...paces_8b8da9205eb731ac258036f24249144e.txt | 70 +++++++++++++++ ...paces_f5fb22be5ee259a7902533d5e90f2935.txt | 70 +++++++++++++++ ..._line_8f3997e9bb390d529e8a302cd3644924.txt | 77 +++++++++++++++++ ...value_81e52238e369e409d9df110376cc3aa3.txt | 59 +++++++++++++ ...butes_befdf95a4fadd41e440a471f38e443da.txt | 74 ++++++++++++++++ ..._else_bb59fa557fa46906ac8d7b2ac4948269.txt | 86 +++++++++++++++++++ ...nless_a63ab0987a8655064d1dcbe0ac4267f7.txt | 50 +++++++++++ ...block_ad2a48dc8c52e2e1b15ed1c970d12457.txt | 70 +++++++++++++++ ...ibute_661703bbd4a517e45d7ccf10bb92dd41.txt | 64 ++++++++++++++ ...nside_2e2b58a4804aa16c21405c4371206b2a.txt | 63 ++++++++++++++ ...butes_0e265aed6fa4a1f4adc75b32f35bd862.txt | 73 ++++++++++++++++ ..._tags_80b50d0bc25df0f6805558f541ff8d08.txt | 50 +++++++++++ ...butes_2b453534ea13ee20fab205fee722364a.txt | 70 +++++++++++++++ ...butes_f995c179776fa746db8f0a5e80590c75.txt | 63 ++++++++++++++ 16 files changed, 1005 insertions(+) create mode 100644 test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt create mode 100644 test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt create mode 100644 test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt create mode 100644 test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt create mode 100644 test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt create mode 100644 test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt create mode 100644 test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt create mode 100644 test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt create mode 100644 test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt create mode 100644 test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt create mode 100644 test/snapshots/parser/attributes_test/test_0057_ERB_comment_between_attributes_0e265aed6fa4a1f4adc75b32f35bd862.txt create mode 100644 test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt create mode 100644 test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt create mode 100644 test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt diff --git a/src/parser.c b/src/parser.c index 252f6dfd1..52de4d4b7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -295,6 +295,11 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T TOKEN_EOF )) { if (token_is(parser, TOKEN_ERB_START)) { + const char* tag = parser->current_token->value; + bool is_output_tag = (tag[2] == '='); + + if (!is_output_tag) { break; } + parser_append_literal_node_from_buffer(parser, &buffer, children, start); AST_ERB_CONTENT_NODE_T* erb_node = parser_parse_erb_tag(parser); diff --git a/test/parser/attributes_test.rb b/test/parser/attributes_test.rb index 789d032a2..4c091d603 100644 --- a/test/parser/attributes_test.rb +++ b/test/parser/attributes_test.rb @@ -195,5 +195,66 @@ class AttributesTest < Minitest::Spec test "Empty attribute value with closing bracket immediatly following it" do assert_parsed_snapshot(%(
div-content
)) end + + test "Conditional attribute with ERB control flow and no surrounding spaces" do + assert_parsed_snapshot(%(data-turbo-permanent<% end %>>)) + end + + test "Conditional attribute with ERB control flow with surrounding spaces" do + assert_parsed_snapshot(%( data-turbo-permanent <% end %>>)) + end + + test "Conditional attribute with ERB on separate line" do + assert_parsed_snapshot <<~HTML + data-menu-button<% end %> + class="css-truncate css-truncate-target" + > + HTML + end + + test "Conditional attribute with value" do + assert_parsed_snapshot(%(
data-enabled="true"<% end %>>
)) + end + + test "Multiple conditional attributes" do + assert_parsed_snapshot(%(
data-a<% end %> <% if b? %>data-b<% end %>>
)) + end + + test "Conditional attribute with elsif and else" do + assert_parsed_snapshot(%(
data-primary<% elsif secondary? %>data-secondary<% else %>data-default<% end %>>
)) + end + + test "Conditional attribute with unless" do + assert_parsed_snapshot(%(
data-enabled<% end %>>
)) + end + + test "Multiple attributes in one conditional block" do + assert_parsed_snapshot(%(
data-admin data-role="admin"<% end %>>
)) + end + + test "Conditional boolean attribute" do + assert_parsed_snapshot(%(disabled<% end %> type="text">)) + end + + test "Conditional attribute with output tag inside" do + assert_parsed_snapshot(%(
data-user="<%= user.id %>"<% end %>>
)) + end + + test "ERB comment between attributes" do + assert_parsed_snapshot(%(
data-baz="qux">
)) + end + + test "Conditional attribute with trimming tags" do + assert_parsed_snapshot(%(
data-conditional<%- end -%>>
)) + end + + test "Empty conditional block in attributes" do + assert_parsed_snapshot(%(
<% end %> data-other="value">
)) + end + + test "Nested conditional attributes" do + assert_parsed_snapshot(%(
<% if inner? %>data-inner<% end %><% end %>>
)) + end end end diff --git a/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt new file mode 100644 index 000000000..b28e20c8a --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt @@ -0,0 +1,70 @@ +--- +source: "Parser::AttributesTest#test_0047_Conditional attribute with ERB control flow and no surrounding spaces" +input: "data-turbo-permanent<% end %>>" +--- +@ DocumentNode (location: (1:0)-(1:106)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:106)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:97)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "dialog" (location: (1:1)-(1:7)) + │ ├── tag_closing: ">" (location: (1:96)-(1:97)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:8)-(1:32)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:8)-(1:23)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:8)-(1:23)) + │ │ │ │ └── content: "data-controller" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:23)-(1:24)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:24)-(1:32)) + │ │ │ ├── open_quote: """ (location: (1:24)-(1:25)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:31)) + │ │ │ │ └── content: "dialog" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:31)-(1:32)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:33)-(1:96)) + │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ ├── content: " if local_assigns[:permanent] " (location: (1:35)-(1:65)) + │ │ ├── tag_closing: "%>" (location: (1:65)-(1:67)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:67)-(1:87)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:67)-(1:87)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:67)-(1:87)) + │ │ │ │ └── content: "data-turbo-permanent" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:87)-(1:96)) + │ │ ├── tag_opening: "<%" (location: (1:87)-(1:89)) + │ │ ├── content: " end " (location: (1:89)-(1:94)) + │ │ └── tag_closing: "%>" (location: (1:94)-(1:96)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "dialog" (location: (1:1)-(1:7)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:97)-(1:106)) + │ ├── tag_opening: "" (location: (1:105)-(1:106)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt b/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt new file mode 100644 index 000000000..4094a112e --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt @@ -0,0 +1,70 @@ +--- +source: "Parser::AttributesTest#test_0048_Conditional attribute with ERB control flow with surrounding spaces" +input: " data-turbo-permanent <% end %>>" +--- +@ DocumentNode (location: (1:0)-(1:108)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:108)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:99)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "dialog" (location: (1:1)-(1:7)) + │ ├── tag_closing: ">" (location: (1:98)-(1:99)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:8)-(1:32)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:8)-(1:23)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:8)-(1:23)) + │ │ │ │ └── content: "data-controller" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:23)-(1:24)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:24)-(1:32)) + │ │ │ ├── open_quote: """ (location: (1:24)-(1:25)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:31)) + │ │ │ │ └── content: "dialog" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:31)-(1:32)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:33)-(1:98)) + │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ ├── content: " if local_assigns[:permanent] " (location: (1:35)-(1:65)) + │ │ ├── tag_closing: "%>" (location: (1:65)-(1:67)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:68)-(1:88)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:68)-(1:88)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:68)-(1:88)) + │ │ │ │ └── content: "data-turbo-permanent" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:89)-(1:98)) + │ │ ├── tag_opening: "<%" (location: (1:89)-(1:91)) + │ │ ├── content: " end " (location: (1:91)-(1:96)) + │ │ └── tag_closing: "%>" (location: (1:96)-(1:98)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "dialog" (location: (1:1)-(1:7)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:99)-(1:108)) + │ ├── tag_opening: "" (location: (1:107)-(1:108)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt b/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt new file mode 100644 index 000000000..7043d2212 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt @@ -0,0 +1,77 @@ +--- +source: "Parser::AttributesTest#test_0049_Conditional attribute with ERB on separate line" +input: |2- +data-menu-button<% end %> + class="css-truncate css-truncate-target" +> +--- +@ DocumentNode (location: (1:0)-(5:0)) +└── children: (2 items) + ├── @ HTMLElementNode (location: (1:0)-(4:8)) + │ ├── open_tag: + │ │ └── @ HTMLOpenTagNode (location: (1:0)-(4:1)) + │ │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ │ ├── tag_name: "span" (location: (1:1)-(1:5)) + │ │ ├── tag_closing: ">" (location: (4:0)-(4:1)) + │ │ ├── children: (2 items) + │ │ │ ├── @ ERBIfNode (location: (2:2)-(2:48)) + │ │ │ │ ├── tag_opening: "<%" (location: (2:2)-(2:4)) + │ │ │ │ ├── content: " if @replaceable " (location: (2:4)-(2:21)) + │ │ │ │ ├── tag_closing: "%>" (location: (2:21)-(2:23)) + │ │ │ │ ├── statements: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (2:23)-(2:39)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (2:23)-(2:39)) + │ │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (2:23)-(2:39)) + │ │ │ │ │ │ └── content: "data-menu-button" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: ∅ + │ │ │ │ │ └── value: ∅ + │ │ │ │ │ + │ │ │ │ ├── subsequent: ∅ + │ │ │ │ └── end_node: + │ │ │ │ └── @ ERBEndNode (location: (2:39)-(2:48)) + │ │ │ │ ├── tag_opening: "<%" (location: (2:39)-(2:41)) + │ │ │ │ ├── content: " end " (location: (2:41)-(2:46)) + │ │ │ │ └── tag_closing: "%>" (location: (2:46)-(2:48)) + │ │ │ │ + │ │ │ │ + │ │ │ └── @ HTMLAttributeNode (location: (3:2)-(3:42)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (3:2)-(3:7)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (3:2)-(3:7)) + │ │ │ │ └── content: "class" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (3:7)-(3:8)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (3:8)-(3:42)) + │ │ │ ├── open_quote: """ (location: (3:8)-(3:9)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (3:9)-(3:41)) + │ │ │ │ └── content: "css-truncate css-truncate-target" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (3:41)-(3:42)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── is_void: false + │ │ + │ ├── tag_name: "span" (location: (1:1)-(1:5)) + │ ├── body: [] + │ ├── close_tag: + │ │ └── @ HTMLCloseTagNode (location: (4:1)-(4:8)) + │ │ ├── tag_opening: "" (location: (4:7)-(4:8)) + │ │ + │ ├── is_void: false + │ └── source: "HTML" + │ + └── @ HTMLTextNode (location: (4:8)-(5:0)) + └── content: "\n" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt b/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt new file mode 100644 index 000000000..e278fcab8 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt @@ -0,0 +1,59 @@ +--- +source: "Parser::AttributesTest#test_0050_Conditional attribute with value" +input: "
data-enabled=\"true\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:57)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:57)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:51)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:50)-(1:51)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:50)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if enabled? " (location: (1:7)-(1:20)) + │ │ ├── tag_closing: "%>" (location: (1:20)-(1:22)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:22)-(1:41)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:22)-(1:34)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:22)-(1:34)) + │ │ │ │ └── content: "data-enabled" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:34)-(1:35)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:35)-(1:41)) + │ │ │ ├── open_quote: """ (location: (1:35)-(1:36)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:36)-(1:40)) + │ │ │ │ └── content: "true" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:40)-(1:41)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:41)-(1:50)) + │ │ ├── tag_opening: "<%" (location: (1:41)-(1:43)) + │ │ ├── content: " end " (location: (1:43)-(1:48)) + │ │ └── tag_closing: "%>" (location: (1:48)-(1:50)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:51)-(1:57)) + │ ├── tag_opening: "" (location: (1:56)-(1:57)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt b/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt new file mode 100644 index 000000000..3a76f28c4 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt @@ -0,0 +1,74 @@ +--- +source: "Parser::AttributesTest#test_0051_Multiple conditional attributes" +input: "
data-a<% end %> <% if b? %>data-b<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:65)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:65)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:59)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:58)-(1:59)) + │ ├── children: (2 items) + │ │ ├── @ ERBIfNode (location: (1:5)-(1:31)) + │ │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ │ ├── content: " if a? " (location: (1:7)-(1:14)) + │ │ │ ├── tag_closing: "%>" (location: (1:14)-(1:16)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:16)-(1:22)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:16)-(1:22)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:16)-(1:22)) + │ │ │ │ │ └── content: "data-a" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:22)-(1:31)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: " end " (location: (1:24)-(1:29)) + │ │ │ └── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:32)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:32)-(1:34)) + │ │ ├── content: " if b? " (location: (1:34)-(1:41)) + │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:43)-(1:49)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:43)-(1:49)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:43)-(1:49)) + │ │ │ │ └── content: "data-b" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:49)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:49)-(1:51)) + │ │ ├── content: " end " (location: (1:51)-(1:56)) + │ │ └── tag_closing: "%>" (location: (1:56)-(1:58)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:59)-(1:65)) + │ ├── tag_opening: "" (location: (1:64)-(1:65)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt b/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt new file mode 100644 index 000000000..4623ebfd6 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt @@ -0,0 +1,86 @@ +--- +source: "Parser::AttributesTest#test_0052_Conditional attribute with elsif and else" +input: "
data-primary<% elsif secondary? %>data-secondary<% else %>data-default<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:108)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:108)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:102)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:101)-(1:102)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:101)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if primary? " (location: (1:7)-(1:20)) + │ │ ├── tag_closing: "%>" (location: (1:20)-(1:22)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:22)-(1:34)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:22)-(1:34)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:22)-(1:34)) + │ │ │ │ └── content: "data-primary" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: + │ │ │ └── @ ERBIfNode (location: (1:34)-(1:70)) + │ │ │ ├── tag_opening: "<%" (location: (1:34)-(1:36)) + │ │ │ ├── content: " elsif secondary? " (location: (1:36)-(1:54)) + │ │ │ ├── tag_closing: "%>" (location: (1:54)-(1:56)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:56)-(1:70)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:56)-(1:70)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:56)-(1:70)) + │ │ │ │ │ └── content: "data-secondary" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: + │ │ │ │ └── @ ERBElseNode (location: (1:70)-(1:92)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:70)-(1:72)) + │ │ │ │ ├── content: " else " (location: (1:72)-(1:78)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:78)-(1:80)) + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:80)-(1:92)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:80)-(1:92)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:80)-(1:92)) + │ │ │ │ │ └── content: "data-default" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── end_node: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:92)-(1:101)) + │ │ ├── tag_opening: "<%" (location: (1:92)-(1:94)) + │ │ ├── content: " end " (location: (1:94)-(1:99)) + │ │ └── tag_closing: "%>" (location: (1:99)-(1:101)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:102)-(1:108)) + │ ├── tag_opening: "" (location: (1:107)-(1:108)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt b/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt new file mode 100644 index 000000000..7f2b16cf7 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt @@ -0,0 +1,50 @@ +--- +source: "Parser::AttributesTest#test_0053_Conditional attribute with unless" +input: "
data-enabled<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:55)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:55)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:49)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:48)-(1:49)) + │ ├── children: (1 item) + │ │ └── @ ERBUnlessNode (location: (1:5)-(1:48)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " unless disabled? " (location: (1:7)-(1:25)) + │ │ ├── tag_closing: "%>" (location: (1:25)-(1:27)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:27)-(1:39)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:27)-(1:39)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:27)-(1:39)) + │ │ │ │ └── content: "data-enabled" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:39)-(1:48)) + │ │ ├── tag_opening: "<%" (location: (1:39)-(1:41)) + │ │ ├── content: " end " (location: (1:41)-(1:46)) + │ │ └── tag_closing: "%>" (location: (1:46)-(1:48)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:49)-(1:55)) + │ ├── tag_opening: "" (location: (1:54)-(1:55)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt b/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt new file mode 100644 index 000000000..23ac40a88 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt @@ -0,0 +1,70 @@ +--- +source: "Parser::AttributesTest#test_0054_Multiple attributes in one conditional block" +input: "
data-admin data-role=\"admin\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:64)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:64)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:58)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:57)-(1:58)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:57)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if admin? " (location: (1:7)-(1:18)) + │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── statements: (2 items) + │ │ │ ├── @ HTMLAttributeNode (location: (1:20)-(1:30)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:20)-(1:30)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:20)-(1:30)) + │ │ │ │ │ └── content: "data-admin" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ └── @ HTMLAttributeNode (location: (1:31)-(1:48)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:31)-(1:40)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:31)-(1:40)) + │ │ │ │ └── content: "data-role" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:40)-(1:41)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:41)-(1:48)) + │ │ │ ├── open_quote: """ (location: (1:41)-(1:42)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:42)-(1:47)) + │ │ │ │ └── content: "admin" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:47)-(1:48)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:48)-(1:57)) + │ │ ├── tag_opening: "<%" (location: (1:48)-(1:50)) + │ │ ├── content: " end " (location: (1:50)-(1:55)) + │ │ └── tag_closing: "%>" (location: (1:55)-(1:57)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:58)-(1:64)) + │ ├── tag_opening: "" (location: (1:63)-(1:64)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt b/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt new file mode 100644 index 000000000..1e377f5a0 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt @@ -0,0 +1,64 @@ +--- +source: "Parser::AttributesTest#test_0055_Conditional boolean attribute" +input: "disabled<% end %> type=\"text\">" +--- +@ DocumentNode (location: (1:0)-(1:61)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:61)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:61)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "input" (location: (1:1)-(1:6)) + │ ├── tag_closing: ">" (location: (1:60)-(1:61)) + │ ├── children: (2 items) + │ │ ├── @ ERBIfNode (location: (1:7)-(1:48)) + │ │ │ ├── tag_opening: "<%" (location: (1:7)-(1:9)) + │ │ │ ├── content: " if should_disable? " (location: (1:9)-(1:29)) + │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:31)-(1:39)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:31)-(1:39)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:31)-(1:39)) + │ │ │ │ │ └── content: "disabled" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:39)-(1:48)) + │ │ │ ├── tag_opening: "<%" (location: (1:39)-(1:41)) + │ │ │ ├── content: " end " (location: (1:41)-(1:46)) + │ │ │ └── tag_closing: "%>" (location: (1:46)-(1:48)) + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:49)-(1:60)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:49)-(1:53)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:49)-(1:53)) + │ │ │ └── content: "type" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:53)-(1:54)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:54)-(1:60)) + │ │ ├── open_quote: """ (location: (1:54)-(1:55)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:55)-(1:59)) + │ │ │ └── content: "text" + │ │ │ + │ │ ├── close_quote: """ (location: (1:59)-(1:60)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "input" (location: (1:1)-(1:6)) + ├── body: [] + ├── close_tag: ∅ + ├── is_void: true + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt b/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt new file mode 100644 index 000000000..75a89e9c6 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt @@ -0,0 +1,63 @@ +--- +source: "Parser::AttributesTest#test_0056_Conditional attribute with output tag inside" +input: "
data-user=\"<%= user.id %>\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:60)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:60)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:54)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:53)-(1:54)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:53)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if user " (location: (1:7)-(1:16)) + │ │ ├── tag_closing: "%>" (location: (1:16)-(1:18)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:18)-(1:44)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:18)-(1:27)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:18)-(1:27)) + │ │ │ │ └── content: "data-user" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:27)-(1:28)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:28)-(1:44)) + │ │ │ ├── open_quote: """ (location: (1:28)-(1:29)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ ERBContentNode (location: (1:29)-(1:43)) + │ │ │ │ ├── tag_opening: "<%=" (location: (1:29)-(1:32)) + │ │ │ │ ├── content: " user.id " (location: (1:32)-(1:41)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:43)-(1:44)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:44)-(1:53)) + │ │ ├── tag_opening: "<%" (location: (1:44)-(1:46)) + │ │ ├── content: " end " (location: (1:46)-(1:51)) + │ │ └── tag_closing: "%>" (location: (1:51)-(1:53)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:54)-(1:60)) + │ ├── tag_opening: "" (location: (1:59)-(1:60)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0057_ERB_comment_between_attributes_0e265aed6fa4a1f4adc75b32f35bd862.txt b/test/snapshots/parser/attributes_test/test_0057_ERB_comment_between_attributes_0e265aed6fa4a1f4adc75b32f35bd862.txt new file mode 100644 index 000000000..ff83721b1 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0057_ERB_comment_between_attributes_0e265aed6fa4a1f4adc75b32f35bd862.txt @@ -0,0 +1,73 @@ +--- +source: "Parser::AttributesTest#test_0057_ERB comment between attributes" +input: "
data-baz=\"qux\">
" +--- +@ DocumentNode (location: (1:0)-(1:66)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:66)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:60)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:59)-(1:60)) + │ ├── children: (3 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:19)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:13)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:13)) + │ │ │ │ └── content: "data-foo" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:13)-(1:14)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:14)-(1:19)) + │ │ │ ├── open_quote: """ (location: (1:14)-(1:15)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:15)-(1:18)) + │ │ │ │ └── content: "bar" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:18)-(1:19)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── @ ERBContentNode (location: (1:20)-(1:44)) + │ │ │ ├── tag_opening: "<%#" (location: (1:20)-(1:23)) + │ │ │ ├── content: " This is a comment " (location: (1:23)-(1:42)) + │ │ │ ├── tag_closing: "%>" (location: (1:42)-(1:44)) + │ │ │ ├── parsed: false + │ │ │ └── valid: true + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:45)-(1:59)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:45)-(1:53)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:45)-(1:53)) + │ │ │ └── content: "data-baz" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:53)-(1:54)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:54)-(1:59)) + │ │ ├── open_quote: """ (location: (1:54)-(1:55)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:55)-(1:58)) + │ │ │ └── content: "qux" + │ │ │ + │ │ ├── close_quote: """ (location: (1:58)-(1:59)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:60)-(1:66)) + │ ├── tag_opening: "" (location: (1:65)-(1:66)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt b/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt new file mode 100644 index 000000000..1bca4a956 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt @@ -0,0 +1,50 @@ +--- +source: "Parser::AttributesTest#test_0058_Conditional attribute with trimming tags" +input: "
data-conditional<%- end -%>>
" +--- +@ DocumentNode (location: (1:0)-(1:59)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:59)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:53)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:52)-(1:53)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:52)) + │ │ ├── tag_opening: "<%-" (location: (1:5)-(1:8)) + │ │ ├── content: " if condition " (location: (1:8)-(1:22)) + │ │ ├── tag_closing: "-%>" (location: (1:22)-(1:25)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:25)-(1:41)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:25)-(1:41)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:41)) + │ │ │ │ └── content: "data-conditional" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:41)-(1:52)) + │ │ ├── tag_opening: "<%-" (location: (1:41)-(1:44)) + │ │ ├── content: " end " (location: (1:44)-(1:49)) + │ │ └── tag_closing: "-%>" (location: (1:49)-(1:52)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:53)-(1:59)) + │ ├── tag_opening: "" (location: (1:58)-(1:59)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt b/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt new file mode 100644 index 000000000..59c0b2c96 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt @@ -0,0 +1,70 @@ +--- +source: "Parser::AttributesTest#test_0059_Empty conditional block in attributes" +input: "
<% end %> data-other=\"value\">
" +--- +@ DocumentNode (location: (1:0)-(1:66)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:66)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:60)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:59)-(1:60)) + │ ├── children: (3 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:16)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:16)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:16)) + │ │ │ │ └── content: "data-static" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── @ ERBIfNode (location: (1:17)-(1:40)) + │ │ │ ├── tag_opening: "<%" (location: (1:17)-(1:19)) + │ │ │ ├── content: " if false " (location: (1:19)-(1:29)) + │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── statements: [] + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:31)-(1:40)) + │ │ │ ├── tag_opening: "<%" (location: (1:31)-(1:33)) + │ │ │ ├── content: " end " (location: (1:33)-(1:38)) + │ │ │ └── tag_closing: "%>" (location: (1:38)-(1:40)) + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:41)-(1:59)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:41)-(1:51)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:41)-(1:51)) + │ │ │ └── content: "data-other" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:51)-(1:52)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:52)-(1:59)) + │ │ ├── open_quote: """ (location: (1:52)-(1:53)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:53)-(1:58)) + │ │ │ └── content: "value" + │ │ │ + │ │ ├── close_quote: """ (location: (1:58)-(1:59)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:60)-(1:66)) + │ ├── tag_opening: "" (location: (1:65)-(1:66)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt b/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt new file mode 100644 index 000000000..661b16394 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt @@ -0,0 +1,63 @@ +--- +source: "Parser::AttributesTest#test_0060_Nested conditional attributes" +input: "
<% if inner? %>data-inner<% end %><% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:70)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:70)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:64)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:63)-(1:64)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:63)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if outer? " (location: (1:7)-(1:18)) + │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── statements: (1 item) + │ │ │ └── @ ERBIfNode (location: (1:20)-(1:54)) + │ │ │ ├── tag_opening: "<%" (location: (1:20)-(1:22)) + │ │ │ ├── content: " if inner? " (location: (1:22)-(1:33)) + │ │ │ ├── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:35)-(1:45)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:35)-(1:45)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:35)-(1:45)) + │ │ │ │ │ └── content: "data-inner" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:45)-(1:54)) + │ │ │ ├── tag_opening: "<%" (location: (1:45)-(1:47)) + │ │ │ ├── content: " end " (location: (1:47)-(1:52)) + │ │ │ └── tag_closing: "%>" (location: (1:52)-(1:54)) + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:54)-(1:63)) + │ │ ├── tag_opening: "<%" (location: (1:54)-(1:56)) + │ │ ├── content: " end " (location: (1:56)-(1:61)) + │ │ └── tag_closing: "%>" (location: (1:61)-(1:63)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:64)-(1:70)) + │ ├── tag_opening: "" (location: (1:69)-(1:70)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file From 92f4d9ab86382b3b7f857ceb7055f4f1d75a6fb4 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Tue, 10 Feb 2026 23:11:45 +0100 Subject: [PATCH 2/5] Cleanup --- src/include/util/hb_buffer.h | 1 + src/parser.c | 5 +++-- src/util/hb_buffer.c | 4 ++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/include/util/hb_buffer.h b/src/include/util/hb_buffer.h index 8e6cfe7f4..9fad181ec 100644 --- a/src/include/util/hb_buffer.h +++ b/src/include/util/hb_buffer.h @@ -28,6 +28,7 @@ void hb_buffer_concat(hb_buffer_T* destination, hb_buffer_T* source); char* hb_buffer_value(const hb_buffer_T* buffer); size_t hb_buffer_length(const hb_buffer_T* buffer); +bool hb_buffer_is_empty(const hb_buffer_T* buffer); size_t hb_buffer_capacity(const hb_buffer_T* buffer); size_t hb_buffer_sizeof(void); diff --git a/src/parser.c b/src/parser.c index 72044b020..cdd61e8c2 100644 --- a/src/parser.c +++ b/src/parser.c @@ -297,9 +297,10 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T )) { if (token_is(parser, TOKEN_ERB_START)) { const char* tag = parser->current_token->value; - bool is_output_tag = (tag[2] == '='); + size_t tag_length = strlen(tag); + bool is_output_tag = (tag_length >= 3 && tag[2] == '='); - if (!is_output_tag) { break; } + if (!is_output_tag && hb_buffer_is_empty(&buffer) && hb_array_size(children) == 0) { break; } parser_append_literal_node_from_buffer(parser, &buffer, children, start); diff --git a/src/util/hb_buffer.c b/src/util/hb_buffer.c index 0ce4212b5..79f4c05b8 100644 --- a/src/util/hb_buffer.c +++ b/src/util/hb_buffer.c @@ -101,6 +101,10 @@ size_t hb_buffer_length(const hb_buffer_T* buffer) { return buffer->length; } +bool hb_buffer_is_empty(const hb_buffer_T* buffer) { + return buffer->length == 0; +} + size_t hb_buffer_capacity(const hb_buffer_T* buffer) { return buffer->capacity; } From 3cadb734d657ae54d1837c968ef0d3c240db8908 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Wed, 11 Feb 2026 09:00:29 +0100 Subject: [PATCH 3/5] Handle more edge cases and add more tests --- src/include/util.h | 2 + src/parser.c | 40 +++- src/util.c | 12 ++ test/parser/attributes_test.rb | 189 +++++++++++++++++ ...paces_8b8da9205eb731ac258036f24249144e.txt | 1 + ...paces_f5fb22be5ee259a7902533d5e90f2935.txt | 1 + ..._line_8f3997e9bb390d529e8a302cd3644924.txt | 1 + ...value_81e52238e369e409d9df110376cc3aa3.txt | 1 + ...butes_befdf95a4fadd41e440a471f38e443da.txt | 2 + ..._else_bb59fa557fa46906ac8d7b2ac4948269.txt | 2 + ...nless_a63ab0987a8655064d1dcbe0ac4267f7.txt | 1 + ...block_ad2a48dc8c52e2e1b15ed1c970d12457.txt | 1 + ...ibute_661703bbd4a517e45d7ccf10bb92dd41.txt | 1 + ...nside_2e2b58a4804aa16c21405c4371206b2a.txt | 1 + ..._tags_80b50d0bc25df0f6805558f541ff8d08.txt | 1 + ...butes_2b453534ea13ee20fab205fee722364a.txt | 1 + ...butes_f995c179776fa746db8f0a5e80590c75.txt | 2 + ...t_ERB_cc81c18671c4f9e96b3b6d49a3335a9a.txt | 56 +++++ ..._trim_81067e7c7b132fdf3b256ad32dad1c01.txt | 56 +++++ ...mment_b0e2e415b648c7709f732f750432fea2.txt | 56 +++++ ...names_7bc68d839b02084ac2c5c49ad5a730ee.txt | 86 ++++++++ ...names_ac218c8fb0e2bad2e1f9d5d6d597b51e.txt | 123 +++++++++++ ...ments_7be5e93318178284efd9f86623f4ee70.txt | 198 ++++++++++++++++++ ...aces)_841e69499590b88a64b3430240dae7f3.txt | 88 ++++++++ ...aces)_237117c152d49ba0cd00f5457a7d443f.txt | 108 ++++++++++ ...aces)_70fa55bc69219f35a693ba2254c393bb.txt | 68 ++++++ ...aces)_8ac6964c1a33a09bdf54da608568a4c8.txt | 51 +++++ ...aces)_0372590f24c21efaff9042c837a7e98a.txt | 68 ++++++ ...aces)_f192b2004ca9e90413e9be2fa89a5ce1.txt | 51 +++++ ...aces)_8ec095e77b931db8dede43c333106e3c.txt | 76 +++++++ ...aces)_433982689d4835af88bf1be67b779dbe.txt | 93 ++++++++ ...aces)_41c2868a5491d3c7933e530e498198c4.txt | 94 +++++++++ ...aces)_dd5f761465a88b995df8a84f09dafc23.txt | 76 +++++++ ...aces)_b93153acbda1d65ebfd960ab5f01c799.txt | 93 ++++++++ ...aces)_7fc9d54f29a28af0be3c00367c9ec78f.txt | 70 +++++++ ...aces)_7801d8fa47bad7b1907c4f815c6c6572.txt | 87 ++++++++ ...aces)_da9b658abe61460610d693735c9b3798.txt | 87 ++++++++ ...aces)_22bee6b8643f463b00fd7f516773742a.txt | 104 +++++++++ ...aces)_b28491b2c2b5ef8e54173c4808e29e26.txt | 69 ++++++ ...aces)_2e8f3266e8a37532ec2fbddb0d51abe3.txt | 49 +++++ ...aces)_4123501fcf8c52c20935146728924c33.txt | 49 +++++ ...aces)_cec20f9884e02e47621408613b8c74ff.txt | 49 +++++ ...aces)_cd98fd353e5642925fde50aa09b8883c.txt | 49 +++++ ...aces)_91c453938988e8052ce3c57ec43085d1.txt | 49 +++++ ...bute)_21f85c26e4ad76ffd2bdcff26b88a684.txt | 51 +++++ ...bute)_af0945767bcb7bb951308eb807e10e27.txt | 51 +++++ ...bute)_4ab1dfa03e2724be706bcc82b58058a3.txt | 51 +++++ ...bute)_3269b2eef75d593930fdea654b6d4829.txt | 51 +++++ ...aces)_0b1ff653f2083d4ed761e301d4a349fc.txt | 85 ++++++++ ...aces)_58860a73111fa6c30c3eb948a5712bb0.txt | 85 ++++++++ ...ional_8c06ba292aee34d2246c5434e2aa3c68.txt | 91 ++++++++ ...ional_ebd40115264193db975ccf7dc4ae35e5.txt | 91 ++++++++ ...butes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt | 91 ++++++++ ...butes_042e33e3b667bd90f51576fb32384468.txt | 100 +++++++++ ...butes_a39365c5182e15b19f92c1aa831b3d88.txt | 82 ++++++++ ...nside_198af2705cb596f4dc827a4bd2ff89bc.txt | 91 ++++++++ ...value_b8559766f404b30543c5bc966e0794a6.txt | 88 ++++++++ ...ibute_44720e6b8d80626b1067450c32388bcc.txt | 65 ++++++ ...value_7e81668eb38a3cbea4d7a95186b4e4d7.txt | 78 +++++++ ...ibute_83f720a8cff8f1b31db7e3747ff6209f.txt | 74 +++++++ ...value_9680e555f9af80f1e23caf65f801478f.txt | 64 ++++++ 61 files changed, 3650 insertions(+), 1 deletion(-) create mode 100644 test/snapshots/parser/attributes_test/test_0061_attribute_name_with_non-output_ERB_cc81c18671c4f9e96b3b6d49a3335a9a.txt create mode 100644 test/snapshots/parser/attributes_test/test_0062_attribute_name_with_ERB_trim_81067e7c7b132fdf3b256ad32dad1c01.txt create mode 100644 test/snapshots/parser/attributes_test/test_0063_attribute_name_with_ERB_comment_b0e2e415b648c7709f732f750432fea2.txt create mode 100644 test/snapshots/parser/attributes_test/test_0064_multiple_non-ERB_outputs_in_attribute_names_7bc68d839b02084ac2c5c49ad5a730ee.txt create mode 100644 test/snapshots/parser/attributes_test/test_0065_mixed_ERB_output_types_in_multiple_attribute_names_ac218c8fb0e2bad2e1f9d5d6d597b51e.txt create mode 100644 test/snapshots/parser/attributes_test/test_0066_ERB_in_attribute_names_within_form_elements_7be5e93318178284efd9f86623f4ee70.txt create mode 100644 test/snapshots/parser/attributes_test/test_0067_if_elsif_else_end_control_flow_in_attributes_(no_spaces)_841e69499590b88a64b3430240dae7f3.txt create mode 100644 test/snapshots/parser/attributes_test/test_0068_if_elsif_elsif_else_end_control_flow_in_attributes_(no_spaces)_237117c152d49ba0cd00f5457a7d443f.txt create mode 100644 test/snapshots/parser/attributes_test/test_0069_if_else_end_control_flow_in_attributes_(no_spaces)_70fa55bc69219f35a693ba2254c393bb.txt create mode 100644 test/snapshots/parser/attributes_test/test_0070_if_end_control_flow_in_attributes_(no_spaces)_8ac6964c1a33a09bdf54da608568a4c8.txt create mode 100644 test/snapshots/parser/attributes_test/test_0071_unless_else_end_control_flow_in_attributes_(no_spaces)_0372590f24c21efaff9042c837a7e98a.txt create mode 100644 test/snapshots/parser/attributes_test/test_0072_unless_end_control_flow_in_attributes_(no_spaces)_f192b2004ca9e90413e9be2fa89a5ce1.txt create mode 100644 test/snapshots/parser/attributes_test/test_0073_case_when_when_end_control_flow_in_attributes_(no_spaces)_8ec095e77b931db8dede43c333106e3c.txt create mode 100644 test/snapshots/parser/attributes_test/test_0074_case_when_when_else_end_control_flow_in_attributes_(no_spaces)_433982689d4835af88bf1be67b779dbe.txt create mode 100644 test/snapshots/parser/attributes_test/test_0075_case_when_when_when_end_control_flow_in_attributes_(no_spaces)_41c2868a5491d3c7933e530e498198c4.txt create mode 100644 test/snapshots/parser/attributes_test/test_0076_case_in_in_end_control_flow_in_attributes_(no_spaces)_dd5f761465a88b995df8a84f09dafc23.txt create mode 100644 test/snapshots/parser/attributes_test/test_0077_case_in_in_else_end_control_flow_in_attributes_(no_spaces)_b93153acbda1d65ebfd960ab5f01c799.txt create mode 100644 test/snapshots/parser/attributes_test/test_0078_begin_rescue_end_control_flow_in_attributes_(no_spaces)_7fc9d54f29a28af0be3c00367c9ec78f.txt create mode 100644 test/snapshots/parser/attributes_test/test_0079_begin_rescue_else_end_control_flow_in_attributes_(no_spaces)_7801d8fa47bad7b1907c4f815c6c6572.txt create mode 100644 test/snapshots/parser/attributes_test/test_0080_begin_rescue_ensure_end_control_flow_in_attributes_(no_spaces)_da9b658abe61460610d693735c9b3798.txt create mode 100644 test/snapshots/parser/attributes_test/test_0081_begin_rescue_else_ensure_end_control_flow_in_attributes_(no_spaces)_22bee6b8643f463b00fd7f516773742a.txt create mode 100644 test/snapshots/parser/attributes_test/test_0082_begin_ensure_end_control_flow_in_attributes_(no_spaces)_b28491b2c2b5ef8e54173c4808e29e26.txt create mode 100644 test/snapshots/parser/attributes_test/test_0083_while_end_control_flow_in_attributes_(no_spaces)_2e8f3266e8a37532ec2fbddb0d51abe3.txt create mode 100644 test/snapshots/parser/attributes_test/test_0084_until_end_control_flow_in_attributes_(no_spaces)_4123501fcf8c52c20935146728924c33.txt create mode 100644 test/snapshots/parser/attributes_test/test_0085_for_end_control_flow_in_attributes_(no_spaces)_cec20f9884e02e47621408613b8c74ff.txt create mode 100644 test/snapshots/parser/attributes_test/test_0086_block_do_end_control_flow_in_attributes_(no_spaces)_cd98fd353e5642925fde50aa09b8883c.txt create mode 100644 test/snapshots/parser/attributes_test/test_0087_block_do_with_args_end_control_flow_in_attributes_(no_spaces)_91c453938988e8052ce3c57ec43085d1.txt create mode 100644 test/snapshots/parser/attributes_test/test_0088_issue_#1063_conditional_boolean_attribute_open_(no_spaces_around_attribute)_21f85c26e4ad76ffd2bdcff26b88a684.txt create mode 100644 test/snapshots/parser/attributes_test/test_0089_issue_#1063_conditional_boolean_attribute_open_(space_after_attribute)_af0945767bcb7bb951308eb807e10e27.txt create mode 100644 test/snapshots/parser/attributes_test/test_0090_issue_#1063_conditional_boolean_attribute_open_(space_before_attribute)_4ab1dfa03e2724be706bcc82b58058a3.txt create mode 100644 test/snapshots/parser/attributes_test/test_0091_issue_#1063_conditional_boolean_attribute_open_(spaces_around_attribute)_3269b2eef75d593930fdea654b6d4829.txt create mode 100644 test/snapshots/parser/attributes_test/test_0092_issue_#1063_two_conditional_attributes_back-to-back_(with_spaces)_0b1ff653f2083d4ed761e301d4a349fc.txt create mode 100644 test/snapshots/parser/attributes_test/test_0093_issue_#1063_two_conditional_attributes_back-to-back_(no_spaces)_58860a73111fa6c30c3eb948a5712bb0.txt create mode 100644 test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt create mode 100644 test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt create mode 100644 test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt create mode 100644 test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt create mode 100644 test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt create mode 100644 test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt create mode 100644 test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt create mode 100644 test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt create mode 100644 test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt create mode 100644 test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt create mode 100644 test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt diff --git a/src/include/util.h b/src/include/util.h index 3028716e4..67b03c4f3 100644 --- a/src/include/util.h +++ b/src/include/util.h @@ -6,6 +6,8 @@ #include int is_newline(int character); +int is_whitespace(int character); +const char* skip_whitespace(const char* ptr); hb_string_T escape_newlines(hb_string_T input); hb_string_T quoted_string(hb_string_T input); diff --git a/src/parser.c b/src/parser.c index cdd61e8c2..a99802959 100644 --- a/src/parser.c +++ b/src/parser.c @@ -27,6 +27,7 @@ static void parser_handle_whitespace(parser_T* parser, token_T* whitespace_token static void parser_consume_whitespace(parser_T* parser, hb_array_T* children); static void parser_skip_erb_content(lexer_T* lexer); static bool parser_lookahead_erb_is_attribute(lexer_T* lexer); +static bool parser_lookahead_erb_is_control_flow(parser_T* parser); static void parser_handle_erb_in_open_tag(parser_T* parser, hb_array_T* children); static void parser_handle_whitespace_in_open_tag(parser_T* parser, hb_array_T* children); @@ -300,7 +301,12 @@ static AST_HTML_ATTRIBUTE_NAME_NODE_T* parser_parse_html_attribute_name(parser_T size_t tag_length = strlen(tag); bool is_output_tag = (tag_length >= 3 && tag[2] == '='); - if (!is_output_tag && hb_buffer_is_empty(&buffer) && hb_array_size(children) == 0) { break; } + if (!is_output_tag) { + bool is_control_flow = parser_lookahead_erb_is_control_flow(parser); + + if (hb_buffer_is_empty(&buffer) && hb_array_size(children) == 0) { break; } + if (is_control_flow) { break; } + } parser_append_literal_node_from_buffer(parser, &buffer, children, start); @@ -726,6 +732,38 @@ static bool parser_lookahead_erb_is_attribute(lexer_T* lexer) { } while (true); } +static bool starts_with_keyword(const char* pointer, const char* keyword) { + size_t length = strlen(keyword); + if (strncmp(pointer, keyword, length) != 0) { return false; } + + char next = pointer[length]; + + return next == '\0' || is_whitespace(next); +} + +// TODO: ideally we could avoid basing this off of strings, and use the step in analyze.c +static bool parser_lookahead_erb_is_control_flow(parser_T* parser) { + lexer_T lexer_copy = *parser->lexer; + token_T* content = lexer_next_token(&lexer_copy); + + if (content == NULL || content->type != TOKEN_ERB_CONTENT) { + if (content) { token_free(content); } + + return false; + } + + const char* pointer = skip_whitespace(content->value); + + bool is_control_flow = starts_with_keyword(pointer, "end") || starts_with_keyword(pointer, "else") + || starts_with_keyword(pointer, "elsif") || starts_with_keyword(pointer, "in") + || starts_with_keyword(pointer, "when") || starts_with_keyword(pointer, "rescue") + || starts_with_keyword(pointer, "ensure"); + + token_free(content); + + return is_control_flow; +} + static void parser_handle_erb_in_open_tag(parser_T* parser, hb_array_T* children) { bool is_output_tag = parser->current_token->value && strlen(parser->current_token->value) >= 3 && strncmp(parser->current_token->value, "<%=", 3) == 0; diff --git a/src/util.c b/src/util.c index 94b2e17b7..9b79b7e9b 100644 --- a/src/util.c +++ b/src/util.c @@ -10,6 +10,18 @@ int is_newline(int character) { return character == '\n' || character == '\r'; } +int is_whitespace(int character) { + return character == ' ' || character == '\t' || character == '\n' || character == '\r'; +} + +const char* skip_whitespace(const char* pointer) { + while (is_whitespace(*pointer)) { + pointer++; + } + + return pointer; +} + hb_string_T escape_newlines(hb_string_T input) { hb_buffer_T buffer; diff --git a/test/parser/attributes_test.rb b/test/parser/attributes_test.rb index 4c091d603..ed55de92b 100644 --- a/test/parser/attributes_test.rb +++ b/test/parser/attributes_test.rb @@ -256,5 +256,194 @@ class AttributesTest < Minitest::Spec test "Nested conditional attributes" do assert_parsed_snapshot(%(
<% if inner? %>data-inner<% end %><% end %>>
)) end + + test "attribute name with non-output ERB" do + assert_parsed_snapshot(%(
-target="value">
)) + end + + test "attribute name with ERB trim" do + assert_parsed_snapshot(%(
-id="thing">
)) + end + + test "attribute name with ERB comment" do + assert_parsed_snapshot(%(
-target="value">
)) + end + + test "multiple non-ERB outputs in attribute names" do + assert_parsed_snapshot(%(
-target="value" id-<% another %>-suffix="test">
)) + end + + test "mixed ERB output types in multiple attribute names" do + assert_parsed_snapshot(%( +
-target="value" + prefix-<% invalid_key %>-id="test" + class="<%= valid_class %>" + >
+ )) + end + + test "ERB in attribute names within form elements" do + assert_parsed_snapshot(%( +
+ -field="text"> + + +
+ )) + end + + # Control flow in attributes - comprehensive tests (no spaces in ERB tags) + test "if/elsif/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%elsif b?%>data-two<%else%>data-three<%end%>>
)) + end + + test "if/elsif/elsif/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%elsif b?%>data-two<%elsif c?%>data-three<%else%>data-four<%end%>>
)) + end + + test "if/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%else%>data-two<%end%>>
)) + end + + test "if/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%end%>>
)) + end + + test "unless/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%else%>data-two<%end%>>
)) + end + + test "unless/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%end%>>
)) + end + + test "case/when/when/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
<%when 1%>data-one<%when 2%>data-two<%end%>>
)) + end + + test "case/when/when/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
<%when 1%>data-one<%when 2%>data-two<%else%>data-default<%end%>>
)) + end + + test "case/when/when/when/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
<%when 1%>data-one<%when 2%>data-two<%when 3%>data-three<%end%>>
)) + end + + test "case/in/in/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
<%in 1%>data-one<%in 2%>data-two<%end%>>
)) + end + + test "case/in/in/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
<%in 1%>data-one<%in 2%>data-two<%else%>data-default<%end%>>
)) + end + + test "begin/rescue/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%rescue%>data-error<%end%>>
)) + end + + test "begin/rescue/else/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%rescue%>data-error<%else%>data-success<%end%>>
)) + end + + test "begin/rescue/ensure/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%rescue%>data-error<%ensure%>data-always<%end%>>
)) + end + + test "begin/rescue/else/ensure/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%rescue%>data-error<%else%>data-success<%ensure%>data-always<%end%>>
)) + end + + test "begin/ensure/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-one<%ensure%>data-always<%end%>>
)) + end + + test "while/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-item<%end%>>
)) + end + + test "until/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-item<%end%>>
)) + end + + test "for/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-item<%end%>>
)) + end + + test "block do/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-item<%end%>>
)) + end + + test "block do with args/end control flow in attributes (no spaces)" do + assert_parsed_snapshot(%(
data-item<%end%>>
)) + end + + test "issue #1063: conditional boolean attribute open (no spaces around attribute)" do + assert_parsed_snapshot(%(
open<% end %>>
)) + end + + test "issue #1063: conditional boolean attribute open (space after attribute)" do + assert_parsed_snapshot(%(
open <% end %>>
)) + end + + test "issue #1063: conditional boolean attribute open (space before attribute)" do + assert_parsed_snapshot(%(
open<% end %>>
)) + end + + test "issue #1063: conditional boolean attribute open (spaces around attribute)" do + assert_parsed_snapshot(%(
open <% end %>>
)) + end + + test "issue #1063: two conditional attributes back-to-back (with spaces)" do + assert_parsed_snapshot(%(
open <% end %> <% if b? %>style='color: red;'<% end %> >
)) + end + + test "issue #1063: two conditional attributes back-to-back (no spaces)" do + assert_parsed_snapshot(%(
open<% end %><% if b? %>style='color: red;'<% end %>>
)) + end + + test "multiple regular attributes before conditional" do + assert_parsed_snapshot(%(
data-active<% end %>>
)) + end + + test "multiple regular attributes after conditional" do + assert_parsed_snapshot(%(
data-active<% end %> id="main" class="container">
)) + end + + test "conditional attribute between regular attributes" do + assert_parsed_snapshot(%(
data-active<% end %> class="container">
)) + end + + test "conditional attribute with value between regular attributes" do + assert_parsed_snapshot(%(
data-active="true"<% end %> class="container">
)) + end + + test "nested conditionals in attributes" do + assert_parsed_snapshot(%(
<% if inner? %>data-inner<% else %>data-outer<% end %><% end %>>
)) + end + + test "conditional with multiple attributes inside" do + assert_parsed_snapshot(%(
data-admin data-role="admin" data-permissions="all"<% end %>>
)) + end + + test "conditional with ERB output in attribute value" do + assert_parsed_snapshot(%(
data-user-id="<%= user.id %>" data-user-name="<%= user.name %>"<% end %>>
)) + end + + test "self-closing tag with conditional attribute" do + assert_parsed_snapshot(%(required<% end %> />)) + end + + test "self-closing tag with conditional attribute and value" do + assert_parsed_snapshot(%(value="<%= default_value %>"<% end %> />)) + end + + test "void element with conditional attribute" do + assert_parsed_snapshot(%(loading="lazy"<% end %>>)) + end + + test "conditional class attribute with ternary in value" do + assert_parsed_snapshot(%(
class="<%= active ? 'active' : 'inactive' %>"<% end %>>
)) + end end end diff --git a/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt index b28e20c8a..30996c2bd 100644 --- a/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt +++ b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt @@ -35,6 +35,7 @@ input: "dat │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) │ │ ├── content: " if local_assigns[:permanent] " (location: (1:35)-(1:65)) │ │ ├── tag_closing: "%>" (location: (1:65)-(1:67)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:67)-(1:87)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt b/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt index 4094a112e..6aebb0a9d 100644 --- a/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt +++ b/test/snapshots/parser/attributes_test/test_0048_Conditional_attribute_with_ERB_control_flow_with_surrounding_spaces_f5fb22be5ee259a7902533d5e90f2935.txt @@ -35,6 +35,7 @@ input: " da │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) │ │ ├── content: " if local_assigns[:permanent] " (location: (1:35)-(1:65)) │ │ ├── tag_closing: "%>" (location: (1:65)-(1:67)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:68)-(1:88)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt b/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt index 7043d2212..961eaf0da 100644 --- a/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt +++ b/test/snapshots/parser/attributes_test/test_0049_Conditional_attribute_with_ERB_on_separate_line_8f3997e9bb390d529e8a302cd3644924.txt @@ -19,6 +19,7 @@ input: |2- │ │ │ │ ├── tag_opening: "<%" (location: (2:2)-(2:4)) │ │ │ │ ├── content: " if @replaceable " (location: (2:4)-(2:21)) │ │ │ │ ├── tag_closing: "%>" (location: (2:21)-(2:23)) + │ │ │ │ ├── then_keyword: ∅ │ │ │ │ ├── statements: (1 item) │ │ │ │ │ └── @ HTMLAttributeNode (location: (2:23)-(2:39)) │ │ │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt b/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt index e278fcab8..068d54065 100644 --- a/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt +++ b/test/snapshots/parser/attributes_test/test_0050_Conditional_attribute_with_value_81e52238e369e409d9df110376cc3aa3.txt @@ -15,6 +15,7 @@ input: "
data-enabled=\"true\"<% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " if enabled? " (location: (1:7)-(1:20)) │ │ ├── tag_closing: "%>" (location: (1:20)-(1:22)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:22)-(1:41)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt b/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt index 3a76f28c4..a73586659 100644 --- a/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt +++ b/test/snapshots/parser/attributes_test/test_0051_Multiple_conditional_attributes_befdf95a4fadd41e440a471f38e443da.txt @@ -15,6 +15,7 @@ input: "
data-a<% end %> <% if b? %>data-b<% end %>>
" │ │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ │ ├── content: " if a? " (location: (1:7)-(1:14)) │ │ │ ├── tag_closing: "%>" (location: (1:14)-(1:16)) + │ │ │ ├── then_keyword: ∅ │ │ │ ├── statements: (1 item) │ │ │ │ └── @ HTMLAttributeNode (location: (1:16)-(1:22)) │ │ │ │ ├── name: @@ -39,6 +40,7 @@ input: "
data-a<% end %> <% if b? %>data-b<% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:32)-(1:34)) │ │ ├── content: " if b? " (location: (1:34)-(1:41)) │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:43)-(1:49)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt b/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt index 4623ebfd6..20bab477e 100644 --- a/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt +++ b/test/snapshots/parser/attributes_test/test_0052_Conditional_attribute_with_elsif_and_else_bb59fa557fa46906ac8d7b2ac4948269.txt @@ -15,6 +15,7 @@ input: "
data-primary<% elsif secondary? %>data-secondary<% │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " if primary? " (location: (1:7)-(1:20)) │ │ ├── tag_closing: "%>" (location: (1:20)-(1:22)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:22)-(1:34)) │ │ │ ├── name: @@ -32,6 +33,7 @@ input: "
data-primary<% elsif secondary? %>data-secondary<% │ │ │ ├── tag_opening: "<%" (location: (1:34)-(1:36)) │ │ │ ├── content: " elsif secondary? " (location: (1:36)-(1:54)) │ │ │ ├── tag_closing: "%>" (location: (1:54)-(1:56)) + │ │ │ ├── then_keyword: ∅ │ │ │ ├── statements: (1 item) │ │ │ │ └── @ HTMLAttributeNode (location: (1:56)-(1:70)) │ │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt b/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt index 7f2b16cf7..0a156450b 100644 --- a/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt +++ b/test/snapshots/parser/attributes_test/test_0053_Conditional_attribute_with_unless_a63ab0987a8655064d1dcbe0ac4267f7.txt @@ -15,6 +15,7 @@ input: "
data-enabled<% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " unless disabled? " (location: (1:7)-(1:25)) │ │ ├── tag_closing: "%>" (location: (1:25)-(1:27)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:27)-(1:39)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt b/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt index 23ac40a88..b440c5cf5 100644 --- a/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt +++ b/test/snapshots/parser/attributes_test/test_0054_Multiple_attributes_in_one_conditional_block_ad2a48dc8c52e2e1b15ed1c970d12457.txt @@ -15,6 +15,7 @@ input: "
data-admin data-role=\"admin\"<% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " if admin? " (location: (1:7)-(1:18)) │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (2 items) │ │ │ ├── @ HTMLAttributeNode (location: (1:20)-(1:30)) │ │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt b/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt index 1e377f5a0..b6d578bce 100644 --- a/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt +++ b/test/snapshots/parser/attributes_test/test_0055_Conditional_boolean_attribute_661703bbd4a517e45d7ccf10bb92dd41.txt @@ -15,6 +15,7 @@ input: "disabled<% end %> type=\"text\">" │ │ │ ├── tag_opening: "<%" (location: (1:7)-(1:9)) │ │ │ ├── content: " if should_disable? " (location: (1:9)-(1:29)) │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── then_keyword: ∅ │ │ │ ├── statements: (1 item) │ │ │ │ └── @ HTMLAttributeNode (location: (1:31)-(1:39)) │ │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt b/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt index 75a89e9c6..7f58048a3 100644 --- a/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt +++ b/test/snapshots/parser/attributes_test/test_0056_Conditional_attribute_with_output_tag_inside_2e2b58a4804aa16c21405c4371206b2a.txt @@ -15,6 +15,7 @@ input: "
data-user=\"<%= user.id %>\"<% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " if user " (location: (1:7)-(1:16)) │ │ ├── tag_closing: "%>" (location: (1:16)-(1:18)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:18)-(1:44)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt b/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt index 1bca4a956..38e54ebd9 100644 --- a/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt +++ b/test/snapshots/parser/attributes_test/test_0058_Conditional_attribute_with_trimming_tags_80b50d0bc25df0f6805558f541ff8d08.txt @@ -15,6 +15,7 @@ input: "
data-conditional<%- end -%>>
" │ │ ├── tag_opening: "<%-" (location: (1:5)-(1:8)) │ │ ├── content: " if condition " (location: (1:8)-(1:22)) │ │ ├── tag_closing: "-%>" (location: (1:22)-(1:25)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ HTMLAttributeNode (location: (1:25)-(1:41)) │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt b/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt index 59c0b2c96..b5df4a111 100644 --- a/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt +++ b/test/snapshots/parser/attributes_test/test_0059_Empty_conditional_block_in_attributes_2b453534ea13ee20fab205fee722364a.txt @@ -26,6 +26,7 @@ input: "
<% end %> data-other=\"value\">
" │ │ │ ├── tag_opening: "<%" (location: (1:17)-(1:19)) │ │ │ ├── content: " if false " (location: (1:19)-(1:29)) │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── then_keyword: ∅ │ │ │ ├── statements: [] │ │ │ ├── subsequent: ∅ │ │ │ └── end_node: diff --git a/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt b/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt index 661b16394..f2b780027 100644 --- a/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt +++ b/test/snapshots/parser/attributes_test/test_0060_Nested_conditional_attributes_f995c179776fa746db8f0a5e80590c75.txt @@ -15,11 +15,13 @@ input: "
<% if inner? %>data-inner<% end %><% end %>>
" │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) │ │ ├── content: " if outer? " (location: (1:7)-(1:18)) │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── then_keyword: ∅ │ │ ├── statements: (1 item) │ │ │ └── @ ERBIfNode (location: (1:20)-(1:54)) │ │ │ ├── tag_opening: "<%" (location: (1:20)-(1:22)) │ │ │ ├── content: " if inner? " (location: (1:22)-(1:33)) │ │ │ ├── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ │ ├── then_keyword: ∅ │ │ │ ├── statements: (1 item) │ │ │ │ └── @ HTMLAttributeNode (location: (1:35)-(1:45)) │ │ │ │ ├── name: diff --git a/test/snapshots/parser/attributes_test/test_0061_attribute_name_with_non-output_ERB_cc81c18671c4f9e96b3b6d49a3335a9a.txt b/test/snapshots/parser/attributes_test/test_0061_attribute_name_with_non-output_ERB_cc81c18671c4f9e96b3b6d49a3335a9a.txt new file mode 100644 index 000000000..12aa7d692 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0061_attribute_name_with_non-output_ERB_cc81c18671c4f9e96b3b6d49a3335a9a.txt @@ -0,0 +1,56 @@ +--- +source: "Parser::AttributesTest#test_0061_attribute name with non-output ERB" +input: "
-target=\"value\">
" +--- +@ DocumentNode (location: (1:0)-(1:41)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:41)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:35)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:34)-(1:35)) + │ ├── children: (1 item) + │ │ └── @ HTMLAttributeNode (location: (1:5)-(1:34)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:26)) + │ │ │ └── children: (3 items) + │ │ │ ├── @ LiteralNode (location: (1:5)-(1:10)) + │ │ │ │ └── content: "data-" + │ │ │ │ + │ │ │ ├── @ ERBContentNode (location: (1:10)-(1:19)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:10)-(1:12)) + │ │ │ │ ├── content: " key " (location: (1:12)-(1:17)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:17)-(1:19)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ └── @ LiteralNode (location: (1:19)-(1:26)) + │ │ │ └── content: "-target" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:26)-(1:27)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:27)-(1:34)) + │ │ ├── open_quote: """ (location: (1:27)-(1:28)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:28)-(1:33)) + │ │ │ └── content: "value" + │ │ │ + │ │ ├── close_quote: """ (location: (1:33)-(1:34)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:35)-(1:41)) + │ ├── tag_opening: "" (location: (1:40)-(1:41)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0062_attribute_name_with_ERB_trim_81067e7c7b132fdf3b256ad32dad1c01.txt b/test/snapshots/parser/attributes_test/test_0062_attribute_name_with_ERB_trim_81067e7c7b132fdf3b256ad32dad1c01.txt new file mode 100644 index 000000000..06dce2855 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0062_attribute_name_with_ERB_trim_81067e7c7b132fdf3b256ad32dad1c01.txt @@ -0,0 +1,56 @@ +--- +source: "Parser::AttributesTest#test_0062_attribute name with ERB trim" +input: "
-id=\"thing\">
" +--- +@ DocumentNode (location: (1:0)-(1:39)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:39)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:33)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:32)-(1:33)) + │ ├── children: (1 item) + │ │ └── @ HTMLAttributeNode (location: (1:5)-(1:32)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:24)) + │ │ │ └── children: (3 items) + │ │ │ ├── @ LiteralNode (location: (1:5)-(1:10)) + │ │ │ │ └── content: "data-" + │ │ │ │ + │ │ │ ├── @ ERBContentNode (location: (1:10)-(1:21)) + │ │ │ │ ├── tag_opening: "<%-" (location: (1:10)-(1:13)) + │ │ │ │ ├── content: " key " (location: (1:13)-(1:18)) + │ │ │ │ ├── tag_closing: "-%>" (location: (1:18)-(1:21)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ └── @ LiteralNode (location: (1:21)-(1:24)) + │ │ │ └── content: "-id" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:24)-(1:25)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:25)-(1:32)) + │ │ ├── open_quote: """ (location: (1:25)-(1:26)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:26)-(1:31)) + │ │ │ └── content: "thing" + │ │ │ + │ │ ├── close_quote: """ (location: (1:31)-(1:32)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:33)-(1:39)) + │ ├── tag_opening: "" (location: (1:38)-(1:39)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0063_attribute_name_with_ERB_comment_b0e2e415b648c7709f732f750432fea2.txt b/test/snapshots/parser/attributes_test/test_0063_attribute_name_with_ERB_comment_b0e2e415b648c7709f732f750432fea2.txt new file mode 100644 index 000000000..77d1eba6e --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0063_attribute_name_with_ERB_comment_b0e2e415b648c7709f732f750432fea2.txt @@ -0,0 +1,56 @@ +--- +source: "Parser::AttributesTest#test_0063_attribute name with ERB comment" +input: "
-target=\"value\">
" +--- +@ DocumentNode (location: (1:0)-(1:46)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:46)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:40)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:39)-(1:40)) + │ ├── children: (1 item) + │ │ └── @ HTMLAttributeNode (location: (1:5)-(1:39)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:31)) + │ │ │ └── children: (3 items) + │ │ │ ├── @ LiteralNode (location: (1:5)-(1:10)) + │ │ │ │ └── content: "data-" + │ │ │ │ + │ │ │ ├── @ ERBContentNode (location: (1:10)-(1:24)) + │ │ │ │ ├── tag_opening: "<%#" (location: (1:10)-(1:13)) + │ │ │ │ ├── content: " comment " (location: (1:13)-(1:22)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:22)-(1:24)) + │ │ │ │ ├── parsed: false + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ └── @ LiteralNode (location: (1:24)-(1:31)) + │ │ │ └── content: "-target" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:31)-(1:32)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:32)-(1:39)) + │ │ ├── open_quote: """ (location: (1:32)-(1:33)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:33)-(1:38)) + │ │ │ └── content: "value" + │ │ │ + │ │ ├── close_quote: """ (location: (1:38)-(1:39)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:40)-(1:46)) + │ ├── tag_opening: "" (location: (1:45)-(1:46)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0064_multiple_non-ERB_outputs_in_attribute_names_7bc68d839b02084ac2c5c49ad5a730ee.txt b/test/snapshots/parser/attributes_test/test_0064_multiple_non-ERB_outputs_in_attribute_names_7bc68d839b02084ac2c5c49ad5a730ee.txt new file mode 100644 index 000000000..8766f19fb --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0064_multiple_non-ERB_outputs_in_attribute_names_7bc68d839b02084ac2c5c49ad5a730ee.txt @@ -0,0 +1,86 @@ +--- +source: "Parser::AttributesTest#test_0064_multiple non-ERB outputs in attribute names" +input: "
-target=\"value\" id-<% another %>-suffix=\"test\">
" +--- +@ DocumentNode (location: (1:0)-(1:72)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:72)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:66)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:65)-(1:66)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:34)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:26)) + │ │ │ │ └── children: (3 items) + │ │ │ │ ├── @ LiteralNode (location: (1:5)-(1:10)) + │ │ │ │ │ └── content: "data-" + │ │ │ │ │ + │ │ │ │ ├── @ ERBContentNode (location: (1:10)-(1:19)) + │ │ │ │ │ ├── tag_opening: "<%" (location: (1:10)-(1:12)) + │ │ │ │ │ ├── content: " key " (location: (1:12)-(1:17)) + │ │ │ │ │ ├── tag_closing: "%>" (location: (1:17)-(1:19)) + │ │ │ │ │ ├── parsed: true + │ │ │ │ │ └── valid: true + │ │ │ │ │ + │ │ │ │ └── @ LiteralNode (location: (1:19)-(1:26)) + │ │ │ │ └── content: "-target" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:26)-(1:27)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:27)-(1:34)) + │ │ │ ├── open_quote: """ (location: (1:27)-(1:28)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:28)-(1:33)) + │ │ │ │ └── content: "value" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:33)-(1:34)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:35)-(1:65)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:35)-(1:58)) + │ │ │ └── children: (3 items) + │ │ │ ├── @ LiteralNode (location: (1:35)-(1:38)) + │ │ │ │ └── content: "id-" + │ │ │ │ + │ │ │ ├── @ ERBContentNode (location: (1:38)-(1:51)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:38)-(1:40)) + │ │ │ │ ├── content: " another " (location: (1:40)-(1:49)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:49)-(1:51)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ └── @ LiteralNode (location: (1:51)-(1:58)) + │ │ │ └── content: "-suffix" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:58)-(1:59)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:59)-(1:65)) + │ │ ├── open_quote: """ (location: (1:59)-(1:60)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:60)-(1:64)) + │ │ │ └── content: "test" + │ │ │ + │ │ ├── close_quote: """ (location: (1:64)-(1:65)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:66)-(1:72)) + │ ├── tag_opening: "" (location: (1:71)-(1:72)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0065_mixed_ERB_output_types_in_multiple_attribute_names_ac218c8fb0e2bad2e1f9d5d6d597b51e.txt b/test/snapshots/parser/attributes_test/test_0065_mixed_ERB_output_types_in_multiple_attribute_names_ac218c8fb0e2bad2e1f9d5d6d597b51e.txt new file mode 100644 index 000000000..e4d829f55 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0065_mixed_ERB_output_types_in_multiple_attribute_names_ac218c8fb0e2bad2e1f9d5d6d597b51e.txt @@ -0,0 +1,123 @@ +--- +source: "Parser::AttributesTest#test_0065_mixed ERB output types in multiple attribute names" +input: |2- + +
-target="value" + prefix-<% invalid_key %>-id="test" + class="<%= valid_class %>" + >
+ +--- +@ DocumentNode (location: (1:0)-(7:6)) +└── children: (3 items) + ├── @ HTMLTextNode (location: (1:0)-(2:8)) + │ └── content: "\n " + │ + ├── @ HTMLElementNode (location: (2:8)-(6:15)) + │ ├── open_tag: + │ │ └── @ HTMLOpenTagNode (location: (2:8)-(6:9)) + │ │ ├── tag_opening: "<" (location: (2:8)-(2:9)) + │ │ ├── tag_name: "div" (location: (2:9)-(2:12)) + │ │ ├── tag_closing: ">" (location: (6:8)-(6:9)) + │ │ ├── children: (3 items) + │ │ │ ├── @ HTMLAttributeNode (location: (3:10)-(3:46)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (3:10)-(3:38)) + │ │ │ │ │ └── children: (3 items) + │ │ │ │ │ ├── @ LiteralNode (location: (3:10)-(3:15)) + │ │ │ │ │ │ └── content: "data-" + │ │ │ │ │ │ + │ │ │ │ │ ├── @ ERBContentNode (location: (3:15)-(3:31)) + │ │ │ │ │ │ ├── tag_opening: "<%=" (location: (3:15)-(3:18)) + │ │ │ │ │ │ ├── content: " valid_key " (location: (3:18)-(3:29)) + │ │ │ │ │ │ ├── tag_closing: "%>" (location: (3:29)-(3:31)) + │ │ │ │ │ │ ├── parsed: true + │ │ │ │ │ │ └── valid: true + │ │ │ │ │ │ + │ │ │ │ │ └── @ LiteralNode (location: (3:31)-(3:38)) + │ │ │ │ │ └── content: "-target" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: "=" (location: (3:38)-(3:39)) + │ │ │ │ └── value: + │ │ │ │ └── @ HTMLAttributeValueNode (location: (3:39)-(3:46)) + │ │ │ │ ├── open_quote: """ (location: (3:39)-(3:40)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (3:40)-(3:45)) + │ │ │ │ │ └── content: "value" + │ │ │ │ │ + │ │ │ │ ├── close_quote: """ (location: (3:45)-(3:46)) + │ │ │ │ └── quoted: true + │ │ │ │ + │ │ │ │ + │ │ │ ├── @ HTMLAttributeNode (location: (4:10)-(4:44)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (4:10)-(4:37)) + │ │ │ │ │ └── children: (3 items) + │ │ │ │ │ ├── @ LiteralNode (location: (4:10)-(4:17)) + │ │ │ │ │ │ └── content: "prefix-" + │ │ │ │ │ │ + │ │ │ │ │ ├── @ ERBContentNode (location: (4:17)-(4:34)) + │ │ │ │ │ │ ├── tag_opening: "<%" (location: (4:17)-(4:19)) + │ │ │ │ │ │ ├── content: " invalid_key " (location: (4:19)-(4:32)) + │ │ │ │ │ │ ├── tag_closing: "%>" (location: (4:32)-(4:34)) + │ │ │ │ │ │ ├── parsed: true + │ │ │ │ │ │ └── valid: true + │ │ │ │ │ │ + │ │ │ │ │ └── @ LiteralNode (location: (4:34)-(4:37)) + │ │ │ │ │ └── content: "-id" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: "=" (location: (4:37)-(4:38)) + │ │ │ │ └── value: + │ │ │ │ └── @ HTMLAttributeValueNode (location: (4:38)-(4:44)) + │ │ │ │ ├── open_quote: """ (location: (4:38)-(4:39)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (4:39)-(4:43)) + │ │ │ │ │ └── content: "test" + │ │ │ │ │ + │ │ │ │ ├── close_quote: """ (location: (4:43)-(4:44)) + │ │ │ │ └── quoted: true + │ │ │ │ + │ │ │ │ + │ │ │ └── @ HTMLAttributeNode (location: (5:10)-(5:36)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (5:10)-(5:15)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (5:10)-(5:15)) + │ │ │ │ └── content: "class" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (5:15)-(5:16)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (5:16)-(5:36)) + │ │ │ ├── open_quote: """ (location: (5:16)-(5:17)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ ERBContentNode (location: (5:17)-(5:35)) + │ │ │ │ ├── tag_opening: "<%=" (location: (5:17)-(5:20)) + │ │ │ │ ├── content: " valid_class " (location: (5:20)-(5:33)) + │ │ │ │ ├── tag_closing: "%>" (location: (5:33)-(5:35)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (5:35)-(5:36)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── is_void: false + │ │ + │ ├── tag_name: "div" (location: (2:9)-(2:12)) + │ ├── body: [] + │ ├── close_tag: + │ │ └── @ HTMLCloseTagNode (location: (6:9)-(6:15)) + │ │ ├── tag_opening: "" (location: (6:14)-(6:15)) + │ │ + │ ├── is_void: false + │ └── source: "HTML" + │ + └── @ HTMLTextNode (location: (6:15)-(7:6)) + └── content: "\n " \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0066_ERB_in_attribute_names_within_form_elements_7be5e93318178284efd9f86623f4ee70.txt b/test/snapshots/parser/attributes_test/test_0066_ERB_in_attribute_names_within_form_elements_7be5e93318178284efd9f86623f4ee70.txt new file mode 100644 index 000000000..3cab1a5df --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0066_ERB_in_attribute_names_within_form_elements_7be5e93318178284efd9f86623f4ee70.txt @@ -0,0 +1,198 @@ +--- +source: "Parser::AttributesTest#test_0066_ERB in attribute names within form elements" +input: |2- + +
+ -field="text"> + + +
+ +--- +@ DocumentNode (location: (1:0)-(7:6)) +└── children: (3 items) + ├── @ HTMLTextNode (location: (1:0)-(2:8)) + │ └── content: "\n " + │ + ├── @ HTMLElementNode (location: (2:8)-(6:15)) + │ ├── open_tag: + │ │ └── @ HTMLOpenTagNode (location: (2:8)-(2:14)) + │ │ ├── tag_opening: "<" (location: (2:8)-(2:9)) + │ │ ├── tag_name: "form" (location: (2:9)-(2:13)) + │ │ ├── tag_closing: ">" (location: (2:13)-(2:14)) + │ │ ├── children: [] + │ │ └── is_void: false + │ │ + │ ├── tag_name: "form" (location: (2:9)-(2:13)) + │ ├── body: (7 items) + │ │ ├── @ HTMLTextNode (location: (2:14)-(3:10)) + │ │ │ └── content: "\n " + │ │ │ + │ │ ├── @ HTMLElementNode (location: (3:10)-(3:50)) + │ │ │ ├── open_tag: + │ │ │ │ └── @ HTMLOpenTagNode (location: (3:10)-(3:50)) + │ │ │ │ ├── tag_opening: "<" (location: (3:10)-(3:11)) + │ │ │ │ ├── tag_name: "input" (location: (3:11)-(3:16)) + │ │ │ │ ├── tag_closing: ">" (location: (3:49)-(3:50)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (3:17)-(3:49)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (3:17)-(3:42)) + │ │ │ │ │ │ └── children: (3 items) + │ │ │ │ │ │ ├── @ LiteralNode (location: (3:17)-(3:22)) + │ │ │ │ │ │ │ └── content: "data-" + │ │ │ │ │ │ │ + │ │ │ │ │ │ ├── @ ERBContentNode (location: (3:22)-(3:36)) + │ │ │ │ │ │ │ ├── tag_opening: "<%=" (location: (3:22)-(3:25)) + │ │ │ │ │ │ │ ├── content: " user.id " (location: (3:25)-(3:34)) + │ │ │ │ │ │ │ ├── tag_closing: "%>" (location: (3:34)-(3:36)) + │ │ │ │ │ │ │ ├── parsed: true + │ │ │ │ │ │ │ └── valid: true + │ │ │ │ │ │ │ + │ │ │ │ │ │ └── @ LiteralNode (location: (3:36)-(3:42)) + │ │ │ │ │ │ └── content: "-field" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: "=" (location: (3:42)-(3:43)) + │ │ │ │ │ └── value: + │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (3:43)-(3:49)) + │ │ │ │ │ ├── open_quote: """ (location: (3:43)-(3:44)) + │ │ │ │ │ ├── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (3:44)-(3:48)) + │ │ │ │ │ │ └── content: "text" + │ │ │ │ │ │ + │ │ │ │ │ ├── close_quote: """ (location: (3:48)-(3:49)) + │ │ │ │ │ └── quoted: true + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ └── is_void: false + │ │ │ │ + │ │ │ ├── tag_name: "input" (location: (3:11)-(3:16)) + │ │ │ ├── body: [] + │ │ │ ├── close_tag: ∅ + │ │ │ ├── is_void: true + │ │ │ └── source: "HTML" + │ │ │ + │ │ ├── @ HTMLTextNode (location: (3:50)-(4:10)) + │ │ │ └── content: "\n " + │ │ │ + │ │ ├── @ HTMLElementNode (location: (4:10)-(4:64)) + │ │ │ ├── open_tag: + │ │ │ │ └── @ HTMLOpenTagNode (location: (4:10)-(4:55)) + │ │ │ │ ├── tag_opening: "<" (location: (4:10)-(4:11)) + │ │ │ │ ├── tag_name: "button" (location: (4:11)-(4:17)) + │ │ │ │ ├── tag_closing: ">" (location: (4:54)-(4:55)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (4:18)-(4:54)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (4:18)-(4:44)) + │ │ │ │ │ │ └── children: (3 items) + │ │ │ │ │ │ ├── @ LiteralNode (location: (4:18)-(4:23)) + │ │ │ │ │ │ │ └── content: "data-" + │ │ │ │ │ │ │ + │ │ │ │ │ │ ├── @ ERBContentNode (location: (4:23)-(4:39)) + │ │ │ │ │ │ │ ├── tag_opening: "<%" (location: (4:23)-(4:25)) + │ │ │ │ │ │ │ ├── content: " collection " (location: (4:25)-(4:37)) + │ │ │ │ │ │ │ ├── tag_closing: "%>" (location: (4:37)-(4:39)) + │ │ │ │ │ │ │ ├── parsed: true + │ │ │ │ │ │ │ └── valid: true + │ │ │ │ │ │ │ + │ │ │ │ │ │ └── @ LiteralNode (location: (4:39)-(4:44)) + │ │ │ │ │ │ └── content: "-list" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: "=" (location: (4:44)-(4:45)) + │ │ │ │ │ └── value: + │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (4:45)-(4:54)) + │ │ │ │ │ ├── open_quote: """ (location: (4:45)-(4:46)) + │ │ │ │ │ ├── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (4:46)-(4:53)) + │ │ │ │ │ │ └── content: "options" + │ │ │ │ │ │ + │ │ │ │ │ ├── close_quote: """ (location: (4:53)-(4:54)) + │ │ │ │ │ └── quoted: true + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ └── is_void: false + │ │ │ │ + │ │ │ ├── tag_name: "button" (location: (4:11)-(4:17)) + │ │ │ ├── body: [] + │ │ │ ├── close_tag: + │ │ │ │ └── @ HTMLCloseTagNode (location: (4:55)-(4:64)) + │ │ │ │ ├── tag_opening: "" (location: (4:63)-(4:64)) + │ │ │ │ + │ │ │ ├── is_void: false + │ │ │ └── source: "HTML" + │ │ │ + │ │ ├── @ HTMLTextNode (location: (4:64)-(5:10)) + │ │ │ └── content: "\n " + │ │ │ + │ │ ├── @ HTMLElementNode (location: (5:10)-(5:64)) + │ │ │ ├── open_tag: + │ │ │ │ └── @ HTMLOpenTagNode (location: (5:10)-(5:55)) + │ │ │ │ ├── tag_opening: "<" (location: (5:10)-(5:11)) + │ │ │ │ ├── tag_name: "select" (location: (5:11)-(5:17)) + │ │ │ │ ├── tag_closing: ">" (location: (5:54)-(5:55)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (5:18)-(5:54)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (5:18)-(5:46)) + │ │ │ │ │ │ └── children: (3 items) + │ │ │ │ │ │ ├── @ LiteralNode (location: (5:18)-(5:25)) + │ │ │ │ │ │ │ └── content: "prefix-" + │ │ │ │ │ │ │ + │ │ │ │ │ │ ├── @ ERBContentNode (location: (5:25)-(5:39)) + │ │ │ │ │ │ │ ├── tag_opening: "<%#" (location: (5:25)-(5:28)) + │ │ │ │ │ │ │ ├── content: " comment " (location: (5:28)-(5:37)) + │ │ │ │ │ │ │ ├── tag_closing: "%>" (location: (5:37)-(5:39)) + │ │ │ │ │ │ │ ├── parsed: false + │ │ │ │ │ │ │ └── valid: true + │ │ │ │ │ │ │ + │ │ │ │ │ │ └── @ LiteralNode (location: (5:39)-(5:46)) + │ │ │ │ │ │ └── content: "-suffix" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: "=" (location: (5:46)-(5:47)) + │ │ │ │ │ └── value: + │ │ │ │ │ └── @ HTMLAttributeValueNode (location: (5:47)-(5:54)) + │ │ │ │ │ ├── open_quote: """ (location: (5:47)-(5:48)) + │ │ │ │ │ ├── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (5:48)-(5:53)) + │ │ │ │ │ │ └── content: "value" + │ │ │ │ │ │ + │ │ │ │ │ ├── close_quote: """ (location: (5:53)-(5:54)) + │ │ │ │ │ └── quoted: true + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ └── is_void: false + │ │ │ │ + │ │ │ ├── tag_name: "select" (location: (5:11)-(5:17)) + │ │ │ ├── body: [] + │ │ │ ├── close_tag: + │ │ │ │ └── @ HTMLCloseTagNode (location: (5:55)-(5:64)) + │ │ │ │ ├── tag_opening: "" (location: (5:63)-(5:64)) + │ │ │ │ + │ │ │ ├── is_void: false + │ │ │ └── source: "HTML" + │ │ │ + │ │ └── @ HTMLTextNode (location: (5:64)-(6:8)) + │ │ └── content: "\n " + │ │ + │ ├── close_tag: + │ │ └── @ HTMLCloseTagNode (location: (6:8)-(6:15)) + │ │ ├── tag_opening: "" (location: (6:14)-(6:15)) + │ │ + │ ├── is_void: false + │ └── source: "HTML" + │ + └── @ HTMLTextNode (location: (6:15)-(7:6)) + └── content: "\n " \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0067_if_elsif_else_end_control_flow_in_attributes_(no_spaces)_841e69499590b88a64b3430240dae7f3.txt b/test/snapshots/parser/attributes_test/test_0067_if_elsif_else_end_control_flow_in_attributes_(no_spaces)_841e69499590b88a64b3430240dae7f3.txt new file mode 100644 index 000000000..348eef60c --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0067_if_elsif_else_end_control_flow_in_attributes_(no_spaces)_841e69499590b88a64b3430240dae7f3.txt @@ -0,0 +1,88 @@ +--- +source: "Parser::AttributesTest#test_0067_if/elsif/else/end control flow in attributes (no spaces)" +input: "
data-one<%elsif b?%>data-two<%else%>data-three<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:74)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:74)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:68)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:67)-(1:68)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:67)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "if a?" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: + │ │ │ └── @ ERBIfNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "elsif b?" (location: (1:24)-(1:32)) + │ │ │ ├── tag_closing: "%>" (location: (1:32)-(1:34)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:34)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:34)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:34)-(1:42)) + │ │ │ │ │ └── content: "data-two" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: + │ │ │ │ └── @ ERBElseNode (location: (1:42)-(1:60)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ │ ├── content: "else" (location: (1:44)-(1:48)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:48)-(1:50)) + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:50)-(1:60)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:50)-(1:60)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:50)-(1:60)) + │ │ │ │ │ └── content: "data-three" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── end_node: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:60)-(1:67)) + │ │ ├── tag_opening: "<%" (location: (1:60)-(1:62)) + │ │ ├── content: "end" (location: (1:62)-(1:65)) + │ │ └── tag_closing: "%>" (location: (1:65)-(1:67)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:68)-(1:74)) + │ ├── tag_opening: "" (location: (1:73)-(1:74)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0068_if_elsif_elsif_else_end_control_flow_in_attributes_(no_spaces)_237117c152d49ba0cd00f5457a7d443f.txt b/test/snapshots/parser/attributes_test/test_0068_if_elsif_elsif_else_end_control_flow_in_attributes_(no_spaces)_237117c152d49ba0cd00f5457a7d443f.txt new file mode 100644 index 000000000..0909f3414 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0068_if_elsif_elsif_else_end_control_flow_in_attributes_(no_spaces)_237117c152d49ba0cd00f5457a7d443f.txt @@ -0,0 +1,108 @@ +--- +source: "Parser::AttributesTest#test_0068_if/elsif/elsif/else/end control flow in attributes (no spaces)" +input: "
data-one<%elsif b?%>data-two<%elsif c?%>data-three<%else%>data-four<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:95)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:95)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:89)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:88)-(1:89)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:88)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "if a?" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: + │ │ │ └── @ ERBIfNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "elsif b?" (location: (1:24)-(1:32)) + │ │ │ ├── tag_closing: "%>" (location: (1:32)-(1:34)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:34)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:34)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:34)-(1:42)) + │ │ │ │ │ └── content: "data-two" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: + │ │ │ │ └── @ ERBIfNode (location: (1:42)-(1:64)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ │ ├── content: "elsif c?" (location: (1:44)-(1:52)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:52)-(1:54)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ ├── statements: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (1:54)-(1:64)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:54)-(1:64)) + │ │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (1:54)-(1:64)) + │ │ │ │ │ │ └── content: "data-three" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: ∅ + │ │ │ │ │ └── value: ∅ + │ │ │ │ │ + │ │ │ │ ├── subsequent: + │ │ │ │ │ └── @ ERBElseNode (location: (1:64)-(1:81)) + │ │ │ │ │ ├── tag_opening: "<%" (location: (1:64)-(1:66)) + │ │ │ │ │ ├── content: "else" (location: (1:66)-(1:70)) + │ │ │ │ │ ├── tag_closing: "%>" (location: (1:70)-(1:72)) + │ │ │ │ │ └── statements: (1 item) + │ │ │ │ │ └── @ HTMLAttributeNode (location: (1:72)-(1:81)) + │ │ │ │ │ ├── name: + │ │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:72)-(1:81)) + │ │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ │ └── @ LiteralNode (location: (1:72)-(1:81)) + │ │ │ │ │ │ └── content: "data-four" + │ │ │ │ │ │ + │ │ │ │ │ │ + │ │ │ │ │ ├── equals: ∅ + │ │ │ │ │ └── value: ∅ + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ └── end_node: ∅ + │ │ │ │ + │ │ │ └── end_node: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:81)-(1:88)) + │ │ ├── tag_opening: "<%" (location: (1:81)-(1:83)) + │ │ ├── content: "end" (location: (1:83)-(1:86)) + │ │ └── tag_closing: "%>" (location: (1:86)-(1:88)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:89)-(1:95)) + │ ├── tag_opening: "" (location: (1:94)-(1:95)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0069_if_else_end_control_flow_in_attributes_(no_spaces)_70fa55bc69219f35a693ba2254c393bb.txt b/test/snapshots/parser/attributes_test/test_0069_if_else_end_control_flow_in_attributes_(no_spaces)_70fa55bc69219f35a693ba2254c393bb.txt new file mode 100644 index 000000000..e73b6ca75 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0069_if_else_end_control_flow_in_attributes_(no_spaces)_70fa55bc69219f35a693ba2254c393bb.txt @@ -0,0 +1,68 @@ +--- +source: "Parser::AttributesTest#test_0069_if/else/end control flow in attributes (no spaces)" +input: "
data-one<%else%>data-two<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:52)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:52)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:46)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:45)-(1:46)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:45)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "if a?" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: + │ │ │ └── @ ERBElseNode (location: (1:22)-(1:38)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "else" (location: (1:24)-(1:28)) + │ │ │ ├── tag_closing: "%>" (location: (1:28)-(1:30)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:30)-(1:38)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:30)-(1:38)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:30)-(1:38)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:38)-(1:45)) + │ │ ├── tag_opening: "<%" (location: (1:38)-(1:40)) + │ │ ├── content: "end" (location: (1:40)-(1:43)) + │ │ └── tag_closing: "%>" (location: (1:43)-(1:45)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:46)-(1:52)) + │ ├── tag_opening: "" (location: (1:51)-(1:52)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0070_if_end_control_flow_in_attributes_(no_spaces)_8ac6964c1a33a09bdf54da608568a4c8.txt b/test/snapshots/parser/attributes_test/test_0070_if_end_control_flow_in_attributes_(no_spaces)_8ac6964c1a33a09bdf54da608568a4c8.txt new file mode 100644 index 000000000..1cbca4a8a --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0070_if_end_control_flow_in_attributes_(no_spaces)_8ac6964c1a33a09bdf54da608568a4c8.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0070_if/end control flow in attributes (no spaces)" +input: "
data-one<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:36)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:36)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:30)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:29)-(1:30)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:29)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "if a?" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:22)-(1:29)) + │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ ├── content: "end" (location: (1:24)-(1:27)) + │ │ └── tag_closing: "%>" (location: (1:27)-(1:29)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:30)-(1:36)) + │ ├── tag_opening: "" (location: (1:35)-(1:36)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0071_unless_else_end_control_flow_in_attributes_(no_spaces)_0372590f24c21efaff9042c837a7e98a.txt b/test/snapshots/parser/attributes_test/test_0071_unless_else_end_control_flow_in_attributes_(no_spaces)_0372590f24c21efaff9042c837a7e98a.txt new file mode 100644 index 000000000..b75efeb63 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0071_unless_else_end_control_flow_in_attributes_(no_spaces)_0372590f24c21efaff9042c837a7e98a.txt @@ -0,0 +1,68 @@ +--- +source: "Parser::AttributesTest#test_0071_unless/else/end control flow in attributes (no spaces)" +input: "
data-one<%else%>data-two<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:56)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:56)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:50)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:49)-(1:50)) + │ ├── children: (1 item) + │ │ └── @ ERBUnlessNode (location: (1:5)-(1:49)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "unless a?" (location: (1:7)-(1:16)) + │ │ ├── tag_closing: "%>" (location: (1:16)-(1:18)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:18)-(1:26)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:18)-(1:26)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:18)-(1:26)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── else_clause: + │ │ │ └── @ ERBElseNode (location: (1:26)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:26)-(1:28)) + │ │ │ ├── content: "else" (location: (1:28)-(1:32)) + │ │ │ ├── tag_closing: "%>" (location: (1:32)-(1:34)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:34)-(1:42)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:34)-(1:42)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:34)-(1:42)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:42)-(1:49)) + │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ ├── content: "end" (location: (1:44)-(1:47)) + │ │ └── tag_closing: "%>" (location: (1:47)-(1:49)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:50)-(1:56)) + │ ├── tag_opening: "" (location: (1:55)-(1:56)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0072_unless_end_control_flow_in_attributes_(no_spaces)_f192b2004ca9e90413e9be2fa89a5ce1.txt b/test/snapshots/parser/attributes_test/test_0072_unless_end_control_flow_in_attributes_(no_spaces)_f192b2004ca9e90413e9be2fa89a5ce1.txt new file mode 100644 index 000000000..69f2f871c --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0072_unless_end_control_flow_in_attributes_(no_spaces)_f192b2004ca9e90413e9be2fa89a5ce1.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0072_unless/end control flow in attributes (no spaces)" +input: "
data-one<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:40)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:40)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:34)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:33)-(1:34)) + │ ├── children: (1 item) + │ │ └── @ ERBUnlessNode (location: (1:5)-(1:33)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "unless a?" (location: (1:7)-(1:16)) + │ │ ├── tag_closing: "%>" (location: (1:16)-(1:18)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:18)-(1:26)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:18)-(1:26)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:18)-(1:26)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:26)-(1:33)) + │ │ ├── tag_opening: "<%" (location: (1:26)-(1:28)) + │ │ ├── content: "end" (location: (1:28)-(1:31)) + │ │ └── tag_closing: "%>" (location: (1:31)-(1:33)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:34)-(1:40)) + │ ├── tag_opening: "" (location: (1:39)-(1:40)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0073_case_when_when_end_control_flow_in_attributes_(no_spaces)_8ec095e77b931db8dede43c333106e3c.txt b/test/snapshots/parser/attributes_test/test_0073_case_when_when_end_control_flow_in_attributes_(no_spaces)_8ec095e77b931db8dede43c333106e3c.txt new file mode 100644 index 000000000..de68dc96e --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0073_case_when_when_end_control_flow_in_attributes_(no_spaces)_8ec095e77b931db8dede43c333106e3c.txt @@ -0,0 +1,76 @@ +--- +source: "Parser::AttributesTest#test_0073_case/when/when/end control flow in attributes (no spaces)" +input: "
<%when 1%>data-one<%when 2%>data-two<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:65)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:65)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:59)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:58)-(1:59)) + │ ├── children: (1 item) + │ │ └── @ ERBCaseNode (location: (1:5)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "case x" (location: (1:7)-(1:13)) + │ │ ├── tag_closing: "%>" (location: (1:13)-(1:15)) + │ │ ├── children: [] + │ │ ├── conditions: (2 items) + │ │ │ ├── @ ERBWhenNode (location: (1:15)-(1:25)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ │ ├── content: "when 1" (location: (1:17)-(1:23)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:23)-(1:25)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:25)-(1:33)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── content: "data-one" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── @ ERBWhenNode (location: (1:33)-(1:43)) + │ │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ │ ├── content: "when 2" (location: (1:35)-(1:41)) + │ │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ │ ├── then_keyword: ∅ + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:43)-(1:51)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:43)-(1:51)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:43)-(1:51)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:51)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:51)-(1:53)) + │ │ ├── content: "end" (location: (1:53)-(1:56)) + │ │ └── tag_closing: "%>" (location: (1:56)-(1:58)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:59)-(1:65)) + │ ├── tag_opening: "" (location: (1:64)-(1:65)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0074_case_when_when_else_end_control_flow_in_attributes_(no_spaces)_433982689d4835af88bf1be67b779dbe.txt b/test/snapshots/parser/attributes_test/test_0074_case_when_when_else_end_control_flow_in_attributes_(no_spaces)_433982689d4835af88bf1be67b779dbe.txt new file mode 100644 index 000000000..443b9d9e8 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0074_case_when_when_else_end_control_flow_in_attributes_(no_spaces)_433982689d4835af88bf1be67b779dbe.txt @@ -0,0 +1,93 @@ +--- +source: "Parser::AttributesTest#test_0074_case/when/when/else/end control flow in attributes (no spaces)" +input: "
<%when 1%>data-one<%when 2%>data-two<%else%>data-default<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:85)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:85)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:79)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:78)-(1:79)) + │ ├── children: (1 item) + │ │ └── @ ERBCaseNode (location: (1:5)-(1:78)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "case x" (location: (1:7)-(1:13)) + │ │ ├── tag_closing: "%>" (location: (1:13)-(1:15)) + │ │ ├── children: [] + │ │ ├── conditions: (2 items) + │ │ │ ├── @ ERBWhenNode (location: (1:15)-(1:25)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ │ ├── content: "when 1" (location: (1:17)-(1:23)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:23)-(1:25)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:25)-(1:33)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── content: "data-one" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── @ ERBWhenNode (location: (1:33)-(1:43)) + │ │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ │ ├── content: "when 2" (location: (1:35)-(1:41)) + │ │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ │ ├── then_keyword: ∅ + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:43)-(1:51)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:43)-(1:51)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:43)-(1:51)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── else_clause: + │ │ │ └── @ ERBElseNode (location: (1:51)-(1:59)) + │ │ │ ├── tag_opening: "<%" (location: (1:51)-(1:53)) + │ │ │ ├── content: "else" (location: (1:53)-(1:57)) + │ │ │ ├── tag_closing: "%>" (location: (1:57)-(1:59)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:59)-(1:71)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:59)-(1:71)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:59)-(1:71)) + │ │ │ │ └── content: "data-default" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:71)-(1:78)) + │ │ ├── tag_opening: "<%" (location: (1:71)-(1:73)) + │ │ ├── content: "end" (location: (1:73)-(1:76)) + │ │ └── tag_closing: "%>" (location: (1:76)-(1:78)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:79)-(1:85)) + │ ├── tag_opening: "" (location: (1:84)-(1:85)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0075_case_when_when_when_end_control_flow_in_attributes_(no_spaces)_41c2868a5491d3c7933e530e498198c4.txt b/test/snapshots/parser/attributes_test/test_0075_case_when_when_when_end_control_flow_in_attributes_(no_spaces)_41c2868a5491d3c7933e530e498198c4.txt new file mode 100644 index 000000000..425e6b072 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0075_case_when_when_when_end_control_flow_in_attributes_(no_spaces)_41c2868a5491d3c7933e530e498198c4.txt @@ -0,0 +1,94 @@ +--- +source: "Parser::AttributesTest#test_0075_case/when/when/when/end control flow in attributes (no spaces)" +input: "
<%when 1%>data-one<%when 2%>data-two<%when 3%>data-three<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:85)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:85)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:79)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:78)-(1:79)) + │ ├── children: (1 item) + │ │ └── @ ERBCaseNode (location: (1:5)-(1:78)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "case x" (location: (1:7)-(1:13)) + │ │ ├── tag_closing: "%>" (location: (1:13)-(1:15)) + │ │ ├── children: [] + │ │ ├── conditions: (3 items) + │ │ │ ├── @ ERBWhenNode (location: (1:15)-(1:25)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ │ ├── content: "when 1" (location: (1:17)-(1:23)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:23)-(1:25)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:25)-(1:33)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:25)-(1:33)) + │ │ │ │ │ └── content: "data-one" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ ├── @ ERBWhenNode (location: (1:33)-(1:43)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ │ │ ├── content: "when 2" (location: (1:35)-(1:41)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:41)-(1:43)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:43)-(1:51)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:43)-(1:51)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:43)-(1:51)) + │ │ │ │ │ └── content: "data-two" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── @ ERBWhenNode (location: (1:51)-(1:61)) + │ │ │ ├── tag_opening: "<%" (location: (1:51)-(1:53)) + │ │ │ ├── content: "when 3" (location: (1:53)-(1:59)) + │ │ │ ├── tag_closing: "%>" (location: (1:59)-(1:61)) + │ │ │ ├── then_keyword: ∅ + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:61)-(1:71)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:61)-(1:71)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:61)-(1:71)) + │ │ │ │ └── content: "data-three" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:71)-(1:78)) + │ │ ├── tag_opening: "<%" (location: (1:71)-(1:73)) + │ │ ├── content: "end" (location: (1:73)-(1:76)) + │ │ └── tag_closing: "%>" (location: (1:76)-(1:78)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:79)-(1:85)) + │ ├── tag_opening: "" (location: (1:84)-(1:85)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0076_case_in_in_end_control_flow_in_attributes_(no_spaces)_dd5f761465a88b995df8a84f09dafc23.txt b/test/snapshots/parser/attributes_test/test_0076_case_in_in_end_control_flow_in_attributes_(no_spaces)_dd5f761465a88b995df8a84f09dafc23.txt new file mode 100644 index 000000000..d45f0ba52 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0076_case_in_in_end_control_flow_in_attributes_(no_spaces)_dd5f761465a88b995df8a84f09dafc23.txt @@ -0,0 +1,76 @@ +--- +source: "Parser::AttributesTest#test_0076_case/in/in/end control flow in attributes (no spaces)" +input: "
<%in 1%>data-one<%in 2%>data-two<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:61)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:61)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:55)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:54)-(1:55)) + │ ├── children: (1 item) + │ │ └── @ ERBCaseMatchNode (location: (1:5)-(1:54)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "case x" (location: (1:7)-(1:13)) + │ │ ├── tag_closing: "%>" (location: (1:13)-(1:15)) + │ │ ├── children: [] + │ │ ├── conditions: (2 items) + │ │ │ ├── @ ERBInNode (location: (1:15)-(1:23)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ │ ├── content: "in 1" (location: (1:17)-(1:21)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:21)-(1:23)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:23)-(1:31)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:23)-(1:31)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:23)-(1:31)) + │ │ │ │ │ └── content: "data-one" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── @ ERBInNode (location: (1:31)-(1:39)) + │ │ │ ├── tag_opening: "<%" (location: (1:31)-(1:33)) + │ │ │ ├── content: "in 2" (location: (1:33)-(1:37)) + │ │ │ ├── tag_closing: "%>" (location: (1:37)-(1:39)) + │ │ │ ├── then_keyword: ∅ + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:39)-(1:47)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:39)-(1:47)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:39)-(1:47)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:47)-(1:54)) + │ │ ├── tag_opening: "<%" (location: (1:47)-(1:49)) + │ │ ├── content: "end" (location: (1:49)-(1:52)) + │ │ └── tag_closing: "%>" (location: (1:52)-(1:54)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:55)-(1:61)) + │ ├── tag_opening: "" (location: (1:60)-(1:61)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0077_case_in_in_else_end_control_flow_in_attributes_(no_spaces)_b93153acbda1d65ebfd960ab5f01c799.txt b/test/snapshots/parser/attributes_test/test_0077_case_in_in_else_end_control_flow_in_attributes_(no_spaces)_b93153acbda1d65ebfd960ab5f01c799.txt new file mode 100644 index 000000000..8f14a4b3c --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0077_case_in_in_else_end_control_flow_in_attributes_(no_spaces)_b93153acbda1d65ebfd960ab5f01c799.txt @@ -0,0 +1,93 @@ +--- +source: "Parser::AttributesTest#test_0077_case/in/in/else/end control flow in attributes (no spaces)" +input: "
<%in 1%>data-one<%in 2%>data-two<%else%>data-default<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:81)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:81)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:75)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:74)-(1:75)) + │ ├── children: (1 item) + │ │ └── @ ERBCaseMatchNode (location: (1:5)-(1:74)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "case x" (location: (1:7)-(1:13)) + │ │ ├── tag_closing: "%>" (location: (1:13)-(1:15)) + │ │ ├── children: [] + │ │ ├── conditions: (2 items) + │ │ │ ├── @ ERBInNode (location: (1:15)-(1:23)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ │ ├── content: "in 1" (location: (1:17)-(1:21)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:21)-(1:23)) + │ │ │ │ ├── then_keyword: ∅ + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:23)-(1:31)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:23)-(1:31)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:23)-(1:31)) + │ │ │ │ │ └── content: "data-one" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── @ ERBInNode (location: (1:31)-(1:39)) + │ │ │ ├── tag_opening: "<%" (location: (1:31)-(1:33)) + │ │ │ ├── content: "in 2" (location: (1:33)-(1:37)) + │ │ │ ├── tag_closing: "%>" (location: (1:37)-(1:39)) + │ │ │ ├── then_keyword: ∅ + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:39)-(1:47)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:39)-(1:47)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:39)-(1:47)) + │ │ │ │ └── content: "data-two" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── else_clause: + │ │ │ └── @ ERBElseNode (location: (1:47)-(1:55)) + │ │ │ ├── tag_opening: "<%" (location: (1:47)-(1:49)) + │ │ │ ├── content: "else" (location: (1:49)-(1:53)) + │ │ │ ├── tag_closing: "%>" (location: (1:53)-(1:55)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:55)-(1:67)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:55)-(1:67)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:55)-(1:67)) + │ │ │ │ └── content: "data-default" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:67)-(1:74)) + │ │ ├── tag_opening: "<%" (location: (1:67)-(1:69)) + │ │ ├── content: "end" (location: (1:69)-(1:72)) + │ │ └── tag_closing: "%>" (location: (1:72)-(1:74)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:75)-(1:81)) + │ ├── tag_opening: "" (location: (1:80)-(1:81)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0078_begin_rescue_end_control_flow_in_attributes_(no_spaces)_7fc9d54f29a28af0be3c00367c9ec78f.txt b/test/snapshots/parser/attributes_test/test_0078_begin_rescue_end_control_flow_in_attributes_(no_spaces)_7fc9d54f29a28af0be3c00367c9ec78f.txt new file mode 100644 index 000000000..fb31e2cff --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0078_begin_rescue_end_control_flow_in_attributes_(no_spaces)_7fc9d54f29a28af0be3c00367c9ec78f.txt @@ -0,0 +1,70 @@ +--- +source: "Parser::AttributesTest#test_0078_begin/rescue/end control flow in attributes (no spaces)" +input: "
data-one<%rescue%>data-error<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:56)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:56)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:50)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:49)-(1:50)) + │ ├── children: (1 item) + │ │ └── @ ERBBeginNode (location: (1:5)-(1:49)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "begin" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── rescue_clause: + │ │ │ └── @ ERBRescueNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "rescue" (location: (1:24)-(1:30)) + │ │ │ ├── tag_closing: "%>" (location: (1:30)-(1:32)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:32)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── content: "data-error" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ └── subsequent: ∅ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:42)-(1:49)) + │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ ├── content: "end" (location: (1:44)-(1:47)) + │ │ └── tag_closing: "%>" (location: (1:47)-(1:49)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:50)-(1:56)) + │ ├── tag_opening: "" (location: (1:55)-(1:56)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0079_begin_rescue_else_end_control_flow_in_attributes_(no_spaces)_7801d8fa47bad7b1907c4f815c6c6572.txt b/test/snapshots/parser/attributes_test/test_0079_begin_rescue_else_end_control_flow_in_attributes_(no_spaces)_7801d8fa47bad7b1907c4f815c6c6572.txt new file mode 100644 index 000000000..612df59b2 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0079_begin_rescue_else_end_control_flow_in_attributes_(no_spaces)_7801d8fa47bad7b1907c4f815c6c6572.txt @@ -0,0 +1,87 @@ +--- +source: "Parser::AttributesTest#test_0079_begin/rescue/else/end control flow in attributes (no spaces)" +input: "
data-one<%rescue%>data-error<%else%>data-success<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:76)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:76)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:70)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:69)-(1:70)) + │ ├── children: (1 item) + │ │ └── @ ERBBeginNode (location: (1:5)-(1:69)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "begin" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── rescue_clause: + │ │ │ └── @ ERBRescueNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "rescue" (location: (1:24)-(1:30)) + │ │ │ ├── tag_closing: "%>" (location: (1:30)-(1:32)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:32)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── content: "data-error" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ └── subsequent: ∅ + │ │ │ + │ │ ├── else_clause: + │ │ │ └── @ ERBElseNode (location: (1:42)-(1:50)) + │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ ├── content: "else" (location: (1:44)-(1:48)) + │ │ │ ├── tag_closing: "%>" (location: (1:48)-(1:50)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:50)-(1:62)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:50)-(1:62)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:50)-(1:62)) + │ │ │ │ └── content: "data-success" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── ensure_clause: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:62)-(1:69)) + │ │ ├── tag_opening: "<%" (location: (1:62)-(1:64)) + │ │ ├── content: "end" (location: (1:64)-(1:67)) + │ │ └── tag_closing: "%>" (location: (1:67)-(1:69)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:70)-(1:76)) + │ ├── tag_opening: "" (location: (1:75)-(1:76)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0080_begin_rescue_ensure_end_control_flow_in_attributes_(no_spaces)_da9b658abe61460610d693735c9b3798.txt b/test/snapshots/parser/attributes_test/test_0080_begin_rescue_ensure_end_control_flow_in_attributes_(no_spaces)_da9b658abe61460610d693735c9b3798.txt new file mode 100644 index 000000000..62e9de767 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0080_begin_rescue_ensure_end_control_flow_in_attributes_(no_spaces)_da9b658abe61460610d693735c9b3798.txt @@ -0,0 +1,87 @@ +--- +source: "Parser::AttributesTest#test_0080_begin/rescue/ensure/end control flow in attributes (no spaces)" +input: "
data-one<%rescue%>data-error<%ensure%>data-always<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:77)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:77)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:71)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:70)-(1:71)) + │ ├── children: (1 item) + │ │ └── @ ERBBeginNode (location: (1:5)-(1:70)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "begin" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── rescue_clause: + │ │ │ └── @ ERBRescueNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "rescue" (location: (1:24)-(1:30)) + │ │ │ ├── tag_closing: "%>" (location: (1:30)-(1:32)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:32)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── content: "data-error" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ └── subsequent: ∅ + │ │ │ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: + │ │ │ └── @ ERBEnsureNode (location: (1:42)-(1:52)) + │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ ├── content: "ensure" (location: (1:44)-(1:50)) + │ │ │ ├── tag_closing: "%>" (location: (1:50)-(1:52)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:52)-(1:63)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:52)-(1:63)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:52)-(1:63)) + │ │ │ │ └── content: "data-always" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:63)-(1:70)) + │ │ ├── tag_opening: "<%" (location: (1:63)-(1:65)) + │ │ ├── content: "end" (location: (1:65)-(1:68)) + │ │ └── tag_closing: "%>" (location: (1:68)-(1:70)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:71)-(1:77)) + │ ├── tag_opening: "" (location: (1:76)-(1:77)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0081_begin_rescue_else_ensure_end_control_flow_in_attributes_(no_spaces)_22bee6b8643f463b00fd7f516773742a.txt b/test/snapshots/parser/attributes_test/test_0081_begin_rescue_else_ensure_end_control_flow_in_attributes_(no_spaces)_22bee6b8643f463b00fd7f516773742a.txt new file mode 100644 index 000000000..3f1b2258d --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0081_begin_rescue_else_ensure_end_control_flow_in_attributes_(no_spaces)_22bee6b8643f463b00fd7f516773742a.txt @@ -0,0 +1,104 @@ +--- +source: "Parser::AttributesTest#test_0081_begin/rescue/else/ensure/end control flow in attributes (no spaces)" +input: "
data-one<%rescue%>data-error<%else%>data-success<%ensure%>data-always<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:97)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:97)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:91)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:90)-(1:91)) + │ ├── children: (1 item) + │ │ └── @ ERBBeginNode (location: (1:5)-(1:90)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "begin" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── rescue_clause: + │ │ │ └── @ ERBRescueNode (location: (1:22)-(1:42)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "rescue" (location: (1:24)-(1:30)) + │ │ │ ├── tag_closing: "%>" (location: (1:30)-(1:32)) + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:32)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:32)-(1:42)) + │ │ │ │ │ └── content: "data-error" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ └── subsequent: ∅ + │ │ │ + │ │ ├── else_clause: + │ │ │ └── @ ERBElseNode (location: (1:42)-(1:50)) + │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ ├── content: "else" (location: (1:44)-(1:48)) + │ │ │ ├── tag_closing: "%>" (location: (1:48)-(1:50)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:50)-(1:62)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:50)-(1:62)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:50)-(1:62)) + │ │ │ │ └── content: "data-success" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ ├── ensure_clause: + │ │ │ └── @ ERBEnsureNode (location: (1:62)-(1:72)) + │ │ │ ├── tag_opening: "<%" (location: (1:62)-(1:64)) + │ │ │ ├── content: "ensure" (location: (1:64)-(1:70)) + │ │ │ ├── tag_closing: "%>" (location: (1:70)-(1:72)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:72)-(1:83)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:72)-(1:83)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:72)-(1:83)) + │ │ │ │ └── content: "data-always" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:83)-(1:90)) + │ │ ├── tag_opening: "<%" (location: (1:83)-(1:85)) + │ │ ├── content: "end" (location: (1:85)-(1:88)) + │ │ └── tag_closing: "%>" (location: (1:88)-(1:90)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:91)-(1:97)) + │ ├── tag_opening: "" (location: (1:96)-(1:97)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0082_begin_ensure_end_control_flow_in_attributes_(no_spaces)_b28491b2c2b5ef8e54173c4808e29e26.txt b/test/snapshots/parser/attributes_test/test_0082_begin_ensure_end_control_flow_in_attributes_(no_spaces)_b28491b2c2b5ef8e54173c4808e29e26.txt new file mode 100644 index 000000000..71ea5ee2c --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0082_begin_ensure_end_control_flow_in_attributes_(no_spaces)_b28491b2c2b5ef8e54173c4808e29e26.txt @@ -0,0 +1,69 @@ +--- +source: "Parser::AttributesTest#test_0082_begin/ensure/end control flow in attributes (no spaces)" +input: "
data-one<%ensure%>data-always<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:57)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:57)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:51)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:50)-(1:51)) + │ ├── children: (1 item) + │ │ └── @ ERBBeginNode (location: (1:5)-(1:50)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "begin" (location: (1:7)-(1:12)) + │ │ ├── tag_closing: "%>" (location: (1:12)-(1:14)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:14)-(1:22)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:14)-(1:22)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:14)-(1:22)) + │ │ │ │ └── content: "data-one" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── rescue_clause: ∅ + │ │ ├── else_clause: ∅ + │ │ ├── ensure_clause: + │ │ │ └── @ ERBEnsureNode (location: (1:22)-(1:32)) + │ │ │ ├── tag_opening: "<%" (location: (1:22)-(1:24)) + │ │ │ ├── content: "ensure" (location: (1:24)-(1:30)) + │ │ │ ├── tag_closing: "%>" (location: (1:30)-(1:32)) + │ │ │ └── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:32)-(1:43)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:32)-(1:43)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:32)-(1:43)) + │ │ │ │ └── content: "data-always" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:43)-(1:50)) + │ │ ├── tag_opening: "<%" (location: (1:43)-(1:45)) + │ │ ├── content: "end" (location: (1:45)-(1:48)) + │ │ └── tag_closing: "%>" (location: (1:48)-(1:50)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:51)-(1:57)) + │ ├── tag_opening: "" (location: (1:56)-(1:57)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0083_while_end_control_flow_in_attributes_(no_spaces)_2e8f3266e8a37532ec2fbddb0d51abe3.txt b/test/snapshots/parser/attributes_test/test_0083_while_end_control_flow_in_attributes_(no_spaces)_2e8f3266e8a37532ec2fbddb0d51abe3.txt new file mode 100644 index 000000000..953df21f3 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0083_while_end_control_flow_in_attributes_(no_spaces)_2e8f3266e8a37532ec2fbddb0d51abe3.txt @@ -0,0 +1,49 @@ +--- +source: "Parser::AttributesTest#test_0083_while/end control flow in attributes (no spaces)" +input: "
data-item<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:42)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:42)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:36)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:35)-(1:36)) + │ ├── children: (1 item) + │ │ └── @ ERBWhileNode (location: (1:5)-(1:35)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "while cond" (location: (1:7)-(1:17)) + │ │ ├── tag_closing: "%>" (location: (1:17)-(1:19)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:19)-(1:28)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:19)-(1:28)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:19)-(1:28)) + │ │ │ │ └── content: "data-item" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:28)-(1:35)) + │ │ ├── tag_opening: "<%" (location: (1:28)-(1:30)) + │ │ ├── content: "end" (location: (1:30)-(1:33)) + │ │ └── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:36)-(1:42)) + │ ├── tag_opening: "" (location: (1:41)-(1:42)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0084_until_end_control_flow_in_attributes_(no_spaces)_4123501fcf8c52c20935146728924c33.txt b/test/snapshots/parser/attributes_test/test_0084_until_end_control_flow_in_attributes_(no_spaces)_4123501fcf8c52c20935146728924c33.txt new file mode 100644 index 000000000..603b90c53 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0084_until_end_control_flow_in_attributes_(no_spaces)_4123501fcf8c52c20935146728924c33.txt @@ -0,0 +1,49 @@ +--- +source: "Parser::AttributesTest#test_0084_until/end control flow in attributes (no spaces)" +input: "
data-item<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:42)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:42)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:36)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:35)-(1:36)) + │ ├── children: (1 item) + │ │ └── @ ERBUntilNode (location: (1:5)-(1:35)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "until done" (location: (1:7)-(1:17)) + │ │ ├── tag_closing: "%>" (location: (1:17)-(1:19)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:19)-(1:28)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:19)-(1:28)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:19)-(1:28)) + │ │ │ │ └── content: "data-item" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:28)-(1:35)) + │ │ ├── tag_opening: "<%" (location: (1:28)-(1:30)) + │ │ ├── content: "end" (location: (1:30)-(1:33)) + │ │ └── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:36)-(1:42)) + │ ├── tag_opening: "" (location: (1:41)-(1:42)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0085_for_end_control_flow_in_attributes_(no_spaces)_cec20f9884e02e47621408613b8c74ff.txt b/test/snapshots/parser/attributes_test/test_0085_for_end_control_flow_in_attributes_(no_spaces)_cec20f9884e02e47621408613b8c74ff.txt new file mode 100644 index 000000000..85fa315e1 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0085_for_end_control_flow_in_attributes_(no_spaces)_cec20f9884e02e47621408613b8c74ff.txt @@ -0,0 +1,49 @@ +--- +source: "Parser::AttributesTest#test_0085_for/end control flow in attributes (no spaces)" +input: "
data-item<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:46)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:46)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:40)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:39)-(1:40)) + │ ├── children: (1 item) + │ │ └── @ ERBForNode (location: (1:5)-(1:39)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "for i in items" (location: (1:7)-(1:21)) + │ │ ├── tag_closing: "%>" (location: (1:21)-(1:23)) + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:23)-(1:32)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:23)-(1:32)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:23)-(1:32)) + │ │ │ │ └── content: "data-item" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:32)-(1:39)) + │ │ ├── tag_opening: "<%" (location: (1:32)-(1:34)) + │ │ ├── content: "end" (location: (1:34)-(1:37)) + │ │ └── tag_closing: "%>" (location: (1:37)-(1:39)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:40)-(1:46)) + │ ├── tag_opening: "" (location: (1:45)-(1:46)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0086_block_do_end_control_flow_in_attributes_(no_spaces)_cd98fd353e5642925fde50aa09b8883c.txt b/test/snapshots/parser/attributes_test/test_0086_block_do_end_control_flow_in_attributes_(no_spaces)_cd98fd353e5642925fde50aa09b8883c.txt new file mode 100644 index 000000000..3107d8601 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0086_block_do_end_control_flow_in_attributes_(no_spaces)_cd98fd353e5642925fde50aa09b8883c.txt @@ -0,0 +1,49 @@ +--- +source: "Parser::AttributesTest#test_0086_block do/end control flow in attributes (no spaces)" +input: "
data-item<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:45)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:45)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:39)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:38)-(1:39)) + │ ├── children: (1 item) + │ │ └── @ ERBBlockNode (location: (1:5)-(1:38)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "items.each do" (location: (1:7)-(1:20)) + │ │ ├── tag_closing: "%>" (location: (1:20)-(1:22)) + │ │ ├── body: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:22)-(1:31)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:22)-(1:31)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:22)-(1:31)) + │ │ │ │ └── content: "data-item" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:31)-(1:38)) + │ │ ├── tag_opening: "<%" (location: (1:31)-(1:33)) + │ │ ├── content: "end" (location: (1:33)-(1:36)) + │ │ └── tag_closing: "%>" (location: (1:36)-(1:38)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:39)-(1:45)) + │ ├── tag_opening: "" (location: (1:44)-(1:45)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0087_block_do_with_args_end_control_flow_in_attributes_(no_spaces)_91c453938988e8052ce3c57ec43085d1.txt b/test/snapshots/parser/attributes_test/test_0087_block_do_with_args_end_control_flow_in_attributes_(no_spaces)_91c453938988e8052ce3c57ec43085d1.txt new file mode 100644 index 000000000..9538f6db3 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0087_block_do_with_args_end_control_flow_in_attributes_(no_spaces)_91c453938988e8052ce3c57ec43085d1.txt @@ -0,0 +1,49 @@ +--- +source: "Parser::AttributesTest#test_0087_block do with args/end control flow in attributes (no spaces)" +input: "
data-item<%end%>>
" +--- +@ DocumentNode (location: (1:0)-(1:52)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:52)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:46)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:45)-(1:46)) + │ ├── children: (1 item) + │ │ └── @ ERBBlockNode (location: (1:5)-(1:45)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: "items.each do |item|" (location: (1:7)-(1:27)) + │ │ ├── tag_closing: "%>" (location: (1:27)-(1:29)) + │ │ ├── body: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:29)-(1:38)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:29)-(1:38)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:29)-(1:38)) + │ │ │ │ └── content: "data-item" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:38)-(1:45)) + │ │ ├── tag_opening: "<%" (location: (1:38)-(1:40)) + │ │ ├── content: "end" (location: (1:40)-(1:43)) + │ │ └── tag_closing: "%>" (location: (1:43)-(1:45)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:46)-(1:52)) + │ ├── tag_opening: "" (location: (1:51)-(1:52)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0088_issue_#1063_conditional_boolean_attribute_open_(no_spaces_around_attribute)_21f85c26e4ad76ffd2bdcff26b88a684.txt b/test/snapshots/parser/attributes_test/test_0088_issue_#1063_conditional_boolean_attribute_open_(no_spaces_around_attribute)_21f85c26e4ad76ffd2bdcff26b88a684.txt new file mode 100644 index 000000000..6bf570b66 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0088_issue_#1063_conditional_boolean_attribute_open_(no_spaces_around_attribute)_21f85c26e4ad76ffd2bdcff26b88a684.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0088_issue #1063: conditional boolean attribute open (no spaces around attribute)" +input: "
open<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:71)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:71)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:61)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:60)-(1:61)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:9)-(1:60)) + │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ ├── content: " if @doc.registration_id.present? " (location: (1:11)-(1:45)) + │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:47)-(1:51)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:47)-(1:51)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:47)-(1:51)) + │ │ │ │ └── content: "open" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:51)-(1:60)) + │ │ ├── tag_opening: "<%" (location: (1:51)-(1:53)) + │ │ ├── content: " end " (location: (1:53)-(1:58)) + │ │ └── tag_closing: "%>" (location: (1:58)-(1:60)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:61)-(1:71)) + │ ├── tag_opening: "" (location: (1:70)-(1:71)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0089_issue_#1063_conditional_boolean_attribute_open_(space_after_attribute)_af0945767bcb7bb951308eb807e10e27.txt b/test/snapshots/parser/attributes_test/test_0089_issue_#1063_conditional_boolean_attribute_open_(space_after_attribute)_af0945767bcb7bb951308eb807e10e27.txt new file mode 100644 index 000000000..2e86bfe0f --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0089_issue_#1063_conditional_boolean_attribute_open_(space_after_attribute)_af0945767bcb7bb951308eb807e10e27.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0089_issue #1063: conditional boolean attribute open (space after attribute)" +input: "
open <% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:72)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:72)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:62)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:61)-(1:62)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:9)-(1:61)) + │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ ├── content: " if @doc.registration_id.present? " (location: (1:11)-(1:45)) + │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:47)-(1:51)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:47)-(1:51)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:47)-(1:51)) + │ │ │ │ └── content: "open" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:52)-(1:61)) + │ │ ├── tag_opening: "<%" (location: (1:52)-(1:54)) + │ │ ├── content: " end " (location: (1:54)-(1:59)) + │ │ └── tag_closing: "%>" (location: (1:59)-(1:61)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:62)-(1:72)) + │ ├── tag_opening: "" (location: (1:71)-(1:72)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0090_issue_#1063_conditional_boolean_attribute_open_(space_before_attribute)_4ab1dfa03e2724be706bcc82b58058a3.txt b/test/snapshots/parser/attributes_test/test_0090_issue_#1063_conditional_boolean_attribute_open_(space_before_attribute)_4ab1dfa03e2724be706bcc82b58058a3.txt new file mode 100644 index 000000000..d0e5bea15 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0090_issue_#1063_conditional_boolean_attribute_open_(space_before_attribute)_4ab1dfa03e2724be706bcc82b58058a3.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0090_issue #1063: conditional boolean attribute open (space before attribute)" +input: "
open<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:72)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:72)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:62)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:61)-(1:62)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:9)-(1:61)) + │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ ├── content: " if @doc.registration_id.present? " (location: (1:11)-(1:45)) + │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:48)-(1:52)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:48)-(1:52)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:48)-(1:52)) + │ │ │ │ └── content: "open" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:52)-(1:61)) + │ │ ├── tag_opening: "<%" (location: (1:52)-(1:54)) + │ │ ├── content: " end " (location: (1:54)-(1:59)) + │ │ └── tag_closing: "%>" (location: (1:59)-(1:61)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:62)-(1:72)) + │ ├── tag_opening: "" (location: (1:71)-(1:72)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0091_issue_#1063_conditional_boolean_attribute_open_(spaces_around_attribute)_3269b2eef75d593930fdea654b6d4829.txt b/test/snapshots/parser/attributes_test/test_0091_issue_#1063_conditional_boolean_attribute_open_(spaces_around_attribute)_3269b2eef75d593930fdea654b6d4829.txt new file mode 100644 index 000000000..213b3b943 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0091_issue_#1063_conditional_boolean_attribute_open_(spaces_around_attribute)_3269b2eef75d593930fdea654b6d4829.txt @@ -0,0 +1,51 @@ +--- +source: "Parser::AttributesTest#test_0091_issue #1063: conditional boolean attribute open (spaces around attribute)" +input: "
open <% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:73)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:73)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:63)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:62)-(1:63)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:9)-(1:62)) + │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ ├── content: " if @doc.registration_id.present? " (location: (1:11)-(1:45)) + │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:48)-(1:52)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:48)-(1:52)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:48)-(1:52)) + │ │ │ │ └── content: "open" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:53)-(1:62)) + │ │ ├── tag_opening: "<%" (location: (1:53)-(1:55)) + │ │ ├── content: " end " (location: (1:55)-(1:60)) + │ │ └── tag_closing: "%>" (location: (1:60)-(1:62)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:63)-(1:73)) + │ ├── tag_opening: "" (location: (1:72)-(1:73)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0092_issue_#1063_two_conditional_attributes_back-to-back_(with_spaces)_0b1ff653f2083d4ed761e301d4a349fc.txt b/test/snapshots/parser/attributes_test/test_0092_issue_#1063_two_conditional_attributes_back-to-back_(with_spaces)_0b1ff653f2083d4ed761e301d4a349fc.txt new file mode 100644 index 000000000..d12803f0d --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0092_issue_#1063_two_conditional_attributes_back-to-back_(with_spaces)_0b1ff653f2083d4ed761e301d4a349fc.txt @@ -0,0 +1,85 @@ +--- +source: "Parser::AttributesTest#test_0092_issue #1063: two conditional attributes back-to-back (with spaces)" +input: "
open <% end %> <% if b? %>style='color: red;'<% end %> >
" +--- +@ DocumentNode (location: (1:0)-(1:87)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:87)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:77)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:76)-(1:77)) + │ ├── children: (2 items) + │ │ ├── @ ERBIfNode (location: (1:9)-(1:35)) + │ │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ │ ├── content: " if a? " (location: (1:11)-(1:18)) + │ │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:21)-(1:25)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:21)-(1:25)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:21)-(1:25)) + │ │ │ │ │ └── content: "open" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:26)-(1:35)) + │ │ │ ├── tag_opening: "<%" (location: (1:26)-(1:28)) + │ │ │ ├── content: " end " (location: (1:28)-(1:33)) + │ │ │ └── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:36)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:36)-(1:38)) + │ │ ├── content: " if b? " (location: (1:38)-(1:45)) + │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:47)-(1:66)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:47)-(1:52)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:47)-(1:52)) + │ │ │ │ └── content: "style" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:52)-(1:53)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:53)-(1:66)) + │ │ │ ├── open_quote: "'" (location: (1:53)-(1:54)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:54)-(1:65)) + │ │ │ │ └── content: "color: red;" + │ │ │ │ + │ │ │ ├── close_quote: "'" (location: (1:65)-(1:66)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:66)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:66)-(1:68)) + │ │ ├── content: " end " (location: (1:68)-(1:73)) + │ │ └── tag_closing: "%>" (location: (1:73)-(1:75)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:77)-(1:87)) + │ ├── tag_opening: "" (location: (1:86)-(1:87)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0093_issue_#1063_two_conditional_attributes_back-to-back_(no_spaces)_58860a73111fa6c30c3eb948a5712bb0.txt b/test/snapshots/parser/attributes_test/test_0093_issue_#1063_two_conditional_attributes_back-to-back_(no_spaces)_58860a73111fa6c30c3eb948a5712bb0.txt new file mode 100644 index 000000000..b3711e744 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0093_issue_#1063_two_conditional_attributes_back-to-back_(no_spaces)_58860a73111fa6c30c3eb948a5712bb0.txt @@ -0,0 +1,85 @@ +--- +source: "Parser::AttributesTest#test_0093_issue #1063: two conditional attributes back-to-back (no spaces)" +input: "
open<% end %><% if b? %>style='color: red;'<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:83)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:83)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:73)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "details" (location: (1:1)-(1:8)) + │ ├── tag_closing: ">" (location: (1:72)-(1:73)) + │ ├── children: (2 items) + │ │ ├── @ ERBIfNode (location: (1:9)-(1:33)) + │ │ │ ├── tag_opening: "<%" (location: (1:9)-(1:11)) + │ │ │ ├── content: " if a? " (location: (1:11)-(1:18)) + │ │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:20)-(1:24)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:20)-(1:24)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:20)-(1:24)) + │ │ │ │ │ └── content: "open" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:24)-(1:33)) + │ │ │ ├── tag_opening: "<%" (location: (1:24)-(1:26)) + │ │ │ ├── content: " end " (location: (1:26)-(1:31)) + │ │ │ └── tag_closing: "%>" (location: (1:31)-(1:33)) + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:33)-(1:72)) + │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ ├── content: " if b? " (location: (1:35)-(1:42)) + │ │ ├── tag_closing: "%>" (location: (1:42)-(1:44)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:44)-(1:63)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:44)-(1:49)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:44)-(1:49)) + │ │ │ │ └── content: "style" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:49)-(1:50)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:50)-(1:63)) + │ │ │ ├── open_quote: "'" (location: (1:50)-(1:51)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:51)-(1:62)) + │ │ │ │ └── content: "color: red;" + │ │ │ │ + │ │ │ ├── close_quote: "'" (location: (1:62)-(1:63)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:63)-(1:72)) + │ │ ├── tag_opening: "<%" (location: (1:63)-(1:65)) + │ │ ├── content: " end " (location: (1:65)-(1:70)) + │ │ └── tag_closing: "%>" (location: (1:70)-(1:72)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "details" (location: (1:1)-(1:8)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:73)-(1:83)) + │ ├── tag_opening: "" (location: (1:82)-(1:83)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt b/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt new file mode 100644 index 000000000..6ccd8c3b2 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt @@ -0,0 +1,91 @@ +--- +source: "Parser::AttributesTest#test_0094_multiple regular attributes before conditional" +input: "
data-active<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:76)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:76)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:70)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:69)-(1:70)) + │ ├── children: (3 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:14)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:7)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:7)) + │ │ │ │ └── content: "id" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:7)-(1:8)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:8)-(1:14)) + │ │ │ ├── open_quote: """ (location: (1:8)-(1:9)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:9)-(1:13)) + │ │ │ │ └── content: "main" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:13)-(1:14)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── @ HTMLAttributeNode (location: (1:15)-(1:32)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:15)-(1:20)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:15)-(1:20)) + │ │ │ │ └── content: "class" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:20)-(1:21)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:21)-(1:32)) + │ │ │ ├── open_quote: """ (location: (1:21)-(1:22)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:22)-(1:31)) + │ │ │ │ └── content: "container" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:31)-(1:32)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:33)-(1:69)) + │ │ ├── tag_opening: "<%" (location: (1:33)-(1:35)) + │ │ ├── content: " if active? " (location: (1:35)-(1:47)) + │ │ ├── tag_closing: "%>" (location: (1:47)-(1:49)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:49)-(1:60)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:49)-(1:60)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:49)-(1:60)) + │ │ │ │ └── content: "data-active" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:60)-(1:69)) + │ │ ├── tag_opening: "<%" (location: (1:60)-(1:62)) + │ │ ├── content: " end " (location: (1:62)-(1:67)) + │ │ └── tag_closing: "%>" (location: (1:67)-(1:69)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:70)-(1:76)) + │ ├── tag_opening: "" (location: (1:75)-(1:76)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt new file mode 100644 index 000000000..c1954d51e --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt @@ -0,0 +1,91 @@ +--- +source: "Parser::AttributesTest#test_0095_multiple regular attributes after conditional" +input: "
data-active<% end %> id=\"main\" class=\"container\">
" +--- +@ DocumentNode (location: (1:0)-(1:76)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:76)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:70)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:69)-(1:70)) + │ ├── children: (3 items) + │ │ ├── @ ERBIfNode (location: (1:5)-(1:41)) + │ │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ │ ├── content: " if active? " (location: (1:7)-(1:19)) + │ │ │ ├── tag_closing: "%>" (location: (1:19)-(1:21)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:21)-(1:32)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:21)-(1:32)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:21)-(1:32)) + │ │ │ │ │ └── content: "data-active" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:32)-(1:41)) + │ │ │ ├── tag_opening: "<%" (location: (1:32)-(1:34)) + │ │ │ ├── content: " end " (location: (1:34)-(1:39)) + │ │ │ └── tag_closing: "%>" (location: (1:39)-(1:41)) + │ │ │ + │ │ │ + │ │ ├── @ HTMLAttributeNode (location: (1:42)-(1:51)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:42)-(1:44)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:42)-(1:44)) + │ │ │ │ └── content: "id" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:44)-(1:45)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:45)-(1:51)) + │ │ │ ├── open_quote: """ (location: (1:45)-(1:46)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:46)-(1:50)) + │ │ │ │ └── content: "main" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:50)-(1:51)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:52)-(1:69)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:52)-(1:57)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:52)-(1:57)) + │ │ │ └── content: "class" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:57)-(1:58)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:58)-(1:69)) + │ │ ├── open_quote: """ (location: (1:58)-(1:59)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:59)-(1:68)) + │ │ │ └── content: "container" + │ │ │ + │ │ ├── close_quote: """ (location: (1:68)-(1:69)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:70)-(1:76)) + │ ├── tag_opening: "" (location: (1:75)-(1:76)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt b/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt new file mode 100644 index 000000000..274b6db39 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt @@ -0,0 +1,91 @@ +--- +source: "Parser::AttributesTest#test_0096_conditional attribute between regular attributes" +input: "
data-active<% end %> class=\"container\">
" +--- +@ DocumentNode (location: (1:0)-(1:76)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:76)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:70)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:69)-(1:70)) + │ ├── children: (3 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:14)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:7)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:7)) + │ │ │ │ └── content: "id" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:7)-(1:8)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:8)-(1:14)) + │ │ │ ├── open_quote: """ (location: (1:8)-(1:9)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:9)-(1:13)) + │ │ │ │ └── content: "main" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:13)-(1:14)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── @ ERBIfNode (location: (1:15)-(1:51)) + │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ ├── content: " if active? " (location: (1:17)-(1:29)) + │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:31)-(1:42)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:31)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:31)-(1:42)) + │ │ │ │ │ └── content: "data-active" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:42)-(1:51)) + │ │ │ ├── tag_opening: "<%" (location: (1:42)-(1:44)) + │ │ │ ├── content: " end " (location: (1:44)-(1:49)) + │ │ │ └── tag_closing: "%>" (location: (1:49)-(1:51)) + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:52)-(1:69)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:52)-(1:57)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:52)-(1:57)) + │ │ │ └── content: "class" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:57)-(1:58)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:58)-(1:69)) + │ │ ├── open_quote: """ (location: (1:58)-(1:59)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:59)-(1:68)) + │ │ │ └── content: "container" + │ │ │ + │ │ ├── close_quote: """ (location: (1:68)-(1:69)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:70)-(1:76)) + │ ├── tag_opening: "" (location: (1:75)-(1:76)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt new file mode 100644 index 000000000..add1153aa --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt @@ -0,0 +1,100 @@ +--- +source: "Parser::AttributesTest#test_0097_conditional attribute with value between regular attributes" +input: "
data-active=\"true\"<% end %> class=\"container\">
" +--- +@ DocumentNode (location: (1:0)-(1:83)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:83)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:77)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:76)-(1:77)) + │ ├── children: (3 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:14)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:7)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:7)) + │ │ │ │ └── content: "id" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:7)-(1:8)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:8)-(1:14)) + │ │ │ ├── open_quote: """ (location: (1:8)-(1:9)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:9)-(1:13)) + │ │ │ │ └── content: "main" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:13)-(1:14)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── @ ERBIfNode (location: (1:15)-(1:58)) + │ │ │ ├── tag_opening: "<%" (location: (1:15)-(1:17)) + │ │ │ ├── content: " if active? " (location: (1:17)-(1:29)) + │ │ │ ├── tag_closing: "%>" (location: (1:29)-(1:31)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:31)-(1:49)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:31)-(1:42)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:31)-(1:42)) + │ │ │ │ │ └── content: "data-active" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: "=" (location: (1:42)-(1:43)) + │ │ │ │ └── value: + │ │ │ │ └── @ HTMLAttributeValueNode (location: (1:43)-(1:49)) + │ │ │ │ ├── open_quote: """ (location: (1:43)-(1:44)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:44)-(1:48)) + │ │ │ │ │ └── content: "true" + │ │ │ │ │ + │ │ │ │ ├── close_quote: """ (location: (1:48)-(1:49)) + │ │ │ │ └── quoted: true + │ │ │ │ + │ │ │ │ + │ │ │ ├── subsequent: ∅ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:49)-(1:58)) + │ │ │ ├── tag_opening: "<%" (location: (1:49)-(1:51)) + │ │ │ ├── content: " end " (location: (1:51)-(1:56)) + │ │ │ └── tag_closing: "%>" (location: (1:56)-(1:58)) + │ │ │ + │ │ │ + │ │ └── @ HTMLAttributeNode (location: (1:59)-(1:76)) + │ │ ├── name: + │ │ │ └── @ HTMLAttributeNameNode (location: (1:59)-(1:64)) + │ │ │ └── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:59)-(1:64)) + │ │ │ └── content: "class" + │ │ │ + │ │ │ + │ │ ├── equals: "=" (location: (1:64)-(1:65)) + │ │ └── value: + │ │ └── @ HTMLAttributeValueNode (location: (1:65)-(1:76)) + │ │ ├── open_quote: """ (location: (1:65)-(1:66)) + │ │ ├── children: (1 item) + │ │ │ └── @ LiteralNode (location: (1:66)-(1:75)) + │ │ │ └── content: "container" + │ │ │ + │ │ ├── close_quote: """ (location: (1:75)-(1:76)) + │ │ └── quoted: true + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:77)-(1:83)) + │ ├── tag_opening: "" (location: (1:82)-(1:83)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt b/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt new file mode 100644 index 000000000..126bb08b9 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt @@ -0,0 +1,82 @@ +--- +source: "Parser::AttributesTest#test_0098_nested conditionals in attributes" +input: "
<% if inner? %>data-inner<% else %>data-outer<% end %><% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:90)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:90)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:84)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:83)-(1:84)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:83)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if outer? " (location: (1:7)-(1:18)) + │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ ERBIfNode (location: (1:20)-(1:74)) + │ │ │ ├── tag_opening: "<%" (location: (1:20)-(1:22)) + │ │ │ ├── content: " if inner? " (location: (1:22)-(1:33)) + │ │ │ ├── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ │ ├── then_keyword: ∅ + │ │ │ ├── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:35)-(1:45)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:35)-(1:45)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:35)-(1:45)) + │ │ │ │ │ └── content: "data-inner" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── subsequent: + │ │ │ │ └── @ ERBElseNode (location: (1:45)-(1:65)) + │ │ │ │ ├── tag_opening: "<%" (location: (1:45)-(1:47)) + │ │ │ │ ├── content: " else " (location: (1:47)-(1:53)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:53)-(1:55)) + │ │ │ │ └── statements: (1 item) + │ │ │ │ └── @ HTMLAttributeNode (location: (1:55)-(1:65)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:55)-(1:65)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:55)-(1:65)) + │ │ │ │ │ └── content: "data-outer" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ │ + │ │ │ └── end_node: + │ │ │ └── @ ERBEndNode (location: (1:65)-(1:74)) + │ │ │ ├── tag_opening: "<%" (location: (1:65)-(1:67)) + │ │ │ ├── content: " end " (location: (1:67)-(1:72)) + │ │ │ └── tag_closing: "%>" (location: (1:72)-(1:74)) + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:74)-(1:83)) + │ │ ├── tag_opening: "<%" (location: (1:74)-(1:76)) + │ │ ├── content: " end " (location: (1:76)-(1:81)) + │ │ └── tag_closing: "%>" (location: (1:81)-(1:83)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:84)-(1:90)) + │ ├── tag_opening: "" (location: (1:89)-(1:90)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt b/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt new file mode 100644 index 000000000..512ffe1d1 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt @@ -0,0 +1,91 @@ +--- +source: "Parser::AttributesTest#test_0099_conditional with multiple attributes inside" +input: "
data-admin data-role=\"admin\" data-permissions=\"all\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:87)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:87)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:81)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:80)-(1:81)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:80)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if admin? " (location: (1:7)-(1:18)) + │ │ ├── tag_closing: "%>" (location: (1:18)-(1:20)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (3 items) + │ │ │ ├── @ HTMLAttributeNode (location: (1:20)-(1:30)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:20)-(1:30)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:20)-(1:30)) + │ │ │ │ │ └── content: "data-admin" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: ∅ + │ │ │ │ └── value: ∅ + │ │ │ │ + │ │ │ ├── @ HTMLAttributeNode (location: (1:31)-(1:48)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:31)-(1:40)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:31)-(1:40)) + │ │ │ │ │ └── content: "data-role" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: "=" (location: (1:40)-(1:41)) + │ │ │ │ └── value: + │ │ │ │ └── @ HTMLAttributeValueNode (location: (1:41)-(1:48)) + │ │ │ │ ├── open_quote: """ (location: (1:41)-(1:42)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:42)-(1:47)) + │ │ │ │ │ └── content: "admin" + │ │ │ │ │ + │ │ │ │ ├── close_quote: """ (location: (1:47)-(1:48)) + │ │ │ │ └── quoted: true + │ │ │ │ + │ │ │ │ + │ │ │ └── @ HTMLAttributeNode (location: (1:49)-(1:71)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:49)-(1:65)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:49)-(1:65)) + │ │ │ │ └── content: "data-permissions" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:65)-(1:66)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:66)-(1:71)) + │ │ │ ├── open_quote: """ (location: (1:66)-(1:67)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:67)-(1:70)) + │ │ │ │ └── content: "all" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:70)-(1:71)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:71)-(1:80)) + │ │ ├── tag_opening: "<%" (location: (1:71)-(1:73)) + │ │ ├── content: " end " (location: (1:73)-(1:78)) + │ │ └── tag_closing: "%>" (location: (1:78)-(1:80)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:81)-(1:87)) + │ ├── tag_opening: "" (location: (1:86)-(1:87)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt b/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt new file mode 100644 index 000000000..5bb0c1378 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt @@ -0,0 +1,88 @@ +--- +source: "Parser::AttributesTest#test_0100_conditional with ERB output in attribute value" +input: "
data-user-id=\"<%= user.id %>\" data-user-name=\"<%= user.name %>\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:98)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:98)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:92)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:91)-(1:92)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:91)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if user? " (location: (1:7)-(1:17)) + │ │ ├── tag_closing: "%>" (location: (1:17)-(1:19)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (2 items) + │ │ │ ├── @ HTMLAttributeNode (location: (1:19)-(1:48)) + │ │ │ │ ├── name: + │ │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:19)-(1:31)) + │ │ │ │ │ └── children: (1 item) + │ │ │ │ │ └── @ LiteralNode (location: (1:19)-(1:31)) + │ │ │ │ │ └── content: "data-user-id" + │ │ │ │ │ + │ │ │ │ │ + │ │ │ │ ├── equals: "=" (location: (1:31)-(1:32)) + │ │ │ │ └── value: + │ │ │ │ └── @ HTMLAttributeValueNode (location: (1:32)-(1:48)) + │ │ │ │ ├── open_quote: """ (location: (1:32)-(1:33)) + │ │ │ │ ├── children: (1 item) + │ │ │ │ │ └── @ ERBContentNode (location: (1:33)-(1:47)) + │ │ │ │ │ ├── tag_opening: "<%=" (location: (1:33)-(1:36)) + │ │ │ │ │ ├── content: " user.id " (location: (1:36)-(1:45)) + │ │ │ │ │ ├── tag_closing: "%>" (location: (1:45)-(1:47)) + │ │ │ │ │ ├── parsed: true + │ │ │ │ │ └── valid: true + │ │ │ │ │ + │ │ │ │ ├── close_quote: """ (location: (1:47)-(1:48)) + │ │ │ │ └── quoted: true + │ │ │ │ + │ │ │ │ + │ │ │ └── @ HTMLAttributeNode (location: (1:49)-(1:82)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:49)-(1:63)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:49)-(1:63)) + │ │ │ │ └── content: "data-user-name" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:63)-(1:64)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:64)-(1:82)) + │ │ │ ├── open_quote: """ (location: (1:64)-(1:65)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ ERBContentNode (location: (1:65)-(1:81)) + │ │ │ │ ├── tag_opening: "<%=" (location: (1:65)-(1:68)) + │ │ │ │ ├── content: " user.name " (location: (1:68)-(1:79)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:79)-(1:81)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:81)-(1:82)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:82)-(1:91)) + │ │ ├── tag_opening: "<%" (location: (1:82)-(1:84)) + │ │ ├── content: " end " (location: (1:84)-(1:89)) + │ │ └── tag_closing: "%>" (location: (1:89)-(1:91)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:92)-(1:98)) + │ ├── tag_opening: "" (location: (1:97)-(1:98)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt b/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt new file mode 100644 index 000000000..924cab94c --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt @@ -0,0 +1,65 @@ +--- +source: "Parser::AttributesTest#test_0101_self-closing tag with conditional attribute" +input: "required<% end %> />" +--- +@ DocumentNode (location: (1:0)-(1:57)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:57)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:57)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "input" (location: (1:1)-(1:6)) + │ ├── tag_closing: "/>" (location: (1:55)-(1:57)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:7)-(1:18)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:7)-(1:11)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:7)-(1:11)) + │ │ │ │ └── content: "type" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:11)-(1:12)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:12)-(1:18)) + │ │ │ ├── open_quote: """ (location: (1:12)-(1:13)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:13)-(1:17)) + │ │ │ │ └── content: "text" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:17)-(1:18)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:19)-(1:54)) + │ │ ├── tag_opening: "<%" (location: (1:19)-(1:21)) + │ │ ├── content: " if required? " (location: (1:21)-(1:35)) + │ │ ├── tag_closing: "%>" (location: (1:35)-(1:37)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:37)-(1:45)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:37)-(1:45)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:37)-(1:45)) + │ │ │ │ └── content: "required" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: ∅ + │ │ │ └── value: ∅ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:45)-(1:54)) + │ │ ├── tag_opening: "<%" (location: (1:45)-(1:47)) + │ │ ├── content: " end " (location: (1:47)-(1:52)) + │ │ └── tag_closing: "%>" (location: (1:52)-(1:54)) + │ │ + │ │ + │ └── is_void: true + │ + ├── tag_name: "input" (location: (1:1)-(1:6)) + ├── body: [] + ├── close_tag: ∅ + ├── is_void: true + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt new file mode 100644 index 000000000..b8bd94786 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt @@ -0,0 +1,78 @@ +--- +source: "Parser::AttributesTest#test_0102_self-closing tag with conditional attribute and value" +input: "value=\"<%= default_value %>\"<% end %> />" +--- +@ DocumentNode (location: (1:0)-(1:78)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:78)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:78)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "input" (location: (1:1)-(1:6)) + │ ├── tag_closing: "/>" (location: (1:76)-(1:78)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:7)-(1:18)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:7)-(1:11)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:7)-(1:11)) + │ │ │ │ └── content: "type" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:11)-(1:12)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:12)-(1:18)) + │ │ │ ├── open_quote: """ (location: (1:12)-(1:13)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:13)-(1:17)) + │ │ │ │ └── content: "text" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:17)-(1:18)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:19)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:19)-(1:21)) + │ │ ├── content: " if has_value? " (location: (1:21)-(1:36)) + │ │ ├── tag_closing: "%>" (location: (1:36)-(1:38)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:38)-(1:66)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:38)-(1:43)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:38)-(1:43)) + │ │ │ │ └── content: "value" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:43)-(1:44)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:44)-(1:66)) + │ │ │ ├── open_quote: """ (location: (1:44)-(1:45)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ ERBContentNode (location: (1:45)-(1:65)) + │ │ │ │ ├── tag_opening: "<%=" (location: (1:45)-(1:48)) + │ │ │ │ ├── content: " default_value " (location: (1:48)-(1:63)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:63)-(1:65)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:65)-(1:66)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:66)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:66)-(1:68)) + │ │ ├── content: " end " (location: (1:68)-(1:73)) + │ │ └── tag_closing: "%>" (location: (1:73)-(1:75)) + │ │ + │ │ + │ └── is_void: true + │ + ├── tag_name: "input" (location: (1:1)-(1:6)) + ├── body: [] + ├── close_tag: ∅ + ├── is_void: true + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt b/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt new file mode 100644 index 000000000..e6b592354 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt @@ -0,0 +1,74 @@ +--- +source: "Parser::AttributesTest#test_0103_void element with conditional attribute" +input: "loading=\"lazy\"<% end %>>" +--- +@ DocumentNode (location: (1:0)-(1:59)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:59)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:59)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "img" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:58)-(1:59)) + │ ├── children: (2 items) + │ │ ├── @ HTMLAttributeNode (location: (1:5)-(1:20)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:5)-(1:8)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:5)-(1:8)) + │ │ │ │ └── content: "src" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:8)-(1:9)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:9)-(1:20)) + │ │ │ ├── open_quote: """ (location: (1:9)-(1:10)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:10)-(1:19)) + │ │ │ │ └── content: "image.png" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:19)-(1:20)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ └── @ ERBIfNode (location: (1:21)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:21)-(1:23)) + │ │ ├── content: " if lazy? " (location: (1:23)-(1:33)) + │ │ ├── tag_closing: "%>" (location: (1:33)-(1:35)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:35)-(1:49)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:35)-(1:42)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:35)-(1:42)) + │ │ │ │ └── content: "loading" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:42)-(1:43)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:43)-(1:49)) + │ │ │ ├── open_quote: """ (location: (1:43)-(1:44)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:44)-(1:48)) + │ │ │ │ └── content: "lazy" + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:48)-(1:49)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:49)-(1:58)) + │ │ ├── tag_opening: "<%" (location: (1:49)-(1:51)) + │ │ ├── content: " end " (location: (1:51)-(1:56)) + │ │ └── tag_closing: "%>" (location: (1:56)-(1:58)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "img" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: ∅ + ├── is_void: true + └── source: "HTML" \ No newline at end of file diff --git a/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt b/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt new file mode 100644 index 000000000..c0981dc49 --- /dev/null +++ b/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt @@ -0,0 +1,64 @@ +--- +source: "Parser::AttributesTest#test_0104_conditional class attribute with ternary in value" +input: "
class=\"<%= active ? 'active' : 'inactive' %>\"<% end %>>
" +--- +@ DocumentNode (location: (1:0)-(1:82)) +└── children: (1 item) + └── @ HTMLElementNode (location: (1:0)-(1:82)) + ├── open_tag: + │ └── @ HTMLOpenTagNode (location: (1:0)-(1:76)) + │ ├── tag_opening: "<" (location: (1:0)-(1:1)) + │ ├── tag_name: "div" (location: (1:1)-(1:4)) + │ ├── tag_closing: ">" (location: (1:75)-(1:76)) + │ ├── children: (1 item) + │ │ └── @ ERBIfNode (location: (1:5)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:5)-(1:7)) + │ │ ├── content: " if styled? " (location: (1:7)-(1:19)) + │ │ ├── tag_closing: "%>" (location: (1:19)-(1:21)) + │ │ ├── then_keyword: ∅ + │ │ ├── statements: (1 item) + │ │ │ └── @ HTMLAttributeNode (location: (1:21)-(1:66)) + │ │ │ ├── name: + │ │ │ │ └── @ HTMLAttributeNameNode (location: (1:21)-(1:26)) + │ │ │ │ └── children: (1 item) + │ │ │ │ └── @ LiteralNode (location: (1:21)-(1:26)) + │ │ │ │ └── content: "class" + │ │ │ │ + │ │ │ │ + │ │ │ ├── equals: "=" (location: (1:26)-(1:27)) + │ │ │ └── value: + │ │ │ └── @ HTMLAttributeValueNode (location: (1:27)-(1:66)) + │ │ │ ├── open_quote: """ (location: (1:27)-(1:28)) + │ │ │ ├── children: (1 item) + │ │ │ │ └── @ ERBContentNode (location: (1:28)-(1:65)) + │ │ │ │ ├── tag_opening: "<%=" (location: (1:28)-(1:31)) + │ │ │ │ ├── content: " active ? 'active' : 'inactive' " (location: (1:31)-(1:63)) + │ │ │ │ ├── tag_closing: "%>" (location: (1:63)-(1:65)) + │ │ │ │ ├── parsed: true + │ │ │ │ └── valid: true + │ │ │ │ + │ │ │ ├── close_quote: """ (location: (1:65)-(1:66)) + │ │ │ └── quoted: true + │ │ │ + │ │ │ + │ │ ├── subsequent: ∅ + │ │ └── end_node: + │ │ └── @ ERBEndNode (location: (1:66)-(1:75)) + │ │ ├── tag_opening: "<%" (location: (1:66)-(1:68)) + │ │ ├── content: " end " (location: (1:68)-(1:73)) + │ │ └── tag_closing: "%>" (location: (1:73)-(1:75)) + │ │ + │ │ + │ └── is_void: false + │ + ├── tag_name: "div" (location: (1:1)-(1:4)) + ├── body: [] + ├── close_tag: + │ └── @ HTMLCloseTagNode (location: (1:76)-(1:82)) + │ ├── tag_opening: "" (location: (1:81)-(1:82)) + │ + ├── is_void: false + └── source: "HTML" \ No newline at end of file From 4de0c47ecfed0ea13115e10c816ecdb2c38fce4a Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Wed, 11 Feb 2026 09:07:04 +0100 Subject: [PATCH 4/5] Add one more test --- test/parser/attributes_test.rb | 6 +++++- ...efore_html_tag_end_8b8da9205eb731ac258036f24249144e.txt} | 2 +- ...before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt} | 2 +- ..._after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt} | 2 +- ...regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt} | 2 +- ...regular_attributes_042e33e3b667bd90f51576fb32384468.txt} | 2 +- ...nals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt} | 2 +- ..._attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt} | 2 +- ...in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt} | 2 +- ...ditional_attribute_44720e6b8d80626b1067450c32388bcc.txt} | 2 +- ...ttribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt} | 2 +- ...ditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt} | 2 +- ...h_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt} | 2 +- 13 files changed, 17 insertions(+), 13 deletions(-) rename test/snapshots/parser/attributes_test/{test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt => test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt} (97%) rename test/snapshots/parser/attributes_test/{test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt => test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt => test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt => test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt => test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt => test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt => test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt => test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt => test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt => test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt => test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt => test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt} (98%) diff --git a/test/parser/attributes_test.rb b/test/parser/attributes_test.rb index ed55de92b..158a8b56f 100644 --- a/test/parser/attributes_test.rb +++ b/test/parser/attributes_test.rb @@ -293,7 +293,6 @@ class AttributesTest < Minitest::Spec )) end - # Control flow in attributes - comprehensive tests (no spaces in ERB tags) test "if/elsif/else/end control flow in attributes (no spaces)" do assert_parsed_snapshot(%(
data-one<%elsif b?%>data-two<%else%>data-three<%end%>>
)) end @@ -402,6 +401,11 @@ class AttributesTest < Minitest::Spec assert_parsed_snapshot(%(
open<% end %><% if b? %>style='color: red;'<% end %>>
)) end + # https://github.com/marcoroth/herb/issues/856#issuecomment-3525179643 + test "issue #856: data-turbo-permanent in if right before html tag end" do + assert_parsed_snapshot(%(data-turbo-permanent<% end %>>)) + end + test "multiple regular attributes before conditional" do assert_parsed_snapshot(%(
data-active<% end %>>
)) end diff --git a/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt b/test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt similarity index 97% rename from test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt rename to test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt index 30996c2bd..2b113d829 100644 --- a/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt +++ b/test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0047_Conditional attribute with ERB control flow and no surrounding spaces" +source: "Parser::AttributesTest#test_0094_issue #856: data-turbo-permanent in if right before html tag end" input: "data-turbo-permanent<% end %>>" --- @ DocumentNode (location: (1:0)-(1:106)) diff --git a/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt rename to test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt index 6ccd8c3b2..01f863045 100644 --- a/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt +++ b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0094_multiple regular attributes before conditional" +source: "Parser::AttributesTest#test_0095_multiple regular attributes before conditional" input: "
data-active<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt b/test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt rename to test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt index c1954d51e..08cf0dbbf 100644 --- a/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt +++ b/test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0095_multiple regular attributes after conditional" +source: "Parser::AttributesTest#test_0096_multiple regular attributes after conditional" input: "
data-active<% end %> id=\"main\" class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt rename to test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt index 274b6db39..a2a0b66bb 100644 --- a/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt +++ b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0096_conditional attribute between regular attributes" +source: "Parser::AttributesTest#test_0097_conditional attribute between regular attributes" input: "
data-active<% end %> class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt b/test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt rename to test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt index add1153aa..1447d5a12 100644 --- a/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt +++ b/test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0097_conditional attribute with value between regular attributes" +source: "Parser::AttributesTest#test_0098_conditional attribute with value between regular attributes" input: "
data-active=\"true\"<% end %> class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:83)) diff --git a/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt b/test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt rename to test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt index 126bb08b9..4ee97b91f 100644 --- a/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt +++ b/test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0098_nested conditionals in attributes" +source: "Parser::AttributesTest#test_0099_nested conditionals in attributes" input: "
<% if inner? %>data-inner<% else %>data-outer<% end %><% end %>>
" --- @ DocumentNode (location: (1:0)-(1:90)) diff --git a/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt b/test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt rename to test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt index 512ffe1d1..82952089e 100644 --- a/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt +++ b/test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0099_conditional with multiple attributes inside" +source: "Parser::AttributesTest#test_0100_conditional with multiple attributes inside" input: "
data-admin data-role=\"admin\" data-permissions=\"all\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:87)) diff --git a/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt b/test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt rename to test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt index 5bb0c1378..52e0356fa 100644 --- a/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt +++ b/test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0100_conditional with ERB output in attribute value" +source: "Parser::AttributesTest#test_0101_conditional with ERB output in attribute value" input: "
data-user-id=\"<%= user.id %>\" data-user-name=\"<%= user.name %>\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:98)) diff --git a/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt rename to test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt index 924cab94c..7ef70a14e 100644 --- a/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt +++ b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0101_self-closing tag with conditional attribute" +source: "Parser::AttributesTest#test_0102_self-closing tag with conditional attribute" input: "required<% end %> />" --- @ DocumentNode (location: (1:0)-(1:57)) diff --git a/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt b/test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt rename to test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt index b8bd94786..5bf64143f 100644 --- a/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt +++ b/test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0102_self-closing tag with conditional attribute and value" +source: "Parser::AttributesTest#test_0103_self-closing tag with conditional attribute and value" input: "value=\"<%= default_value %>\"<% end %> />" --- @ DocumentNode (location: (1:0)-(1:78)) diff --git a/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt b/test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt rename to test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt index e6b592354..1f1d7d4ba 100644 --- a/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt +++ b/test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0103_void element with conditional attribute" +source: "Parser::AttributesTest#test_0104_void element with conditional attribute" input: "loading=\"lazy\"<% end %>>" --- @ DocumentNode (location: (1:0)-(1:59)) diff --git a/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt b/test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt rename to test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt index c0981dc49..5431cf24f 100644 --- a/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt +++ b/test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0104_conditional class attribute with ternary in value" +source: "Parser::AttributesTest#test_0105_conditional class attribute with ternary in value" input: "
class=\"<%= active ? 'active' : 'inactive' %>\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:82)) From f69460b43b4ed6f8e8fbe16eed71f28fa49dcad1 Mon Sep 17 00:00:00 2001 From: Marco Roth Date: Wed, 11 Feb 2026 09:08:25 +0100 Subject: [PATCH 5/5] Remove duplicate test --- test/parser/attributes_test.rb | 6 +----- ...surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt} | 2 +- ...before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt} | 2 +- ..._after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt} | 2 +- ...regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt} | 2 +- ...regular_attributes_042e33e3b667bd90f51576fb32384468.txt} | 2 +- ...nals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt} | 2 +- ..._attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt} | 2 +- ...in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt} | 2 +- ...ditional_attribute_44720e6b8d80626b1067450c32388bcc.txt} | 2 +- ...ttribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt} | 2 +- ...ditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt} | 2 +- ...h_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt} | 2 +- 13 files changed, 13 insertions(+), 17 deletions(-) rename test/snapshots/parser/attributes_test/{test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt => test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt} (97%) rename test/snapshots/parser/attributes_test/{test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt => test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt => test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt => test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt => test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt => test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt => test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt => test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt => test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt => test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt => test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt} (98%) rename test/snapshots/parser/attributes_test/{test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt => test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt} (98%) diff --git a/test/parser/attributes_test.rb b/test/parser/attributes_test.rb index 158a8b56f..264947717 100644 --- a/test/parser/attributes_test.rb +++ b/test/parser/attributes_test.rb @@ -196,6 +196,7 @@ class AttributesTest < Minitest::Spec assert_parsed_snapshot(%(
div-content
)) end + # https://github.com/marcoroth/herb/issues/856#issuecomment-3525179643 test "Conditional attribute with ERB control flow and no surrounding spaces" do assert_parsed_snapshot(%(data-turbo-permanent<% end %>>)) end @@ -401,11 +402,6 @@ class AttributesTest < Minitest::Spec assert_parsed_snapshot(%(
open<% end %><% if b? %>style='color: red;'<% end %>>
)) end - # https://github.com/marcoroth/herb/issues/856#issuecomment-3525179643 - test "issue #856: data-turbo-permanent in if right before html tag end" do - assert_parsed_snapshot(%(data-turbo-permanent<% end %>>)) - end - test "multiple regular attributes before conditional" do assert_parsed_snapshot(%(
data-active<% end %>>
)) end diff --git a/test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt similarity index 97% rename from test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt rename to test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt index 2b113d829..30996c2bd 100644 --- a/test/snapshots/parser/attributes_test/test_0094_issue_#856_data-turbo-permanent_in_if_right_before_html_tag_end_8b8da9205eb731ac258036f24249144e.txt +++ b/test/snapshots/parser/attributes_test/test_0047_Conditional_attribute_with_ERB_control_flow_and_no_surrounding_spaces_8b8da9205eb731ac258036f24249144e.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0094_issue #856: data-turbo-permanent in if right before html tag end" +source: "Parser::AttributesTest#test_0047_Conditional attribute with ERB control flow and no surrounding spaces" input: "data-turbo-permanent<% end %>>" --- @ DocumentNode (location: (1:0)-(1:106)) diff --git a/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt b/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt rename to test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt index 01f863045..6ccd8c3b2 100644 --- a/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt +++ b/test/snapshots/parser/attributes_test/test_0094_multiple_regular_attributes_before_conditional_8c06ba292aee34d2246c5434e2aa3c68.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0095_multiple regular attributes before conditional" +source: "Parser::AttributesTest#test_0094_multiple regular attributes before conditional" input: "
data-active<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt rename to test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt index 08cf0dbbf..c1954d51e 100644 --- a/test/snapshots/parser/attributes_test/test_0096_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt +++ b/test/snapshots/parser/attributes_test/test_0095_multiple_regular_attributes_after_conditional_ebd40115264193db975ccf7dc4ae35e5.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0096_multiple regular attributes after conditional" +source: "Parser::AttributesTest#test_0095_multiple regular attributes after conditional" input: "
data-active<% end %> id=\"main\" class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt b/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt rename to test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt index a2a0b66bb..274b6db39 100644 --- a/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt +++ b/test/snapshots/parser/attributes_test/test_0096_conditional_attribute_between_regular_attributes_cdc09bc0e09eda8292c2c93ae9ecbd90.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0097_conditional attribute between regular attributes" +source: "Parser::AttributesTest#test_0096_conditional attribute between regular attributes" input: "
data-active<% end %> class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:76)) diff --git a/test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt rename to test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt index 1447d5a12..add1153aa 100644 --- a/test/snapshots/parser/attributes_test/test_0098_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt +++ b/test/snapshots/parser/attributes_test/test_0097_conditional_attribute_with_value_between_regular_attributes_042e33e3b667bd90f51576fb32384468.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0098_conditional attribute with value between regular attributes" +source: "Parser::AttributesTest#test_0097_conditional attribute with value between regular attributes" input: "
data-active=\"true\"<% end %> class=\"container\">
" --- @ DocumentNode (location: (1:0)-(1:83)) diff --git a/test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt b/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt rename to test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt index 4ee97b91f..126bb08b9 100644 --- a/test/snapshots/parser/attributes_test/test_0099_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt +++ b/test/snapshots/parser/attributes_test/test_0098_nested_conditionals_in_attributes_a39365c5182e15b19f92c1aa831b3d88.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0099_nested conditionals in attributes" +source: "Parser::AttributesTest#test_0098_nested conditionals in attributes" input: "
<% if inner? %>data-inner<% else %>data-outer<% end %><% end %>>
" --- @ DocumentNode (location: (1:0)-(1:90)) diff --git a/test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt b/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt rename to test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt index 82952089e..512ffe1d1 100644 --- a/test/snapshots/parser/attributes_test/test_0100_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt +++ b/test/snapshots/parser/attributes_test/test_0099_conditional_with_multiple_attributes_inside_198af2705cb596f4dc827a4bd2ff89bc.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0100_conditional with multiple attributes inside" +source: "Parser::AttributesTest#test_0099_conditional with multiple attributes inside" input: "
data-admin data-role=\"admin\" data-permissions=\"all\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:87)) diff --git a/test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt b/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt rename to test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt index 52e0356fa..5bb0c1378 100644 --- a/test/snapshots/parser/attributes_test/test_0101_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt +++ b/test/snapshots/parser/attributes_test/test_0100_conditional_with_ERB_output_in_attribute_value_b8559766f404b30543c5bc966e0794a6.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0101_conditional with ERB output in attribute value" +source: "Parser::AttributesTest#test_0100_conditional with ERB output in attribute value" input: "
data-user-id=\"<%= user.id %>\" data-user-name=\"<%= user.name %>\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:98)) diff --git a/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt b/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt rename to test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt index 7ef70a14e..924cab94c 100644 --- a/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt +++ b/test/snapshots/parser/attributes_test/test_0101_self-closing_tag_with_conditional_attribute_44720e6b8d80626b1067450c32388bcc.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0102_self-closing tag with conditional attribute" +source: "Parser::AttributesTest#test_0101_self-closing tag with conditional attribute" input: "required<% end %> />" --- @ DocumentNode (location: (1:0)-(1:57)) diff --git a/test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt rename to test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt index 5bf64143f..b8bd94786 100644 --- a/test/snapshots/parser/attributes_test/test_0103_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt +++ b/test/snapshots/parser/attributes_test/test_0102_self-closing_tag_with_conditional_attribute_and_value_7e81668eb38a3cbea4d7a95186b4e4d7.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0103_self-closing tag with conditional attribute and value" +source: "Parser::AttributesTest#test_0102_self-closing tag with conditional attribute and value" input: "value=\"<%= default_value %>\"<% end %> />" --- @ DocumentNode (location: (1:0)-(1:78)) diff --git a/test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt b/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt rename to test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt index 1f1d7d4ba..e6b592354 100644 --- a/test/snapshots/parser/attributes_test/test_0104_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt +++ b/test/snapshots/parser/attributes_test/test_0103_void_element_with_conditional_attribute_83f720a8cff8f1b31db7e3747ff6209f.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0104_void element with conditional attribute" +source: "Parser::AttributesTest#test_0103_void element with conditional attribute" input: "loading=\"lazy\"<% end %>>" --- @ DocumentNode (location: (1:0)-(1:59)) diff --git a/test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt b/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt similarity index 98% rename from test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt rename to test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt index 5431cf24f..c0981dc49 100644 --- a/test/snapshots/parser/attributes_test/test_0105_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt +++ b/test/snapshots/parser/attributes_test/test_0104_conditional_class_attribute_with_ternary_in_value_9680e555f9af80f1e23caf65f801478f.txt @@ -1,5 +1,5 @@ --- -source: "Parser::AttributesTest#test_0105_conditional class attribute with ternary in value" +source: "Parser::AttributesTest#test_0104_conditional class attribute with ternary in value" input: "
class=\"<%= active ? 'active' : 'inactive' %>\"<% end %>>
" --- @ DocumentNode (location: (1:0)-(1:82))