Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add failing spec for mocked component without template #2191

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ nav_order: 5

## main

* Improve error messaging for malformed components.

*Martin Meyerhoff*, *Joel Hawksley*

* Do not prefix release tags with `v`, per recommendation from @bkuhlmann.

*Joel Hawksley*
Expand Down
12 changes: 8 additions & 4 deletions lib/view_component/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,15 @@ def define_render_template_for
end

@component.silence_redefinition_of_method(:render_template_for)
@component.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def render_template_for(variant = nil, format = nil)
#{method_body}
begin
@component.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def render_template_for(variant = nil, format = nil)
#{method_body}
end
RUBY
rescue SyntaxError
raise ViewComponent::CompilerMethodBodySyntaxError.new(@component.name, method_body)
end
RUBY
end

def template_errors
Expand Down
8 changes: 8 additions & 0 deletions lib/view_component/errors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,12 @@ def initialize(setter_method_name, setter_name)
super(MESSAGE.gsub("SETTER_METHOD_NAME", setter_method_name.to_s).gsub("SETTER_NAME", setter_name.to_s))
end
end

class CompilerMethodBodySyntaxError < StandardError
MESSAGE = "Could not compile COMPONENT_NAME due to SyntaxError in method body: METHOD_BODY"

def initialize(component_name, method_body)
super(MESSAGE.gsub("COMPONENT_NAME", component_name.to_s).gsub("METHOD_BODY", method_body.to_s))
end
end
end
17 changes: 16 additions & 1 deletion test/sandbox/test/rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_render_inline_allocations

allocations = (Rails.version.to_f >= 8.0) ?
{"3.5.0" => 117, "3.4.1" => 117, "3.3.6" => 129} :
{"3.3.6" => 120, "3.3.0" => 120, "3.2.6" => 118, "3.1.6" => 118, "3.0.7" => 127}
{"3.3.6" => 120, "3.3.0" => 132, "3.2.6" => 118, "3.1.6" => 118, "3.0.7" => 127}

assert_allocations(**allocations) do
render_inline(MyComponent.new)
Expand Down Expand Up @@ -1236,4 +1236,19 @@ def test_request_param

assert_text("foo")
end

# In https://github.com/ViewComponent/view_component/issues/2187,
# the Solidus test suite built mocked components by hand, resulting
# in a difficult-to-debug error. While this test case is quite narrow,
# it isolates the unintentional error masking we were doing.
def test_render_anonymous_component_without_template
location = caller(1, 1).first
mock_component = Class.new(MyComponent)
mock_component.define_singleton_method(:name) { "Foo" }
mock_component.define_singleton_method(:to_s) { "#{name} (#{location})" }

assert_raises(ViewComponent::CompilerMethodBodySyntaxError) do
render_inline(mock_component.new)
end
end
end
Loading