render_test.rb 27.5 KB
Newer Older
1 2 3
require 'abstract_unit'
require 'controller/fake_models'

Y
Yehuda Katz 已提交
4 5 6
class TestController < ActionController::Base
end

7 8
module RenderTestCases
  def setup_view(paths)
9
    @assigns = { :secret => 'in the sauce' }
10 11
    @view = Class.new(ActionView::Base) do
      def view_cache_dependencies; end
12 13 14 15

      def fragment_cache_key(key)
        ActiveSupport::Cache.expand_cache_key(key, :views)
      end
16 17
    end.new(paths, @assigns)

18
    @controller_view = TestController.new.view_context
J
Joshua Peek 已提交
19 20 21

    # Reload and register danish language for testing
    I18n.backend.store_translations 'da', {}
22
    I18n.backend.store_translations 'pt-BR', {}
J
Joshua Peek 已提交
23 24

    # Ensure original are still the same since we are reindexing view paths
25
    assert_equal ORIGINAL_LOCALES, I18n.available_locales.map(&:to_s).sort
26 27
  end

28
  def test_render_without_options
29
    e = assert_raises(ArgumentError) { @view.render() }
30
    assert_match(/You invoked render but did not give any of (.+) option./, e.message)
31 32
  end

33
  def test_render_file
34
    assert_equal "Hello world!", @view.render(:file => "test/hello_world")
35 36
  end

37 38
  # Test if :formats, :locale etc. options are passed correctly to the resolvers.
  def test_render_file_with_format
39 40 41
    assert_match "<h1>No Comment</h1>", @view.render(:file => "comments/empty", :formats => [:html])
    assert_match "<error>No Comment</error>", @view.render(:file => "comments/empty", :formats => [:xml])
    assert_match "<error>No Comment</error>", @view.render(:file => "comments/empty", :formats => :xml)
42 43
  end

44
  def test_render_template_with_format
45 46
    assert_match "<h1>No Comment</h1>", @view.render(:template => "comments/empty", :formats => [:html])
    assert_match "<error>No Comment</error>", @view.render(:template => "comments/empty", :formats => [:xml])
47
  end
48

49 50 51 52 53
  def test_rendered_format_without_format
    @view.render(:inline => "test")
    assert_equal :html, @view.lookup_context.rendered_format
  end

54 55 56 57 58
  def test_render_partial_implicitly_use_format_of_the_rendered_template
    @view.lookup_context.formats = [:json]
    assert_equal "Hello world", @view.render(:template => "test/one", :formats => [:html])
  end

59 60 61 62 63 64 65
  def test_render_partial_implicitly_use_format_of_the_rendered_partial
    @view.lookup_context.formats = [:html]
    assert_equal "Third level", @view.render(:template => "test/html_template")
  end

  def test_render_partial_use_last_prepended_format_for_partials_with_the_same_names
    @view.lookup_context.formats = [:html]
C
Carlos Antonio da Silva 已提交
66
    assert_equal "\nHTML Template, but JSON partial", @view.render(:template => "test/change_priority")
67 68
  end

69
  def test_render_template_with_a_missing_partial_of_another_format
70
    @view.lookup_context.formats = [:html]
F
Franky W 已提交
71
    e = assert_raise ActionView::Template::Error do
72 73
      @view.render(:template => "with_format", :formats => [:json])
    end
F
Franky W 已提交
74
    assert_includes(e.message, "Missing partial /_missing with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :builder, :ruby]}.")
75 76
  end

77 78
  def test_render_file_with_locale
    assert_equal "<h1>Kein Kommentar</h1>", @view.render(:file => "comments/empty", :locale => [:de])
79
    assert_equal "<h1>Kein Kommentar</h1>", @view.render(:file => "comments/empty", :locale => :de)
80
  end
81

82 83 84
  def test_render_template_with_locale
    assert_equal "<h1>Kein Kommentar</h1>", @view.render(:template => "comments/empty", :locale => [:de])
  end
85

86 87
  def test_render_file_with_handlers
    assert_equal "<h1>No Comment</h1>\n", @view.render(:file => "comments/empty", :handlers => [:builder])
88
    assert_equal "<h1>No Comment</h1>\n", @view.render(:file => "comments/empty", :handlers => :builder)
89
  end
90

91 92 93
  def test_render_template_with_handlers
    assert_equal "<h1>No Comment</h1>\n", @view.render(:template => "comments/empty", :handlers => [:builder])
  end
94

95 96 97 98 99 100 101 102
  def test_render_raw_template_with_handlers
    assert_equal "<%= hello_world %>\n", @view.render(:template => "plain_text")
  end

  def test_render_raw_template_with_quotes
    assert_equal %q;Here are some characters: !@#$%^&*()-="'}{`; + "\n", @view.render(:template => "plain_text_with_characters")
  end

103
  def test_render_ruby_template_with_handlers
G
Guillermo Iguaran 已提交
104 105 106
    assert_equal "Hello from Ruby code", @view.render(:template => "ruby_template")
  end

107 108
  def test_render_ruby_template_inline
    assert_equal '4', @view.render(:inline => "(2**2).to_s", :type => :ruby)
G
Guillermo Iguaran 已提交
109 110
  end

111
  def test_render_file_with_localization_on_context_level
112
    old_locale, @view.locale = @view.locale, :da
113 114
    assert_equal "Hey verden", @view.render(:file => "test/hello_world")
  ensure
115
    @view.locale = old_locale
J
Joshua Peek 已提交
116 117
  end

118
  def test_render_file_with_dashed_locale
119
    old_locale, @view.locale = @view.locale, :"pt-BR"
120
    assert_equal "Ola mundo", @view.render(:file => "test/hello_world")
121
  ensure
122
    @view.locale = old_locale
123 124
  end

125
  def test_render_file_at_top_level
126
    assert_equal 'Elastica', @view.render(:file => '/shared')
127 128
  end

129
  def test_render_file_with_full_path
130
    template_path = File.join(File.dirname(__FILE__), '../fixtures/test/hello_world')
131
    assert_equal "Hello world!", @view.render(:file => template_path)
132 133 134
  end

  def test_render_file_with_instance_variables
135
    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_ivar")
136 137 138 139
  end

  def test_render_file_with_locals
    locals = { :secret => 'in the sauce' }
140
    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/render_file_with_locals", :locals => locals)
141 142 143
  end

  def test_render_file_not_using_full_path_with_dot_in_path
144
    assert_equal "The secret is in the sauce\n", @view.render(:file => "test/dot.directory/render_file_with_ivar")
145 146
  end

147 148 149 150
  def test_render_partial_from_default
    assert_equal "only partial", @view.render("test/partial_only")
  end

151 152 153 154
  def test_render_partial
    assert_equal "only partial", @view.render(:partial => "test/partial_only")
  end

155 156 157 158
  def test_render_partial_with_format
    assert_equal 'partial html', @view.render(:partial => 'test/partial')
  end

159 160 161 162 163
  def test_render_partial_with_selected_format
    assert_equal 'partial html', @view.render(:partial => 'test/partial', :formats => :html)
    assert_equal 'partial js', @view.render(:partial => 'test/partial', :formats => [:js])
  end

164
  def test_render_partial_at_top_level
165
    # file fixtures/_top_level_partial_only (not fixtures/test)
166 167 168 169
    assert_equal 'top level partial', @view.render(:partial => '/top_level_partial_only')
  end

  def test_render_partial_with_format_at_top_level
170
    # file fixtures/_top_level_partial.html (not fixtures/test, with format extension)
171 172 173
    assert_equal 'top level partial html', @view.render(:partial => '/top_level_partial')
  end

174 175 176 177
  def test_render_partial_with_locals
    assert_equal "5", @view.render(:partial => "test/counter", :locals => { :counter_counter => 5 })
  end

178 179 180 181
  def test_render_partial_with_locals_from_default
    assert_equal "only partial", @view.render("test/partial_only", :counter_counter => 5)
  end

182 183
  def test_render_partial_with_number
    assert_nothing_raised { @view.render(:partial => "test/200") }
184 185 186
  end

  def test_render_partial_with_missing_filename
187
    assert_raises(ActionView::MissingTemplate) { @view.render(:partial => "test/") }
188 189
  end

190
  def test_render_partial_with_incompatible_object
191
    e = assert_raises(ArgumentError) { @view.render(:partial => nil) }
192
    assert_equal "'#{nil.inspect}' is not an ActiveModel-compatible object. It must implement :to_partial_path.", e.message
193 194
  end

195 196 197 198
  def test_render_partial_starting_with_a_capital
    assert_nothing_raised { @view.render(:partial => 'test/FooBar') }
  end

199
  def test_render_partial_with_hyphen
200
    assert_nothing_raised { @view.render(:partial => "test/a-in") }
201 202 203 204 205 206 207 208 209 210 211 212 213
  end

  def test_render_partial_with_invalid_option_as
    e = assert_raises(ArgumentError) { @view.render(:partial => "test/partial_only", :as => 'a-in') }
    assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " +
      "make sure it starts with lowercase letter, " +
      "and is followed by any combination of letters, numbers and underscores.", e.message
  end

  def test_render_partial_with_hyphen_and_invalid_option_as
    e = assert_raises(ArgumentError) { @view.render(:partial => "test/a-in", :as => 'a-in') }
    assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " +
      "make sure it starts with lowercase letter, " +
214 215 216
      "and is followed by any combination of letters, numbers and underscores.", e.message
  end

217
  def test_render_partial_with_errors
218
    e = assert_raises(ActionView::Template::Error) { @view.render(:partial => "test/raise") }
219
    assert_match %r!method.*doesnt_exist!, e.message
220 221
    assert_equal "", e.sub_template_message
    assert_equal "1", e.line_number
222
    assert_equal "1: <%= doesnt_exist %>", e.annoted_source_code.strip
223 224 225
    assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name
  end

226 227 228 229 230 231 232 233 234
  def test_render_error_indentation
    e = assert_raises(ActionView::Template::Error) { @view.render(:partial => "test/raise_indentation") }
    error_lines = e.annoted_source_code.split("\n")
    assert_match %r!error\shere!, e.message
    assert_equal "11", e.line_number
    assert_equal "     9: <p>Ninth paragraph</p>", error_lines.second
    assert_equal "    10: <p>Tenth paragraph</p>", error_lines.third
  end

235
  def test_render_sub_template_with_errors
236
    e = assert_raises(ActionView::Template::Error) { @view.render(:template => "test/sub_template_raise") }
237
    assert_match %r!method.*doesnt_exist!, e.message
238 239 240
    assert_equal "Trace of template inclusion: #{File.expand_path("#{FIXTURE_LOAD_PATH}/test/sub_template_raise.html.erb")}", e.sub_template_message
    assert_equal "1", e.line_number
    assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name
241 242
  end

243
  def test_render_file_with_errors
244
    e = assert_raises(ActionView::Template::Error) { @view.render(:file => File.expand_path("test/_raise", FIXTURE_LOAD_PATH)) }
245 246 247 248 249 250 251
    assert_match %r!method.*doesnt_exist!, e.message
    assert_equal "", e.sub_template_message
    assert_equal "1", e.line_number
    assert_equal "1: <%= doesnt_exist %>", e.annoted_source_code.strip
    assert_equal File.expand_path("#{FIXTURE_LOAD_PATH}/test/_raise.html.erb"), e.file_name
  end

252 253
  def test_render_object
    assert_equal "Hello: david", @view.render(:partial => "test/customer", :object => Customer.new("david"))
254 255
    assert_equal "FalseClass", @view.render(:partial => "test/klass", :object => false)
    assert_equal "NilClass", @view.render(:partial => "test/klass", :object => nil)
256 257
  end

258 259 260 261
  def test_render_object_with_array
    assert_equal "[1, 2, 3]", @view.render(:partial => "test/object_inspector", :object => [1, 2, 3])
  end

262 263 264
  def test_render_partial_collection
    assert_equal "Hello: davidHello: mary", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), Customer.new("mary") ])
  end
265

266 267 268 269 270 271
  def test_render_partial_collection_as_by_string
    assert_equal "david david davidmary mary mary",
      @view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => 'customer')
  end

  def test_render_partial_collection_as_by_symbol
272
    assert_equal "david david davidmary mary mary",
273 274
      @view.render(:partial => "test/customer_with_var", :collection => [ Customer.new("david"), Customer.new("mary") ], :as => :customer)
  end
275

276
  def test_render_partial_collection_without_as
277
    assert_equal "local_inspector,local_inspector_counter,local_inspector_iteration",
278 279
      @view.render(:partial => "test/local_inspector", :collection => [ Customer.new("mary") ])
  end
280

281 282 283 284 285 286 287 288
  def test_render_partial_with_empty_collection_should_return_nil
    assert_nil @view.render(:partial => "test/customer", :collection => [])
  end

  def test_render_partial_with_nil_collection_should_return_nil
    assert_nil @view.render(:partial => "test/customer", :collection => nil)
  end

289 290 291 292 293 294 295 296
  def test_render_partial_without_object_does_not_put_partial_name_to_local_assigns
    assert_equal 'false', @view.render(partial: 'test/partial_name_in_local_assigns')
  end

  def test_render_partial_with_nil_object_puts_partial_name_to_local_assigns
    assert_equal 'true', @view.render(partial: 'test/partial_name_in_local_assigns', object: nil)
  end

297 298 299
  def test_render_partial_with_nil_values_in_collection
    assert_equal "Hello: davidHello: Anonymous", @view.render(:partial => "test/customer", :collection => [ Customer.new("david"), nil ])
  end
300

301 302 303
  def test_render_partial_with_layout_using_collection_and_template
    assert_equal "<b>Hello: Amazon</b><b>Hello: Yahoo</b>", @view.render(:partial => "test/customer", :layout => 'test/b_layout_for_partial', :collection => [ Customer.new("Amazon"), Customer.new("Yahoo") ])
  end
304

305 306 307
  def test_render_partial_with_layout_using_collection_and_template_makes_current_item_available_in_layout
    assert_equal '<b class="amazon">Hello: Amazon</b><b class="yahoo">Hello: Yahoo</b>',
      @view.render(:partial => "test/customer", :layout => 'test/b_layout_for_partial_with_object', :collection => [ Customer.new("Amazon"), Customer.new("Yahoo") ])
308 309
  end

310 311 312 313 314 315 316 317
  def test_render_partial_with_layout_using_collection_and_template_makes_current_item_counter_available_in_layout
    assert_equal '<b data-counter="0">Hello: Amazon</b><b data-counter="1">Hello: Yahoo</b>',
      @view.render(:partial => "test/customer", :layout => 'test/b_layout_for_partial_with_object_counter', :collection => [ Customer.new("Amazon"), Customer.new("Yahoo") ])
  end

  def test_render_partial_with_layout_using_object_and_template_makes_object_available_in_layout
    assert_equal '<b class="amazon">Hello: Amazon</b>',
      @view.render(:partial => "test/customer", :layout => 'test/b_layout_for_partial_with_object', :object => Customer.new("Amazon"))
318 319
  end

320 321 322 323
  def test_render_partial_with_empty_array_should_return_nil
    assert_nil @view.render(:partial => [])
  end

Y
Yehuda Katz 已提交
324 325 326 327 328 329 330 331
  def test_render_partial_using_string
    assert_equal "Hello: Anonymous", @controller_view.render('customer')
  end

  def test_render_partial_with_locals_using_string
    assert_equal "Hola: david", @controller_view.render('customer_greeting', :greeting => 'Hola', :customer_greeting => Customer.new("david"))
  end

332 333 334 335 336 337 338 339 340 341
  def test_render_partial_with_object_uses_render_partial_path
    assert_equal "Hello: lifo",
      @controller_view.render(:partial => Customer.new("lifo"), :locals => {:greeting => "Hello"})
  end

  def test_render_partial_with_object_and_format_uses_render_partial_path
    assert_equal "<greeting>Hello</greeting><name>lifo</name>",
      @controller_view.render(:partial => Customer.new("lifo"), :formats => :xml, :locals => {:greeting => "Hello"})
  end

Y
Yehuda Katz 已提交
342 343 344 345 346 347 348 349 350 351 352
  def test_render_partial_using_object
    assert_equal "Hello: lifo",
      @controller_view.render(Customer.new("lifo"), :greeting => "Hello")
  end

  def test_render_partial_using_collection
    customers = [ Customer.new("Amazon"), Customer.new("Yahoo") ]
    assert_equal "Hello: AmazonHello: Yahoo",
      @controller_view.render(customers, :greeting => "Hello")
  end

E
Eugene Gilburg 已提交
353 354 355 356
  def test_render_partial_using_collection_without_path
    assert_equal "hi good customer: david0", @controller_view.render([ GoodCustomer.new("david") ], greeting: "hi")
  end

357 358 359 360
  def test_render_partial_without_object_or_collection_does_not_generate_partial_name_local_variable
    exception = assert_raises ActionView::Template::Error do
      @controller_view.render("partial_name_local_variable")
    end
361 362
    assert_instance_of NameError, exception.cause
    assert_equal :partial_name_local_variable, exception.cause.name
363 364
  end

365 366 367 368 369 370 371
  # TODO: The reason for this test is unclear, improve documentation
  def test_render_partial_and_fallback_to_layout
    assert_equal "Before (Josh)\n\nAfter", @view.render(:partial => "test/layout_for_partial", :locals => { :name => "Josh" })
  end

  # TODO: The reason for this test is unclear, improve documentation
  def test_render_missing_xml_partial_and_raise_missing_template
372
    @view.formats = [:xml]
373
    assert_raises(ActionView::MissingTemplate) { @view.render(:partial => "test/layout_for_partial") }
374 375
  ensure
    @view.formats = nil
376 377
  end

A
Anton Astashov 已提交
378
  def test_render_layout_with_block_and_other_partial_inside
379
    render = @view.render(:layout => "test/layout_with_partial_and_yield") { "Yield!" }
A
Anton Astashov 已提交
380 381 382
    assert_equal "Before\npartial html\nYield!\nAfter\n", render
  end

383 384 385 386 387 388 389 390 391
  def test_render_inline
    assert_equal "Hello, World!", @view.render(:inline => "Hello, World!")
  end

  def test_render_inline_with_locals
    assert_equal "Hello, Josh!", @view.render(:inline => "Hello, <%= name %>!", :locals => { :name => "Josh" })
  end

  def test_render_fallbacks_to_erb_for_unknown_types
392
    assert_equal "Hello, World!", @view.render(:inline => "Hello, World!", :type => :bar)
393 394
  end

395 396 397
  CustomHandler = lambda do |template|
    "@output_buffer = ''\n" +
      "@output_buffer << 'source: #{template.source.inspect}'\n"
398 399
  end

400 401
  def test_render_inline_with_render_from_to_proc
    ActionView::Template.register_template_handler :ruby_handler, :source.to_proc
402 403 404
    assert_equal '3', @view.render(inline: "(1 + 2).to_s", type: :ruby_handler)
  ensure
    ActionView::Template.unregister_template_handler :ruby_handler
405 406
  end

407
  def test_render_inline_with_compilable_custom_type
408
    ActionView::Template.register_template_handler :foo, CustomHandler
409 410 411
    assert_equal 'source: "Hello, World!"', @view.render(inline: "Hello, World!", type: :foo)
  ensure
    ActionView::Template.unregister_template_handler :foo
412 413 414
  end

  def test_render_inline_with_locals_and_compilable_custom_type
415
    ActionView::Template.register_template_handler :foo, CustomHandler
416 417 418
    assert_equal 'source: "Hello, <%= name %>!"', @view.render(inline: "Hello, <%= name %>!", locals: { name: "Josh" }, type: :foo)
  ensure
    ActionView::Template.unregister_template_handler :foo
419
  end
420

E
Eugene Gilburg 已提交
421 422 423 424 425 426 427 428
  def test_render_body
    assert_equal 'some body', @view.render(body: 'some body')
  end

  def test_render_plain
    assert_equal 'some plaintext', @view.render(plain: 'some plaintext')
  end

429 430 431 432
  def test_render_knows_about_types_registered_when_extensions_are_checked_earlier_in_initialization
    ActionView::Template::Handlers.extensions
    ActionView::Template.register_template_handler :foo, CustomHandler
    assert ActionView::Template::Handlers.extensions.include?(:foo)
433 434 435 436 437 438 439 440 441 442 443
  ensure
    ActionView::Template.unregister_template_handler :foo
  end

  def test_render_does_not_use_unregistered_extension_and_template_handler
    ActionView::Template.register_template_handler :foo, CustomHandler
    ActionView::Template.unregister_template_handler :foo
    assert_not ActionView::Template::Handlers.extensions.include?(:foo)
    assert_equal "Hello, World!", @view.render(inline: "Hello, World!", type: :foo)
  ensure
    ActionView::Template::Handlers.class_variable_get(:@@template_handlers).delete(:foo)
444
  end
445

446
  def test_render_ignores_templates_with_malformed_template_handlers
447 448
    ActiveSupport::Deprecation.silence do
      %w(malformed malformed.erb malformed.html.erb malformed.en.html.erb).each do |name|
A
Arun Agrawal 已提交
449
        assert File.exist?(File.expand_path("#{FIXTURE_LOAD_PATH}/test/malformed/#{name}~")), "Malformed file (#{name}~) which should be ignored does not exists"
450
        assert_raises(ActionView::MissingTemplate) { @view.render(:file => "test/malformed/#{name}") }
451
      end
452 453 454
    end
  end

455 456
  def test_render_with_layout
    assert_equal %(<title></title>\nHello world!\n),
457
      @view.render(:file => "test/hello_world", :layout => "layouts/yield")
458 459
  end

460 461
  def test_render_with_layout_which_has_render_inline
    assert_equal %(welcome\nHello world!\n),
462
      @view.render(:file => "test/hello_world", :layout => "layouts/yield_with_render_inline_inside")
463 464
  end

465 466
  def test_render_with_layout_which_renders_another_partial
    assert_equal %(partial html\nHello world!\n),
467
      @view.render(:file => "test/hello_world", :layout => "layouts/yield_with_render_partial_inside")
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
  end

  def test_render_layout_with_block_and_yield
    assert_equal %(Content from block!\n),
      @view.render(:layout => "layouts/yield_only") { "Content from block!" }
  end

  def test_render_layout_with_block_and_yield_with_params
    assert_equal %(Yield! Content from block!\n),
      @view.render(:layout => "layouts/yield_with_params") { |param| "#{param} Content from block!" }
  end

  def test_render_layout_with_block_which_renders_another_partial_and_yields
    assert_equal %(partial html\nContent from block!\n),
      @view.render(:layout => "layouts/partial_and_yield") { "Content from block!" }
  end

485 486 487 488 489 490 491 492 493 494
  def test_render_partial_and_layout_without_block_with_locals
    assert_equal %(Before (Foo!)\npartial html\nAfter),
      @view.render(:partial => 'test/partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
  end

  def test_render_partial_and_layout_without_block_with_locals_and_rendering_another_partial
    assert_equal %(Before (Foo!)\npartial html\npartial with partial\n\nAfter),
      @view.render(:partial => 'test/partial_with_partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
  end

495 496 497 498 499
  def test_render_partial_shortcut_with_block_content
    assert_equal %(Before (shortcut test)\nBefore\n\n  Yielded: arg1/arg2\n\nAfter\nAfter),
      @view.render(partial: "test/partial_shortcut_with_block_content", layout: "test/layout_for_partial", locals: { name: "shortcut test" })
  end

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514
  def test_render_layout_with_a_nested_render_layout_call
    assert_equal %(Before (Foo!)\nBefore (Bar!)\npartial html\nAfter\npartial with layout\n\nAfter),
      @view.render(:partial => 'test/partial_with_layout', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
  end

  def test_render_layout_with_a_nested_render_layout_call_using_block_with_render_partial
    assert_equal %(Before (Foo!)\nBefore (Bar!)\n\n  partial html\n\nAfterpartial with layout\n\nAfter),
      @view.render(:partial => 'test/partial_with_layout_block_partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
  end

  def test_render_layout_with_a_nested_render_layout_call_using_block_with_render_content
    assert_equal %(Before (Foo!)\nBefore (Bar!)\n\n  Content from inside layout!\n\nAfterpartial with layout\n\nAfter),
      @view.render(:partial => 'test/partial_with_layout_block_content', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
  end

515 516
  def test_render_partial_with_layout_raises_descriptive_error
    e = assert_raises(ActionView::MissingTemplate) { @view.render(partial: 'test/partial', layout: true) }
517
    assert_match "Missing partial /_true with", e.message
518 519
  end

520
  def test_render_with_nested_layout
521
    assert_equal %(<title>title</title>\n\n<div id="column">column</div>\n<div id="content">content</div>\n),
522
      @view.render(:file => "test/nested_layout", :layout => "layouts/yield")
523
  end
524

525 526
  def test_render_with_file_in_layout
    assert_equal %(\n<title>title</title>\n\n),
527
      @view.render(:file => "test/layout_render_file")
528
  end
529 530 531

  def test_render_layout_with_object
    assert_equal %(<title>David</title>),
532
      @view.render(:file => "test/layout_render_object")
533
  end
534

535 536
  def test_render_with_passing_couple_extensions_to_one_register_template_handler_function_call
    ActionView::Template.register_template_handler :foo1, :foo2, CustomHandler
537 538 539
    assert_equal @view.render(inline: "Hello, World!", type: :foo1), @view.render(inline: "Hello, World!", type: :foo2)
  ensure
    ActionView::Template.unregister_template_handler :foo1, :foo2
540
  end
541

542 543 544
  def test_render_throws_exception_when_no_extensions_passed_to_register_template_handler_function_call
    assert_raises(ArgumentError) { ActionView::Template.register_template_handler CustomHandler }
  end
545
end
546

Y
Yehuda Katz 已提交
547
class CachedViewRenderTest < ActiveSupport::TestCase
548 549 550 551 552
  include RenderTestCases

  # Ensure view path cache is primed
  def setup
    view_paths = ActionController::Base.view_paths
553
    assert_equal ActionView::OptimizedFileSystemResolver, view_paths.first.class
554 555
    setup_view(view_paths)
  end
W
wycats 已提交
556 557 558

  def teardown
    GC.start
559
    I18n.reload!
W
wycats 已提交
560
  end
561 562
end

Y
Yehuda Katz 已提交
563
class LazyViewRenderTest < ActiveSupport::TestCase
564 565
  include RenderTestCases

566 567 568
  # Test the same thing as above, but make sure the view path
  # is not eager loaded
  def setup
569
    path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH)
A
Aaron Patterson 已提交
570
    view_paths = ActionView::PathSet.new([path])
571
    assert_equal ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH), view_paths.first
572
    setup_view(view_paths)
573
  end
W
wycats 已提交
574 575 576

  def teardown
    GC.start
577
    I18n.reload!
W
wycats 已提交
578
  end
579

580 581 582 583 584
  def test_render_utf8_template_with_magic_comment
    with_external_encoding Encoding::ASCII_8BIT do
      result = @view.render(:file => "test/utf8_magic", :formats => [:html], :layouts => "layouts/yield")
      assert_equal Encoding::UTF_8, result.encoding
      assert_equal "\nРусский \nтекст\n\nUTF-8\nUTF-8\nUTF-8\n", result
585
    end
586
  end
587

588 589 590 591 592
  def test_render_utf8_template_with_default_external_encoding
    with_external_encoding Encoding::UTF_8 do
      result = @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield")
      assert_equal Encoding::UTF_8, result.encoding
      assert_equal "Русский текст\n\nUTF-8\nUTF-8\nUTF-8\n", result
593
    end
594
  end
595

596 597
  def test_render_utf8_template_with_incompatible_external_encoding
    with_external_encoding Encoding::SHIFT_JIS do
598
      e = assert_raises(ActionView::Template::Error) { @view.render(:file => "test/utf8", :formats => [:html], :layouts => "layouts/yield") }
599
      assert_match 'Your template was not saved as valid Shift_JIS', e.cause.message
600
    end
601
  end
602

603 604
  def test_render_utf8_template_with_partial_with_incompatible_encoding
    with_external_encoding Encoding::SHIFT_JIS do
605
      e = assert_raises(ActionView::Template::Error) { @view.render(:file => "test/utf8_magic_with_bare_partial", :formats => [:html], :layouts => "layouts/yield") }
606
      assert_match 'Your template was not saved as valid Shift_JIS', e.cause.message
607
    end
608
  end
609

610 611 612 613 614 615
  def with_external_encoding(encoding)
    old = Encoding.default_external
    silence_warnings { Encoding.default_external = encoding }
    yield
  ensure
    silence_warnings { Encoding.default_external = old }
616
  end
617
end
618 619

class CachedCollectionViewRenderTest < CachedViewRenderTest
620 621 622 623 624 625
  class CachedCustomer < Customer; end

  teardown do
    ActionView::PartialRenderer.collection_cache.clear
  end

626 627
  test "with custom key" do
    customer = Customer.new("david")
628
    key = cache_key([customer, 'key'], "test/_customer")
629 630 631 632 633

    ActionView::PartialRenderer.collection_cache.write(key, 'Hello')

    assert_equal "Hello",
      @view.render(partial: "test/customer", collection: [customer], cache: ->(item) { [item, 'key'] })
634
  end
635

636 637 638 639 640 641 642 643 644 645
  test "with caching with custom key and rendering with different key" do
    customer = Customer.new("david")
    key = cache_key([customer, 'key'], "test/_customer")

    ActionView::PartialRenderer.collection_cache.write(key, 'Hello')

    assert_equal "Hello: david",
      @view.render(partial: "test/customer", collection: [customer], cache: ->(item) { [item, 'another_key'] })
  end

646 647
  test "automatic caching with inferred cache name" do
    customer = CachedCustomer.new("david")
648
    key = cache_key(customer, "test/_cached_customer")
649 650 651 652 653 654 655 656 657

    ActionView::PartialRenderer.collection_cache.write(key, 'Cached')

    assert_equal "Cached",
      @view.render(partial: "test/cached_customer", collection: [customer])
  end

  test "automatic caching with as name" do
    customer = CachedCustomer.new("david")
658
    key = cache_key(customer, "test/_cached_customer_as")
659 660 661 662 663

    ActionView::PartialRenderer.collection_cache.write(key, 'Cached')

    assert_equal "Cached",
      @view.render(partial: "test/cached_customer_as", collection: [customer], as: :buyer)
664
  end
665 666 667 668 669 670

  private
    def cache_key(names, virtual_path)
      digest = ActionView::Digestor.digest name: virtual_path, finder: @view.lookup_context, dependencies: []
      @view.fragment_cache_key([ *Array(names), digest ])
    end
671
end