diff --git a/CHANGELOG.md b/CHANGELOG.md index 3afb2bff7..5728292f4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # master +* Add support for `config.action_view.annotate_template_file_names` (coming in Rails 6.1). + + *Joel Hawksley* + * Remove initializer requirement from the component. *Vasiliy Ermolovich* diff --git a/lib/view_component/base.rb b/lib/view_component/base.rb index b710b0f2c..ddcbc51d1 100644 --- a/lib/view_component/base.rb +++ b/lib/view_component/base.rb @@ -77,6 +77,10 @@ def render? true end + def self.short_identifier + @short_identifier ||= defined?(Rails.root) ? source_location.sub("#{Rails.root}/", "") : source_location + end + def initialize(*); end def render(options = {}, args = {}, &block) @@ -180,8 +184,20 @@ def compile(raise_template_errors: false) return false end + # If template name annotations are turned on, a line is dynamically + # added with a comment. In this case, we want to return a different + # starting line number so errors that are raised will point to the + # correct line in the component template. + line_number = + if ActionView::Base.respond_to?(:annotate_template_file_names) && + ActionView::Base.annotate_template_file_names + -2 + else + -1 + end + templates.each do |template| - class_eval <<-RUBY, template[:path], -1 + class_eval <<-RUBY, template[:path], line_number def #{call_method_name(template[:variant])} @output_buffer = ActionView::OutputBuffer.new #{compiled_template(template[:path])} @@ -271,7 +287,7 @@ def compiled_template(file_path) if handler.method(:call).parameters.length > 1 handler.call(self, template) - else # remove before upstreaming into Rails + else handler.call(OpenStruct.new(source: template, identifier: identifier, type: type)) end end diff --git a/test/config/application.rb b/test/config/application.rb index 52b0d0a7a..b9658c960 100644 --- a/test/config/application.rb +++ b/test/config/application.rb @@ -7,7 +7,6 @@ require "action_view/railtie" require "view_component/engine" require "sprockets/railtie" -require "better_html" require "haml" require "slim" diff --git a/test/config/environments/test.rb b/test/config/environments/test.rb index e14d982c8..5a7e8d4ea 100644 --- a/test/config/environments/test.rb +++ b/test/config/environments/test.rb @@ -36,5 +36,7 @@ # Print deprecation notices to the stderr config.active_support.deprecation = :stderr + config.action_view.annotate_template_file_names = true if Rails.version.to_f >= 6.1 + config.eager_load = true end diff --git a/test/view_component/better_html_test.rb b/test/view_component/better_html_test.rb index e6a67f3ad..f1e1aabad 100644 --- a/test/view_component/better_html_test.rb +++ b/test/view_component/better_html_test.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "test_helper" +require "better_html" require "better_html/test_helper/safe_erb_tester" # This test exists to ensure basic non-breaking compatiblity with Shopify/better_html diff --git a/test/view_component/integration_test.rb b/test/view_component/integration_test.rb index 6921c93da..2b49da03a 100644 --- a/test/view_component/integration_test.rb +++ b/test/view_component/integration_test.rb @@ -10,6 +10,17 @@ class IntegrationTest < ActionDispatch::IntegrationTest assert_select("div", "Foo\n bar") end + if Rails.version.to_f >= 6.1 + test "rendering component with template annotations enabled" do + get "/" + assert_response :success + + assert_includes response.body, "BEGIN app/components/erb_component.rb" + + assert_select("div", "Foo\n bar") + end + end + test "rendering component in a controller" do get "/controller_inline_baseline" @@ -24,7 +35,7 @@ class IntegrationTest < ActionDispatch::IntegrationTest inline_response = response.body - assert_equal baseline_response, inline_response + assert_includes inline_response, baseline_response end test "rendering component with content" do @@ -48,8 +59,7 @@ class IntegrationTest < ActionDispatch::IntegrationTest get "/partial" assert_response :success - assert_includes response.body, "partial:
hello,partial world!" - assert_includes response.body, "component:
hello,partial world!" + assert_select("div", "hello,partial world!", count: 2) end test "rendering component without variant" do @@ -111,7 +121,7 @@ class IntegrationTest < ActionDispatch::IntegrationTest get "/render_check" assert_response :success - assert_empty response.body.strip + refute_includes response.body, "Rendered" end test "renders component preview" do diff --git a/test/view_component/view_component_test.rb b/test/view_component/view_component_test.rb index de13a005c..0f9d09286 100644 --- a/test/view_component/view_component_test.rb +++ b/test/view_component/view_component_test.rb @@ -89,7 +89,7 @@ def test_renders_erb_template def test_renders_partial_template render_inline(PartialComponent.new) - assert_text("hello,partial world!\n\nhello,partial world!") + assert_text("hello,partial world!", count: 2) end def test_renders_content_for_template @@ -379,7 +379,6 @@ def test_backtrace_returns_correct_file_and_line_number assert_match %r[app/components/exception_in_template_component\.html\.erb:2], error.backtrace[0] end - def test_render_collection products = [OpenStruct.new(name: "Radio clock"), OpenStruct.new(name: "Mints")] render_inline(ProductComponent.with_collection(products, notice: "On sale"))