Skip to content

Remove .test_controller in favor of vc_test_controller_class #2322

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

Merged
merged 2 commits into from
Jun 3, 2025
Merged
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: 6

## main

* BREAKING: Remove `config.test_controller` in favor of `vc_test_controller_class` test helper method.

*Joel Hawksley*

* BREAKING: `config.component_parent_class` is now `config.generate.component_parent_class`, moving the generator-specific option to the generator configuration namespace.

*Joel Hawksley*
Expand Down
10 changes: 10 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,16 @@ test "logged out user sees login link" do
end
```

### `#vc_test_controller_class`

Set the controller used by `render_inline`:

```ruby
def vc_test_controller_class
MyTestController
end
```

### `#vc_test_request` → [ActionDispatch::TestRequest]

Access the request used by `render_inline`:
Expand Down
14 changes: 12 additions & 2 deletions docs/guide/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,20 @@ end
Since 2.27.0
{: .label }

Component tests assume the existence of an `ApplicationController` class, which can be configured globally using the `test_controller` option:
Component tests assume the existence of an `ApplicationController` class. To set the controller for a test file, define `vc_test_controller_class`:

```ruby
config.view_component.test_controller = "BaseController"
class ExampleComponentTest < ViewComponent::TestCase
def vc_test_controller_class
PublicController
end

def test_component_in_public_controller
render_inline ExampleComponent.new

assert_text "foo"
end
end
```

To configure the controller used for a test case, use `with_controller_class` from `ViewComponent::TestHelpers`.
Expand Down
10 changes: 0 additions & 10 deletions lib/view_component/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -400,16 +400,6 @@ def safe_output_postamble
end
end

# Set the controller used for testing components:
#
# ```ruby
# config.view_component.test_controller = "MyTestController"
# ```
#
# Defaults to `nil`. If this is falsy, `"ApplicationController"` is used. Can also be
# configured on a per-test basis using `with_controller_class`.
#

# Configuration for generators.
#
# All options under this namespace default to `false` unless otherwise
Expand Down
3 changes: 1 addition & 2 deletions lib/view_component/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ def defaults
ActiveSupport::OrderedOptions.new.merge!({
generate: default_generate_options,
previews: default_previews_options,
instrumentation_enabled: false,
test_controller: "ApplicationController"
instrumentation_enabled: false
})
end

Expand Down
15 changes: 14 additions & 1 deletion lib/view_component/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,20 @@ def with_request_url(full_path, host: nil, method: nil)
#
# @return [ActionController::Base]
def vc_test_controller
@vc_test_controller ||= __vc_test_helpers_build_controller(Base.test_controller.constantize)
@vc_test_controller ||= __vc_test_helpers_build_controller(vc_test_controller_class)
end

# Set the controller used by `render_inline`:
#
# ```ruby
# def vc_test_controller_class
# MyTestController
# end
# ```
def vc_test_controller_class
return @__vc_test_controller_class if defined?(@__vc_test_controller_class)

defined?(ApplicationController) ? ApplicationController : ActionController::Base
end

# Access the request used by `render_inline`:
Expand Down
1 change: 0 additions & 1 deletion test/sandbox/config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

config.view_component.show_previews = true
config.view_component.instrumentation_enabled = true
config.view_component.test_controller = "IntegrationExamplesController"

# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
Expand Down
15 changes: 7 additions & 8 deletions test/sandbox/test/base_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ module TestModuleWithConfig
include ViewComponent::Configurable

configure do |config|
config.view_component.test_controller = "AnotherController"
config.view_component.instrumentation_enabled = false
end

class SomeComponent < ViewComponent::Base
Expand All @@ -169,7 +169,7 @@ module TestAlreadyConfigurableModule
include ViewComponent::Configurable

configure do |config|
config.view_component.test_controller = "AnotherController"
config.view_component.instrumentation_enabled = false
end

class SomeComponent < ViewComponent::Base
Expand All @@ -180,7 +180,7 @@ module TestAlreadyConfiguredModule
include ActiveSupport::Configurable

configure do |config|
config.view_component = ActiveSupport::InheritableOptions[test_controller: "AnotherController"]
config.view_component = ActiveSupport::InheritableOptions[instrumentation_enabled: false]
end

include ViewComponent::Configurable
Expand All @@ -190,10 +190,9 @@ class SomeComponent < ViewComponent::Base
end

def test_uses_module_configuration
# We override this ourselves in test/sandbox/config/environments/test.rb.
assert_equal "IntegrationExamplesController", TestModuleWithoutConfig::SomeComponent.test_controller
assert_equal "AnotherController", TestModuleWithConfig::SomeComponent.test_controller
assert_equal "AnotherController", TestAlreadyConfigurableModule::SomeComponent.test_controller
assert_equal "AnotherController", TestAlreadyConfiguredModule::SomeComponent.test_controller
assert_equal true, TestModuleWithoutConfig::SomeComponent.instrumentation_enabled
assert_equal false, TestModuleWithConfig::SomeComponent.instrumentation_enabled
assert_equal false, TestAlreadyConfigurableModule::SomeComponent.instrumentation_enabled
assert_equal false, TestAlreadyConfiguredModule::SomeComponent.instrumentation_enabled
end
end
6 changes: 5 additions & 1 deletion test/sandbox/test/rendering_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ def __allocate_instance_variables
@vc_test_request = nil
end

def vc_test_controller_class
IntegrationExamplesController
end

def test_render_inline
render_inline(MyComponent.new)

Expand All @@ -30,7 +34,7 @@ def test_render_inline_allocations
MyComponent.__vc_ensure_compiled

with_instrumentation_enabled_option(false) do
assert_allocations({"3.5" => 75, "3.4" => 80, "3.3" => 82, "3.2" => 81}) do
assert_allocations({"3.5" => 70, "3.4" => 75, "3.3" => 76, "3.2" => 75}) do
render_inline(MyComponent.new)
end
end
Expand Down
Loading