mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
65e42c91f5
Previously the same class, ActionView::TestCase::TestController, was used to build a controller for every ActionView::TestCase class. This caused issues when helpers/helper methods were set directly on the controller (which from one test we seem to want to support). This commit solves this by creating a new controller class for every test case, which gives the controller a unique set of helpers to work with. Co-authored-by: John Crepezzi <seejohnrun@github.com>
355 lines
9.9 KiB
Ruby
355 lines
9.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "abstract_unit"
|
|
require "rails/engine"
|
|
|
|
module ActionView
|
|
module ATestHelper
|
|
end
|
|
|
|
module AnotherTestHelper
|
|
def from_another_helper
|
|
"Howdy!"
|
|
end
|
|
end
|
|
|
|
module ASharedTestHelper
|
|
def from_shared_helper
|
|
"Holla!"
|
|
end
|
|
end
|
|
|
|
class TestCase
|
|
helper ASharedTestHelper
|
|
DeveloperStruct = Struct.new(:name)
|
|
|
|
module SharedTests
|
|
def setup
|
|
ActionView::LookupContext::DetailsKey.clear
|
|
super
|
|
end
|
|
|
|
def self.included(test_case)
|
|
test_case.class_eval do
|
|
test "helpers defined on ActionView::TestCase are available" do
|
|
assert_includes test_case.ancestors, ASharedTestHelper
|
|
assert_equal "Holla!", from_shared_helper
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
class GeneralViewTest < ActionView::TestCase
|
|
include SharedTests
|
|
test_case = self
|
|
|
|
test "memoizes the view" do
|
|
assert_same view, view
|
|
end
|
|
|
|
test "exposes params" do
|
|
assert params.is_a? ActionController::Parameters
|
|
end
|
|
|
|
test "exposes view as _view for backwards compatibility" do
|
|
assert_same _view, view
|
|
end
|
|
|
|
test "retrieve non existing config values" do
|
|
assert_nil ActionView::Base.empty.config.something_odd
|
|
end
|
|
|
|
test "works without testing a helper module" do
|
|
assert_equal "Eloy", render("developers/developer", developer: DeveloperStruct.new("Eloy"))
|
|
end
|
|
|
|
test "can render a layout with block" do
|
|
assert_equal "Before (ChrisCruft)\n!\nAfter",
|
|
render(layout: "test/layout_for_partial", locals: { name: "ChrisCruft" }) { "!" }
|
|
end
|
|
|
|
helper AnotherTestHelper
|
|
test "additional helper classes can be specified as in a controller" do
|
|
assert_includes test_case.ancestors, AnotherTestHelper
|
|
assert_equal "Howdy!", from_another_helper
|
|
end
|
|
|
|
test "determine_default_helper_class returns nil if the test name constant resolves to a class" do
|
|
assert_nil self.class.determine_default_helper_class("String")
|
|
end
|
|
|
|
test "delegates notice to request.flash[:notice]" do
|
|
assert_called_with(view.request.flash, :[], [:notice]) do
|
|
view.notice
|
|
end
|
|
end
|
|
|
|
test "delegates alert to request.flash[:alert]" do
|
|
assert_called_with(view.request.flash, :[], [:alert]) do
|
|
view.alert
|
|
end
|
|
end
|
|
|
|
test "uses controller lookup context" do
|
|
assert_equal lookup_context, @controller.lookup_context
|
|
end
|
|
end
|
|
|
|
class ClassMethodsTest < ActionView::TestCase
|
|
include SharedTests
|
|
test_case = self
|
|
|
|
tests ATestHelper
|
|
test "tests the specified helper module" do
|
|
assert_equal ATestHelper, test_case.helper_class
|
|
assert_includes test_case.ancestors, ATestHelper
|
|
end
|
|
|
|
helper AnotherTestHelper
|
|
test "additional helper classes can be specified as in a controller" do
|
|
assert_includes test_case.ancestors, AnotherTestHelper
|
|
assert_equal "Howdy!", from_another_helper
|
|
|
|
test_case.helper_class.module_eval do
|
|
def render_from_helper
|
|
from_another_helper
|
|
end
|
|
end
|
|
assert_equal "Howdy!", render(partial: "test/from_helper")
|
|
end
|
|
end
|
|
|
|
class HelperInclusionTest < ActionView::TestCase
|
|
module RenderHelper
|
|
def render_from_helper
|
|
render partial: "customer", collection: @customers
|
|
end
|
|
end
|
|
|
|
helper RenderHelper
|
|
|
|
test "helper class that is being tested is always included in view instance" do
|
|
@controller.controller_path = "test"
|
|
|
|
@customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")]
|
|
assert_match(/Hello: EloyHello: Manfred/, render(partial: "test/from_helper"))
|
|
end
|
|
end
|
|
|
|
class ControllerHelperMethod < ActionView::TestCase
|
|
module SomeHelper
|
|
def some_method
|
|
render partial: "test/from_helper"
|
|
end
|
|
end
|
|
|
|
helper SomeHelper
|
|
|
|
test "can call a helper method defined on the current controller from a helper" do
|
|
@controller.singleton_class.class_eval <<-EOF, __FILE__, __LINE__ + 1
|
|
def render_from_helper
|
|
'controller_helper_method'
|
|
end
|
|
EOF
|
|
@controller.class.helper_method :render_from_helper
|
|
|
|
assert_equal "controller_helper_method", some_method
|
|
end
|
|
|
|
class AnotherTestClass < ActionView::TestCase
|
|
test "doesn't use controller helpers from other tests" do
|
|
assert_not_respond_to view, :render_from_helper
|
|
assert_not_includes @controller._helpers.instance_methods, :render_from_helper
|
|
end
|
|
end
|
|
end
|
|
|
|
class ViewAssignsTest < ActionView::TestCase
|
|
test "view_assigns returns a Hash of user defined ivars" do
|
|
@a = "b"
|
|
@c = "d"
|
|
assert_equal({ a: "b", c: "d" }, view_assigns)
|
|
end
|
|
|
|
test "view_assigns excludes internal ivars" do
|
|
INTERNAL_IVARS.each do |ivar|
|
|
assert defined?(ivar), "expected #{ivar} to be defined"
|
|
assert_not_includes view_assigns.keys, ivar.to_s.tr("@", "").to_sym, "expected #{ivar} to be excluded from view_assigns"
|
|
end
|
|
end
|
|
end
|
|
|
|
class HelperExposureTest < ActionView::TestCase
|
|
helper(Module.new do
|
|
def render_from_helper
|
|
from_test_case(suffix: "!")
|
|
end
|
|
end)
|
|
test "is able to make methods available to the view" do
|
|
assert_equal "Word!", render(partial: "test/from_helper")
|
|
end
|
|
|
|
def from_test_case(suffix: "?"); "Word#{suffix}"; end
|
|
helper_method :from_test_case
|
|
end
|
|
|
|
class IgnoreProtectAgainstForgeryTest < ActionView::TestCase
|
|
module HelperThatInvokesProtectAgainstForgery
|
|
def help_me
|
|
protect_against_forgery?
|
|
end
|
|
end
|
|
|
|
helper HelperThatInvokesProtectAgainstForgery
|
|
|
|
test "protect_from_forgery? in any helpers returns false" do
|
|
assert_not view.help_me
|
|
end
|
|
end
|
|
|
|
class ATestHelperTest < ActionView::TestCase
|
|
include SharedTests
|
|
test_case = self
|
|
|
|
test "inflects the name of the helper module to test from the test case class" do
|
|
assert_equal ATestHelper, test_case.helper_class
|
|
assert_includes test_case.ancestors, ATestHelper
|
|
end
|
|
|
|
test "a configured test controller is available" do
|
|
assert_kind_of ActionController::Base, controller
|
|
assert_equal "", controller.controller_path
|
|
end
|
|
|
|
test "no additional helpers should shared across test cases" do
|
|
assert_not_includes test_case.ancestors, AnotherTestHelper
|
|
assert_raise(NoMethodError) { send :from_another_helper }
|
|
end
|
|
|
|
test "is able to use routes" do
|
|
controller.request.assign_parameters(@routes, "foo", "index", {}, "/foo", [])
|
|
with_routing do |set|
|
|
set.draw {
|
|
get :foo, to: "foo#index"
|
|
get :bar, to: "bar#index"
|
|
}
|
|
assert_equal "/foo", url_for
|
|
assert_equal "/bar", url_for(controller: "bar")
|
|
end
|
|
end
|
|
|
|
test "is able to use named routes" do
|
|
with_routing do |set|
|
|
set.draw { resources :contents }
|
|
assert_equal "http://test.host/contents/new", new_content_url
|
|
assert_equal "http://test.host/contents/1", content_url(id: 1)
|
|
end
|
|
end
|
|
|
|
test "is able to use mounted routes" do
|
|
with_routing do |set|
|
|
app = Class.new(Rails::Engine) do
|
|
def self.routes
|
|
@routes ||= ActionDispatch::Routing::RouteSet.new
|
|
end
|
|
|
|
routes.draw { get "bar", to: lambda { } }
|
|
|
|
def self.call(*)
|
|
end
|
|
end
|
|
|
|
set.draw { mount app => "/foo", :as => "foo_app" }
|
|
|
|
singleton_class.include set.mounted_helpers
|
|
|
|
assert_equal "/foo/bar", foo_app.bar_path
|
|
end
|
|
end
|
|
|
|
test "named routes can be used from helper included in view" do
|
|
with_routing do |set|
|
|
set.draw { resources :contents }
|
|
_helpers.module_eval do
|
|
def render_from_helper
|
|
new_content_url
|
|
end
|
|
end
|
|
|
|
assert_equal "http://test.host/contents/new", render(partial: "test/from_helper")
|
|
end
|
|
end
|
|
|
|
test "is able to render partials with local variables" do
|
|
assert_equal "Eloy", render("developers/developer", developer: DeveloperStruct.new("Eloy"))
|
|
assert_equal "Eloy", render(partial: "developers/developer",
|
|
locals: { developer: DeveloperStruct.new("Eloy") })
|
|
end
|
|
|
|
test "is able to render partials from templates and also use instance variables" do
|
|
@controller.controller_path = "test"
|
|
|
|
@customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")]
|
|
assert_match(/Hello: EloyHello: Manfred/, render(template: "test/list"))
|
|
end
|
|
|
|
test "is able to render partials from templates and also use instance variables after view has been referenced" do
|
|
@controller.controller_path = "test"
|
|
|
|
view
|
|
|
|
@customers = [DeveloperStruct.new("Eloy"), DeveloperStruct.new("Manfred")]
|
|
assert_match(/Hello: EloyHello: Manfred/, render(template: "test/list"))
|
|
end
|
|
|
|
test "is able to use helpers that depend on the view flow" do
|
|
assert_not content_for?(:foo)
|
|
|
|
content_for :foo, "bar"
|
|
assert content_for?(:foo)
|
|
assert_equal "bar", content_for(:foo)
|
|
end
|
|
end
|
|
|
|
class AssertionsTest < ActionView::TestCase
|
|
def render_from_helper
|
|
form_tag("/foo") do
|
|
safe_concat render(plain: "<ul><li>foo</li></ul>")
|
|
end
|
|
end
|
|
helper_method :render_from_helper
|
|
|
|
test "uses the output_buffer for assert_select" do
|
|
render(partial: "test/from_helper")
|
|
|
|
assert_select "form" do
|
|
assert_select "li", text: "foo"
|
|
end
|
|
end
|
|
|
|
test "do not memoize the document_root_element in view tests" do
|
|
concat form_tag("/foo")
|
|
|
|
assert_select "form"
|
|
|
|
concat content_tag(:b, "Strong", class: "foo")
|
|
|
|
assert_select "form"
|
|
assert_select "b.foo"
|
|
end
|
|
end
|
|
|
|
module AHelperWithInitialize
|
|
def initialize(*)
|
|
super
|
|
@called_initialize = true
|
|
end
|
|
end
|
|
|
|
class AHelperWithInitializeTest < ActionView::TestCase
|
|
test "the helper's initialize was actually called" do
|
|
assert @called_initialize
|
|
end
|
|
end
|
|
end
|