From 6d9eb9aac994932643aed69b333551d52a7d5ef6 Mon Sep 17 00:00:00 2001 From: Francesco Aiello Date: Fri, 31 Mar 2023 10:24:28 -0700 Subject: [PATCH 1/5] Handle case-when co-authored-by: Elia Schito --- lib/erb/formatter.rb | 2 +- test/fixtures/case_when.html.erb | 10 +++++++ test/fixtures/case_when.html.expected.erb | 10 +++++++ test/fixtures/complex_case_when.html.erb | 22 ++++++++++++++++ .../complex_case_when.html.expected.erb | 26 +++++++++++++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 test/fixtures/case_when.html.erb create mode 100644 test/fixtures/case_when.html.expected.erb create mode 100644 test/fixtures/complex_case_when.html.erb create mode 100644 test/fixtures/complex_case_when.html.expected.erb diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index b0471b4..7af0160 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -307,7 +307,7 @@ def format_erb_tags(string) full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}" tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - when /\A(else|elsif\b(.*))\z/ + when /\A(else|elsif\b(.*)|when\b(.*))\z/ full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}" tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) diff --git a/test/fixtures/case_when.html.erb b/test/fixtures/case_when.html.erb new file mode 100644 index 0000000..cf44883 --- /dev/null +++ b/test/fixtures/case_when.html.erb @@ -0,0 +1,10 @@ +<% case 'fake' %> + <% when 'fake' %> + there + <% when 'something' %> + there +<% when 'else' %> + hi + <% else %> + there + <% end %> diff --git a/test/fixtures/case_when.html.expected.erb b/test/fixtures/case_when.html.expected.erb new file mode 100644 index 0000000..25b018e --- /dev/null +++ b/test/fixtures/case_when.html.expected.erb @@ -0,0 +1,10 @@ +<% case 'fake' %> +<% when 'fake' %> + there +<% when 'something' %> + there +<% when 'else' %> + hi +<% else %> + there +<% end %> diff --git a/test/fixtures/complex_case_when.html.erb b/test/fixtures/complex_case_when.html.erb new file mode 100644 index 0000000..3d57f54 --- /dev/null +++ b/test/fixtures/complex_case_when.html.erb @@ -0,0 +1,22 @@ +
+ <% if payment_method.present? %> +<% case payment_method.class.to_s %> + <% when 'Foo::PaymentMethod::FooCreditCard' %> + <% if payment_method.active %> + + *<%= payment_source.last_digits %> + <%= payment_source.month %>/<%= payment_source.year %> + <% else %> + <%= t('.payment.card_removed_or_expired') %> + <% end %> + <% when 'Foo::PaymentMethod::Bar' %> + <%= t('.payment.invoice') %> + <% when 'Foo::PaymentMethod' %> + <%= t('.payment.stripe_invoice') %> + <% else %> + <% Rails.logger.error.report(StandardError.new("No human readable name found for payment method #{payment_method.class}")) %> + <% end %> + <% else %> + <%= t('.payment.no_payment_method_found') %> +<% end %> +
diff --git a/test/fixtures/complex_case_when.html.expected.erb b/test/fixtures/complex_case_when.html.expected.erb new file mode 100644 index 0000000..efb2be4 --- /dev/null +++ b/test/fixtures/complex_case_when.html.expected.erb @@ -0,0 +1,26 @@ +
+ <% if payment_method.present? %> + <% case payment_method.class.to_s %> + <% when 'Foo::PaymentMethod::FooCreditCard' %> + <% if payment_method.active %> + + *<%= payment_source.last_digits %> + <%= payment_source.month %>/<%= payment_source.year %> + <% else %> + <%= t(".payment.card_removed_or_expired") %> + <% end %> + <% when 'Foo::PaymentMethod::Bar' %> + <%= t(".payment.invoice") %> + <% when 'Foo::PaymentMethod' %> + <%= t(".payment.stripe_invoice") %> + <% else %> + <% Rails.logger.error.report( + StandardError.new( + "No human readable name found for payment method #{payment_method.class}" + ) + ) %> + <% end %> + <% else %> + <%= t(".payment.no_payment_method_found") %> + <% end %> +
From 0345476e30ffbf20b30df11417928c53c975a3b8 Mon Sep 17 00:00:00 2001 From: Francesco Aiello Date: Fri, 31 Mar 2023 09:58:18 -0700 Subject: [PATCH 2/5] Rename ERB_OPEN_BLOCK to RUBY_OPEN_BLOCK co-authored-by: Elia Schito --- lib/erb/formatter.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index 7af0160..8372da8 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -49,7 +49,7 @@ class Error < StandardError; end SELF_CLOSING_TAG = /\A(area|base|br|col|command|embed|hr|img|input|keygen|link|menuitem|meta|param|source|track|wbr)\z/i - ERB_OPEN_BLOCK = ->(code) do + RUBY_OPEN_BLOCK = ->(code) do # is nil when the parsing is broken, meaning it's an open expression Ripper.sexp(code).nil? end.freeze @@ -170,7 +170,7 @@ def format_erb_attributes(string) tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) tag_stack_push('%erb%', ruby_code) - when ERB_OPEN_BLOCK + when RUBY_OPEN_BLOCK html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) tag_stack_push('%erb%', ruby_code) else @@ -258,8 +258,8 @@ def format_text(text) def format_ruby(code, autoclose: false) if autoclose - code += "\nend" unless ERB_OPEN_BLOCK["#{code}\nend"] - code += "\n}" unless ERB_OPEN_BLOCK["#{code}\n}"] + code += "\nend" unless RUBY_OPEN_BLOCK["#{code}\nend"] + code += "\n}" unless RUBY_OPEN_BLOCK["#{code}\n}"] end p RUBY_IN_: code if @debug @@ -312,7 +312,7 @@ def format_erb_tags(string) tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) tag_stack_push('%erb%', ruby_code) - when ERB_OPEN_BLOCK + when RUBY_OPEN_BLOCK full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}" html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) tag_stack_push('%erb%', ruby_code) From ab85c7779f096183aae538d9666886db6a86032a Mon Sep 17 00:00:00 2001 From: Francesco Aiello Date: Fri, 31 Mar 2023 10:19:01 -0700 Subject: [PATCH 3/5] Move ruby open and close block regex into constant Co-authored-by: Elia Schito --- lib/erb/formatter.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index 8372da8..ad16726 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -53,6 +53,8 @@ class Error < StandardError; end # is nil when the parsing is broken, meaning it's an open expression Ripper.sexp(code).nil? end.freeze + RUBY_CLOSE_BLOCK = /\Aend\z/ + RUBY_REOPEN_BLOCK = /\A(else|elsif\b(.*)|when\b(.*))\z/ RUBOCOP_STDIN_MARKER = "====================" @@ -303,11 +305,11 @@ def format_erb_tags(string) erb_open << ' ' unless ruby_code.start_with?('#') case ruby_code - when /\Aend\z/ + when RUBY_CLOSE_BLOCK full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}" tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - when /\A(else|elsif\b(.*)|when\b(.*))\z/ + when RUBY_REOPEN_BLOCK full_erb_tag = "#{erb_open}#{ruby_code} #{erb_close}" tag_stack_pop('%erb%', ruby_code) html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) From e842ad0236f2451a89ef071417846902af0f32b5 Mon Sep 17 00:00:00 2001 From: Francesco Aiello Date: Fri, 31 Mar 2023 10:19:12 -0700 Subject: [PATCH 4/5] Remove unused ERB start/end constants Co-authored-by: Elia Schito --- lib/erb/formatter.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index ad16726..2f57a87 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -38,8 +38,6 @@ class Error < StandardError; end ERB_TAG = %r{(<%(?:==|=|-|))\s*(.*?)\s*(-?%>)}m ERB_PLACEHOLDER = %r{erb[a-z0-9]+tag} - ERB_END = %r{(<%-?)\s*(end)\s*(-?%>)} - ERB_ELSE = %r{(<%-?)\s*(else|elsif\b.*)\s*(-?%>)} TAG_NAME = /[a-z0-9_:-]+/ TAG_NAME_ONLY = /\A#{TAG_NAME}\z/ From ffa3e17f8b918f8614964e52a54a4c2a2c65a714 Mon Sep 17 00:00:00 2001 From: Francesco Aiello Date: Fri, 31 Mar 2023 10:19:27 -0700 Subject: [PATCH 5/5] Remove unused format_erb_attributes method Co-authored-by: Elia Schito --- lib/erb/formatter.rb | 39 --------------------------------------- 1 file changed, 39 deletions(-) diff --git a/lib/erb/formatter.rb b/lib/erb/formatter.rb index 2f57a87..b4d49c4 100644 --- a/lib/erb/formatter.rb +++ b/lib/erb/formatter.rb @@ -146,45 +146,6 @@ def format_attributes(tag_name, attrs, tag_closing) attr_html end - def format_erb_attributes(string) - erb_scanner = StringScanner.new(string.to_s) - erb_pre_pos = 0 - until erb_scanner.eos? - if erb_scanner.scan_until(erb_tags_regexp) - erb_pre_match = erb_scanner.pre_match - erb_pre_match = erb_pre_match[erb_pre_pos..] - erb_pre_pos = erb_scanner.pos - - erb_code = erb_tags[erb_scanner.captures.first] - - format_attributes(erb_pre_match) - - erb_open, ruby_code, erb_close = ERB_TAG.match(erb_code).captures - full_erb_tag = "#{erb_open} #{ruby_code} #{erb_close}" - - case ruby_code - when /\Aend\z/ - tag_stack_pop('%erb%', ruby_code) - html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - when /\A(else|elsif\b(.*))\z/ - tag_stack_pop('%erb%', ruby_code) - html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - tag_stack_push('%erb%', ruby_code) - when RUBY_OPEN_BLOCK - html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - tag_stack_push('%erb%', ruby_code) - else - ruby_code = format_ruby(ruby_code, autoclose: false) - html << (erb_pre_match.match?(/\s+\z/) ? indented(full_erb_tag) : full_erb_tag) - end - else - rest = erb_scanner.rest.to_s - format_erb_attributes(rest) - erb_scanner.terminate - end - end - end - def tag_stack_push(tag_name, code) tag_stack << [tag_name, code] p PUSH: tag_stack if @debug