form_helper_test.rb 83.6 KB
Newer Older
1
require 'abstract_unit'
2
require 'controller/fake_models'
3
require 'active_support/core_ext/object/inclusion'
4

5 6
class FormHelperTest < ActionView::TestCase
  tests ActionView::Helpers::FormHelper
D
Initial  
David Heinemeier Hansson 已提交
7

W
wycats 已提交
8 9 10 11
  def form_for(*)
    @output_buffer = super
  end

D
Initial  
David Heinemeier Hansson 已提交
12
  def setup
13
    super
14 15 16 17 18 19 20 21 22 23

    # Create "label" locale for testing I18n label helpers
    I18n.backend.store_translations 'label', {
      :activemodel => {
        :attributes => {
          :post => {
            :cost => "Total cost"
          }
        }
      },
24 25
      :helpers => {
        :label => {
26
          :post => {
27 28 29 30
            :body => "Write entire text here",
            :color => {
              :red => "Rojo"
            }
31 32 33 34 35
          }
        }
      }
    }

36 37 38 39
    # Create "submit" locale for testing I18n submit helpers
    I18n.backend.store_translations 'submit', {
      :helpers => {
        :submit => {
40 41
          :create => 'Create %{model}',
          :update => 'Confirm %{model} changes',
42 43
          :submit => 'Save changes',
          :another_post => {
44
            :update => 'Update your %{model}'
45
          }
46 47 48 49
        }
      }
    }

50
    @post = Post.new
51
    @comment = Comment.new
52 53
    def @post.errors()
      Class.new{
54
        def [](field); field == "author_name" ? ["can't be empty"] : [] end
55
        def empty?() false end
56
        def count() 1 end
57 58
        def full_messages() [ "Author name can't be empty" ] end
      }.new
59
    end
60
    def @post.id; 123; end
61
    def @post.id_before_type_cast; 123; end
62
    def @post.to_param; '123'; end
63

64
    @post.persisted   = true
D
Initial  
David Heinemeier Hansson 已提交
65 66 67 68 69
    @post.title       = "Hello World"
    @post.author_name = ""
    @post.body        = "Back to the hill and over it again!"
    @post.secret      = 1
    @post.written_on  = Date.new(2004, 6, 15)
70 71

    @blog_post = Blog::Post.new("And his name will be forty and four.", 44)
72
  end
73

74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
  Routes = ActionDispatch::Routing::RouteSet.new
  Routes.draw do
    resources :posts do
      resources :comments
    end

    namespace :admin do
      resources :posts do
        resources :comments
      end
    end

    match "/foo", :to => "controller#action"
    root :to => "main#index"
  end

  def _routes
    Routes
  end

  include Routes.url_helpers

96 97
  def url_for(object)
    @url_for_options = object
98 99
    if object.is_a?(Hash) && object[:use_route].blank? && object[:controller].blank?
      object.merge!(:controller => "main", :action => "index")
100
    end
101
    super
D
Initial  
David Heinemeier Hansson 已提交
102 103
  end

104 105 106 107 108 109 110
  def test_label
    assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
    assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
    assert_dom_equal(
      '<label class="title_label" for="post_title">Title</label>',
      label("post", "title", nil, :class => 'title_label')
    )
111
    assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
112
  end
113

114 115
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
116
    assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
117 118
  end

119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
  def test_label_with_locales_strings
    old_locale, I18n.locale = I18n.locale, :label
    assert_dom_equal('<label for="post_body">Write entire text here</label>', label("post", "body"))
  ensure
    I18n.locale = old_locale
  end

  def test_label_with_human_attribute_name
    old_locale, I18n.locale = I18n.locale, :label
    assert_dom_equal('<label for="post_cost">Total cost</label>', label(:post, :cost))
  ensure
    I18n.locale = old_locale
  end

  def test_label_with_locales_symbols
    old_locale, I18n.locale = I18n.locale, :label
    assert_dom_equal('<label for="post_body">Write entire text here</label>', label(:post, :body))
  ensure
    I18n.locale = old_locale
  end

140 141 142 143 144 145 146
  def test_label_with_locales_and_options
    old_locale, I18n.locale = I18n.locale, :label
    assert_dom_equal('<label for="post_body" class="post_body">Write entire text here</label>', label(:post, :body, :class => 'post_body'))
  ensure
    I18n.locale = old_locale
  end

147 148 149 150 151 152 153
  def test_label_with_locales_and_value
    old_locale, I18n.locale = I18n.locale, :label
    assert_dom_equal('<label for="post_color_red">Rojo</label>', label(:post, :color, :value => "red"))
  ensure
    I18n.locale = old_locale
  end

154 155 156 157 158 159 160 161
  def test_label_with_for_attribute_as_symbol
    assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, :for => "my_for"))
  end

  def test_label_with_for_attribute_as_string
    assert_dom_equal('<label for="my_for">Title</label>', label(:post, :title, nil, "for" => "my_for"))
  end

162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
  def test_label_with_id_attribute_as_symbol
    assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
  end

  def test_label_with_id_attribute_as_string
    assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
  end

  def test_label_with_for_and_id_attributes_as_symbol
    assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
  end

  def test_label_with_for_and_id_attributes_as_string
    assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
  end

178 179 180 181 182
  def test_label_for_radio_buttons_with_value
    assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
    assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
  end

S
Stephen Celis 已提交
183 184 185 186
  def test_label_with_block
    assert_dom_equal('<label for="post_title">The title, please:</label>', label(:post, :title) { "The title, please:" })
  end

D
Initial  
David Heinemeier Hansson 已提交
187
  def test_text_field
188
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
189 190
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
191
    assert_dom_equal(
192 193 194 195
      '<input id="post_title" name="post[title]" size="30" type="password" />', password_field("post", "title")
    )
    assert_dom_equal(
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title", :value => @post.title)
D
Initial  
David Heinemeier Hansson 已提交
196
    )
197
    assert_dom_equal(
198
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
199 200 201 202 203
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
204
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
205 206 207 208
      '<input id="post_title" name="post[title]" size="30" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
    )
  end

209 210 211 212 213 214 215 216
  def test_text_field_with_html_entities
    @post.title = "The HTML Entity for & is &amp;"
    assert_dom_equal(
      '<input id="post_title" name="post[title]" size="30" type="text" value="The HTML Entity for &amp; is &amp;amp;" />',
      text_field("post", "title")
    )
  end

D
Initial  
David Heinemeier Hansson 已提交
217
  def test_text_field_with_options
218
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
219 220
    assert_dom_equal expected, text_field("post", "title", "size" => 35)
    assert_dom_equal expected, text_field("post", "title", :size => 35)
D
Initial  
David Heinemeier Hansson 已提交
221
  end
222

D
Initial  
David Heinemeier Hansson 已提交
223
  def test_text_field_assuming_size
224
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
225 226
    assert_dom_equal expected, text_field("post", "title", "maxlength" => 35)
    assert_dom_equal expected, text_field("post", "title", :maxlength => 35)
D
Initial  
David Heinemeier Hansson 已提交
227
  end
228

229 230 231 232 233 234
  def test_text_field_removing_size
    expected = '<input id="post_title" maxlength="35" name="post[title]" type="text" value="Hello World" />'
    assert_dom_equal expected, text_field("post", "title", "maxlength" => 35, "size" => nil)
    assert_dom_equal expected, text_field("post", "title", :maxlength => 35, :size => nil)
  end

235 236 237 238 239
  def test_text_field_with_nil_value
    expected = '<input id="post_title" name="post[title]" size="30" type="text" />'
    assert_dom_equal expected, text_field("post", "title", :value => nil)
  end

240 241 242 243 244 245 246
  def test_text_field_doesnt_change_param_values
    object_name = 'post[]'
    expected = '<input id="post_123_title" name="post[123][title]" size="30" type="text" value="Hello World" />'
    assert_equal expected, text_field(object_name, "title")
    assert_equal object_name, "post[]"
  end

247 248 249 250 251
  def test_file_field_has_no_size
    expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
    assert_dom_equal expected, file_field("user", "avatar")
  end

252 253 254
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
255 256
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
257 258 259 260 261 262 263 264
  end

  def test_hidden_field_with_escapes
    @post.title = "<b>Hello World</b>"
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
      hidden_field("post", "title")
  end

265 266 267 268 269
  def test_hidden_field_with_nil_value
    expected = '<input id="post_title" name="post[title]" type="hidden" />'
    assert_dom_equal expected, hidden_field("post", "title", :value => nil)
  end

270
  def test_hidden_field_with_options
271 272 273 274
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
      hidden_field("post", "title", :value => "Something Else")
  end

275 276 277 278 279
  def test_text_field_with_custom_type
    assert_dom_equal '<input id="user_email" size="30" name="user[email]" type="email" />',
      text_field("user", "email", :type => "email")
  end

D
Initial  
David Heinemeier Hansson 已提交
280
  def test_check_box
281
    assert_dom_equal(
282
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
283 284 285
      check_box("post", "secret")
    )
    @post.secret = 0
286
    assert_dom_equal(
287
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
288
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
289
    )
290
    assert_dom_equal(
291
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
292 293
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
294
    @post.secret = true
295
    assert_dom_equal(
296
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
297 298
      check_box("post", "secret")
    )
299
    assert_dom_equal(
300
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
301 302
      check_box("post", "secret?")
    )
303 304 305

    @post.secret = ['0']
    assert_dom_equal(
306
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
307 308 309 310
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
311
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
312 313
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
314
  end
315

316 317
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
318
    assert_dom_equal(
319
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
320 321 322
      check_box("post", "secret", {}, "on", "off")
    )
  end
323

324 325 326 327 328 329 330 331 332 333 334 335 336
  def test_check_box_with_multiple_behavior
    @post.comment_ids = [2,3]
    assert_dom_equal(
      '<input name="post[comment_ids][]" type="hidden" value="0" /><input id="post_comment_ids_1" name="post[comment_ids][]" type="checkbox" value="1" />',
      check_box("post", "comment_ids", { :multiple => true }, 1)
    )
    assert_dom_equal(
      '<input name="post[comment_ids][]" type="hidden" value="0" /><input checked="checked" id="post_comment_ids_3" name="post[comment_ids][]" type="checkbox" value="3" />',
      check_box("post", "comment_ids", { :multiple => true }, 3)
    )
  end


337 338
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
339
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
340 341 342 343
      check_box("post", "secret", { :disabled => :true })
    )
  end

344
  def test_radio_button
345
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
346
      radio_button("post", "title", "Hello World")
347
    )
348
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
349
      radio_button("post", "title", "Goodbye World")
350
    )
351 352 353
    assert_dom_equal('<input id="item_subobject_title_inside_world" name="item[subobject][title]" type="radio" value="inside world"/>',
      radio_button("item[subobject]", "title", "inside world")
    )
354
  end
355

356 357 358 359 360
  def test_radio_button_is_checked_with_integers
    assert_dom_equal('<input checked="checked" id="post_secret_1" name="post[secret]" type="radio" value="1" />',
      radio_button("post", "secret", "1")
   )
  end
361

N
Neeraj Singh 已提交
362 363 364 365 366
  def test_radio_button_with_negative_integer_value
    assert_dom_equal('<input id="post_secret_-1" name="post[secret]" type="radio" value="-1" />',
      radio_button("post", "secret", "-1"))
  end

367 368 369 370 371
  def test_radio_button_respects_passed_in_id
     assert_dom_equal('<input checked="checked" id="foo" name="post[secret]" type="radio" value="1" />',
       radio_button("post", "secret", "1", :id=>"foo")
    )
  end
372

373 374 375 376 377 378 379 380 381 382
  def test_radio_button_with_booleans
    assert_dom_equal('<input id="post_secret_true" name="post[secret]" type="radio" value="true" />',
      radio_button("post", "secret", true)
    )

    assert_dom_equal('<input id="post_secret_false" name="post[secret]" type="radio" value="false" />',
      radio_button("post", "secret", false)
    )
  end

D
Initial  
David Heinemeier Hansson 已提交
383
  def test_text_area
384
    assert_dom_equal(
385
      '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
386 387 388
      text_area("post", "body")
    )
  end
389

D
Initial  
David Heinemeier Hansson 已提交
390 391
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
392
    assert_dom_equal(
393
      '<textarea cols="40" id="post_body" name="post[body]" rows="20">Back to &lt;i&gt;the&lt;/i&gt; hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
394 395 396
      text_area("post", "body")
    )
  end
397

398 399 400 401 402 403
  def test_text_area_with_alternate_value
    assert_dom_equal(
      '<textarea cols="40" id="post_body" name="post[body]" rows="20">Testing alternate values.</textarea>',
      text_area("post", "body", :value => 'Testing alternate values.')
    )
  end
404

405 406 407 408 409 410 411 412
  def test_text_area_with_html_entities
    @post.body        = "The HTML Entity for & is &amp;"
    assert_dom_equal(
      '<textarea cols="40" id="post_body" name="post[body]" rows="20">The HTML Entity for &amp; is &amp;amp;</textarea>',
      text_area("post", "body")
    )
  end

413 414 415 416 417 418
  def test_text_area_with_size_option
    assert_dom_equal(
      '<textarea cols="183" id="post_body" name="post[body]" rows="820">Back to the hill and over it again!</textarea>',
      text_area("post", "body", :size => "183x820")
    )
  end
419

420
  def test_search_field
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
    expected = %{<input id="contact_notes_query" size="30" name="contact[notes_query]" type="search" />}
    assert_dom_equal(expected, search_field("contact", "notes_query"))
  end

  def test_telephone_field
    expected = %{<input id="user_cell" size="30" name="user[cell]" type="tel" />}
    assert_dom_equal(expected, telephone_field("user", "cell"))
  end

  def test_url_field
    expected = %{<input id="user_homepage" size="30" name="user[homepage]" type="url" />}
    assert_dom_equal(expected, url_field("user", "homepage"))
  end

  def test_email_field
    expected = %{<input id="user_address" size="30" name="user[address]" type="email" />}
    assert_dom_equal(expected, email_field("user", "address"))
  end

  def test_number_field
    expected = %{<input name="order[quantity]" size="30" max="9" id="order_quantity" type="number" min="1" />}
    assert_dom_equal(expected, number_field("order", "quantity", :in => 1...10))
  end

  def test_range_input
    expected = %{<input name="hifi[volume]" step="0.1" size="30" max="11" id="hifi_volume" type="range" min="0" />}
    assert_dom_equal(expected, range_field("hifi", "volume", :in => 0..11, :step => 0.1))
  end

D
Initial  
David Heinemeier Hansson 已提交
450
  def test_explicit_name
451
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
452
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
453
    )
454
    assert_dom_equal(
455
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
456 457
      text_area("post", "body", "name" => "really!")
    )
458
    assert_dom_equal(
459
      '<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
460 461
      check_box("post", "secret", "name" => "i mean it")
    )
462
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
463
                 text_field("post", "title", :name => "dont guess")
464
    assert_dom_equal text_area("post", "body", "name" => "really!"),
465
                 text_area("post", "body", :name => "really!")
466
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
467
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
468
  end
469

D
Initial  
David Heinemeier Hansson 已提交
470
  def test_explicit_id
471
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
472
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
473
    )
474
    assert_dom_equal(
475
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
476 477
      text_area("post", "body", "id" => "really!")
    )
478
    assert_dom_equal(
479
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
480 481
      check_box("post", "secret", "id" => "i mean it")
    )
482
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
483
                 text_field("post", "title", :id => "dont guess")
484
    assert_dom_equal text_area("post", "body", "id" => "really!"),
485
                 text_area("post", "body", :id => "really!")
486
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
487
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
488
  end
489

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
  def test_nil_id
    assert_dom_equal(
      '<input name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => nil)
    )
    assert_dom_equal(
      '<textarea cols="40" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
      text_area("post", "body", "id" => nil)
    )
    assert_dom_equal(
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" name="post[secret]" type="checkbox" value="1" />',
      check_box("post", "secret", "id" => nil)
    )
    assert_dom_equal(
      '<input type="radio" name="post[secret]" value="0" />',
      radio_button("post", "secret", "0", "id" => nil)
    )
    assert_dom_equal(
      '<select name="post[secret]"></select>',
      select("post", "secret", [], {}, "id" => nil)
    )
    assert_dom_equal text_field("post", "title", "id" => nil),
                 text_field("post", "title", :id => nil)
    assert_dom_equal text_area("post", "body", "id" => nil),
                 text_area("post", "body", :id => nil)
    assert_dom_equal check_box("post", "secret", "id" => nil),
                 check_box("post", "secret", :id => nil)
516 517
    assert_dom_equal radio_button("post", "secret", "0", "id" => nil),
                 radio_button("post", "secret", "0", :id => nil)
518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
  end

  def test_index
    assert_dom_equal(
      '<input name="post[5][title]" size="30" id="post_5_title" type="text" value="Hello World" />',
      text_field("post", "title", "index" => 5)
    )
    assert_dom_equal(
      '<textarea cols="40" name="post[5][body]" id="post_5_body" rows="20">Back to the hill and over it again!</textarea>',
      text_area("post", "body", "index" => 5)
    )
    assert_dom_equal(
      '<input name="post[5][secret]" type="hidden" value="0" /><input checked="checked" name="post[5][secret]" type="checkbox" value="1" id="post_5_secret" />',
      check_box("post", "secret", "index" => 5)
    )
    assert_dom_equal(
      text_field("post", "title", "index" => 5),
      text_field("post", "title", "index" => 5)
    )
    assert_dom_equal(
      text_area("post", "body", "index" => 5),
      text_area("post", "body", "index" => 5)
    )
    assert_dom_equal(
      check_box("post", "secret", "index" => 5),
      check_box("post", "secret", "index" => 5)
    )
  end

  def test_index_with_nil_id
    assert_dom_equal(
      '<input name="post[5][title]" size="30" type="text" value="Hello World" />',
      text_field("post", "title", "index" => 5, 'id' => nil)
    )
    assert_dom_equal(
      '<textarea cols="40" name="post[5][body]" rows="20">Back to the hill and over it again!</textarea>',
      text_area("post", "body", "index" => 5, 'id' => nil)
    )
    assert_dom_equal(
      '<input name="post[5][secret]" type="hidden" value="0" /><input checked="checked" name="post[5][secret]" type="checkbox" value="1" />',
      check_box("post", "secret", "index" => 5, 'id' => nil)
    )
    assert_dom_equal(
      text_field("post", "title", "index" => 5, 'id' => nil),
      text_field("post", "title", :index => 5, :id => nil)
    )
    assert_dom_equal(
      text_area("post", "body", "index" => 5, 'id' => nil),
      text_area("post", "body", :index => 5, :id => nil)
    )
    assert_dom_equal(
      check_box("post", "secret", "index" => 5, 'id' => nil),
      check_box("post", "secret", :index => 5, :id => nil)
    )
  end

574 575
  def test_auto_index
    pid = @post.id
576 577 578 579
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
580
    assert_dom_equal(
581 582
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
583
    assert_dom_equal(
584
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
585 586
      text_area("post[]", "body")
    )
587
    assert_dom_equal(
588
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
589 590
      check_box("post[]", "secret")
    )
591
   assert_dom_equal(
592
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
593 594
      radio_button("post[]", "title", "Hello World")
    )
595
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
596 597 598
      radio_button("post[]", "title", "Goodbye World")
    )
  end
599

600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
  def test_auto_index_with_nil_id
    pid = @post.id
    assert_dom_equal(
      "<input name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />",
      text_field("post[]","title", :id => nil)
    )
    assert_dom_equal(
      "<textarea cols=\"40\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
      text_area("post[]", "body", :id => nil)
    )
    assert_dom_equal(
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
      check_box("post[]", "secret", :id => nil)
    )
   assert_dom_equal(
"<input checked=\"checked\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
      radio_button("post[]", "title", "Hello World", :id => nil)
    )
    assert_dom_equal("<input name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
      radio_button("post[]", "title", "Goodbye World", :id => nil)
    )
  end

A
Aaron Patterson 已提交
623 624 625 626 627 628
  def test_form_for_requires_block
    assert_raises(ArgumentError) do
      form_for(:post, @post, :html => { :id => 'create-post' })
    end
  end

629
  def test_form_for
630 631 632 633 634 635
    form_for(@post, :html => { :id => 'create-post' }) do |f|
      concat f.label(:title) { "The Title" }
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
636 637
    end

638
    expected = whole_form("/posts/123", "create-post" , "edit_post", :method => "put") do
S
Stephen Celis 已提交
639
      "<label for='post_title'>The Title</label>" +
640 641
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
642
      "<input name='post[secret]' type='hidden' value='0' />" +
643
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
644
      "<input name='commit' type='submit' value='Create post' />"
645
    end
646

647
    assert_dom_equal expected, output_buffer
648 649
  end

650 651 652
  def test_form_for_with_file_field_generate_multipart
    Post.send :attr_accessor, :file

653 654
    form_for(@post, :html => { :id => 'create-post' }) do |f|
      concat f.file_field(:file)
655 656
    end

657 658 659
    expected = whole_form("/posts/123", "create-post" , "edit_post", :method => "put", :multipart => true) do
      "<input name='post[file]' type='file' id='post_file' />"
    end
660 661 662 663

    assert_dom_equal expected, output_buffer
  end

664 665 666
  def test_fields_for_with_file_field_generate_multipart
    Comment.send :attr_accessor, :file

667 668 669 670
    form_for(@post) do |f|
      concat f.fields_for(:comment, @post) { |c|
        concat c.file_field(:file)
      }
671 672
    end

673 674 675
    expected = whole_form("/posts/123", "edit_post_123" , "edit_post", :method => "put", :multipart => true) do
      "<input name='post[comment][file]' type='file' id='post_comment_file' />"
    end
676 677 678 679 680

    assert_dom_equal expected, output_buffer
  end


681 682 683 684 685 686 687 688 689 690 691 692
  def test_form_for_with_format
    form_for(@post, :format => :json, :html => { :id => "edit_post_123", :class => "edit_post" }) do |f|
      concat f.label(:title)
    end

    expected = whole_form("/posts/123.json", "edit_post_123" , "edit_post", :method => "put") do
      "<label for='post_title'>Title</label>"
    end

    assert_dom_equal expected, output_buffer
  end

693 694 695 696 697 698
  def test_form_for_with_isolated_namespaced_model
    form_for(@blog_post) do |f|
      concat f.text_field :title
      concat f.submit('Edit post')
    end

699
    expected = whole_form("/posts/44", "edit_post_44" , "edit_post", :method => "put") do
700
      "<input name='post[title]' size='30' type='text' id='post_title' value='And his name will be forty and four.' />" +
701
      "<input name='commit' type='submit' value='Edit post' />" +
702
      "</form>"
703 704 705
    end

    assert_dom_equal expected, output_buffer
706 707
  end

708
  def test_form_for_with_symbol_object_name
709
    form_for(@post, :as => "other_name", :html => { :id => 'create-post' }) do |f|
710
      concat f.label(:title, :class => 'post_title')
711 712 713
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
714 715 716
      concat f.submit('Create post')
    end

W
wycats 已提交
717
    expected =  whole_form("/posts/123", "create-post", "other_name_edit", :method => "put") do
718
      "<label for='other_name_title' class='post_title'>Title</label>" +
719 720 721
      "<input name='other_name[title]' size='30' id='other_name_title' value='Hello World' type='text' />" +
      "<textarea name='other_name[body]' id='other_name_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='other_name[secret]' value='0' type='hidden' />" +
S
Stephen Celis 已提交
722
      "<input name='other_name[secret]' checked='checked' id='other_name_secret' value='1' type='checkbox' />" +
723
      "<input name='commit' value='Create post' type='submit' />"
W
wycats 已提交
724
    end
725 726 727 728

    assert_dom_equal expected, output_buffer
  end

729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
  def test_form_for_with_method_as_part_of_html_options
    form_for(@post, :url => '/', :html => { :id => 'create-post', :method => :delete }) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
    end

    expected =  whole_form("/", "create-post", "edit_post", "delete") do
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
    end

    assert_dom_equal expected, output_buffer
  end

746
  def test_form_for_with_method
747
    form_for(@post, :url => '/', :method => :delete, :html => { :id => 'create-post' }) do |f|
748 749 750
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
751 752
    end

753
    expected =  whole_form("/", "create-post", "edit_post", "delete") do
754 755
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
756
      "<input name='post[secret]' type='hidden' value='0' />" +
W
wycats 已提交
757 758
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
    end
759

760
    assert_dom_equal expected, output_buffer
761
  end
762

763 764 765
  def test_form_for_with_search_field
    # Test case for bug which would emit an "object" attribute
    # when used with form_for using a search_field form helper
766
    form_for(Post.new, :url => "/search", :html => { :id => 'search-post', :method => :get}) do |f|
767 768 769
      concat f.search_field(:title)
    end

770
    expected =  whole_form("/search", "search-post", "new_post", "get") do
771 772 773 774 775
      "<input name='post[title]' size='30' type='search' id='post_title' />"
    end

    assert_dom_equal expected, output_buffer
  end
776

777
  def test_form_for_with_remote
778 779 780 781
    form_for(@post, :url => '/', :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
782 783
    end

784
    expected =  whole_form("/", "create-post", "edit_post", :method => "put", :remote => true) do
785 786 787
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
W
wycats 已提交
788 789
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
    end
790 791 792 793

    assert_dom_equal expected, output_buffer
  end

794
  def test_form_for_with_remote_without_html
795 796 797 798 799
    @post.persisted = false
    form_for(@post, :remote => true) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
800 801
    end

802
    expected =  whole_form("/posts", 'new_post', 'new_post', :remote => true) do
803 804 805
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
W
wycats 已提交
806 807
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
    end
808 809 810 811

    assert_dom_equal expected, output_buffer
  end

812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
  def test_form_for_without_object
    form_for(:post, :html => { :id => 'create-post' }) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
    end

    expected = whole_form("/", "create-post") do
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
    end

    assert_dom_equal expected, output_buffer
  end

829
  def test_form_for_with_index
830 831 832 833 834
    form_for(@post, :as => "post[]") do |f|
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
835
    end
836

837
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
838
      "<label for='post_123_title'>Title</label>" +
839 840
      "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
      "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
841
      "<input name='post[123][secret]' type='hidden' value='0' />" +
W
wycats 已提交
842 843
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
    end
844

845
    assert_dom_equal expected, output_buffer
846 847
  end

848
  def test_form_for_with_nil_index_option_override
849 850 851 852
    form_for(@post, :as => "post[]", :index => nil) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
853 854
    end

855
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
856 857 858
      "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
      "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[][secret]' type='hidden' value='0' />" +
W
wycats 已提交
859 860
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
    end
861

862
    assert_dom_equal expected, output_buffer
863 864
  end

865 866 867
  def test_submit_with_object_as_new_record_and_locale_strings
    old_locale, I18n.locale = I18n.locale, :submit

868
    @post.persisted = false
869 870
    form_for(@post) do |f|
      concat f.submit
871 872
    end

873
    expected = whole_form('/posts', 'new_post', 'new_post') do
874
      "<input name='commit' type='submit' value='Create Post' />"
875
    end
W
wycats 已提交
876

877 878 879 880 881 882 883 884
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

  def test_submit_with_object_as_existing_record_and_locale_strings
    old_locale, I18n.locale = I18n.locale, :submit

885 886
    form_for(@post) do |f|
      concat f.submit
887 888
    end

889
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
890
      "<input name='commit' type='submit' value='Confirm Post changes' />"
891
    end
W
wycats 已提交
892

893 894 895 896 897
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

898 899 900 901 902 903 904 905
  def test_submit_without_object_and_locale_strings
    old_locale, I18n.locale = I18n.locale, :submit

    form_for(:post) do |f|
      concat f.submit :class => "extra"
    end

    expected = whole_form do
906
      "<input name='commit' class='extra' type='submit' value='Save changes' />"
907 908 909 910 911 912 913
    end

    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

914 915 916
  def test_submit_with_object_and_nested_lookup
    old_locale, I18n.locale = I18n.locale, :submit

917 918
    form_for(@post, :as => :another_post) do |f|
      concat f.submit
919 920
    end

921
    expected = whole_form('/posts/123', 'another_post_edit', 'another_post_edit', :method => 'put') do
922
      "<input name='commit' type='submit' value='Update your Post' />"
923
    end
W
wycats 已提交
924

925 926 927 928 929
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

930
  def test_nested_fields_for
931 932 933 934 935
    @comment.body = 'Hello World'
    form_for(@post) do |f|
      concat f.fields_for(@comment) { |c|
        concat c.text_field(:body)
      }
936 937
    end

938 939 940
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      "<input name='post[comment][body]' size='30' type='text' id='post_comment_body' value='Hello World' />"
    end
941

942
    assert_dom_equal expected, output_buffer
943
  end
944

945
  def test_nested_fields_for_with_nested_collections
946 947 948 949 950
    form_for(@post, :as => 'post[]') do |f|
      concat f.text_field(:title)
      concat f.fields_for('comment[]', @comment) { |c|
        concat c.text_field(:name)
      }
951 952
    end

953
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
954 955 956
      "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
      "<input name='post[123][comment][][name]' size='30' type='text' id='post_123_comment__name' value='new comment' />"
    end
957 958 959 960

    assert_dom_equal expected, output_buffer
  end

961
  def test_nested_fields_for_with_index_and_parent_fields
962 963 964 965 966
    form_for(@post, :index => 1) do |c|
      concat c.text_field(:title)
      concat c.fields_for('comment', @comment, :index => 1) { |r|
        concat r.text_field(:name)
      }
967 968
    end

969
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
970 971 972
      "<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
      "<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' />"
    end
973 974 975 976

    assert_dom_equal expected, output_buffer
  end

977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992
  def test_nested_fields_for_with_index_with_index_and_parent_fields
    form_for(@post, :index => 1) do |c|
      concat c.text_field(:title)
      concat c.fields_for_with_index('comment', @comment, :index => 1) { |r, comment_index|
        concat r.text_field(:name, "data-index" => comment_index)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[1][title]' size='30' type='text' id='post_1_title' value='Hello World' />" +
      "<input name='post[1][comment][1][name]' size='30' type='text' id='post_1_comment_1_name' value='new comment' data-index='1' />"
    end

    assert_dom_equal expected, output_buffer
  end

993
  def test_form_for_with_index_and_nested_fields_for
994 995 996 997
    output_buffer = form_for(@post, :index => 1) do |f|
      concat f.fields_for(:comment, @post) { |c|
        concat c.text_field(:title)
      }
998 999
    end

1000 1001 1002
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />"
    end
1003 1004 1005 1006 1007

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_index_on_both
1008 1009 1010 1011
    form_for(@post, :index => 1) do |f|
      concat f.fields_for(:comment, @post, :index => 5) { |c|
        concat c.text_field(:title)
      }
1012 1013
    end

1014 1015 1016
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />"
    end
1017 1018 1019 1020 1021

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_auto_index
1022 1023 1024 1025
    form_for(@post, :as => "post[]") do |f|
      concat f.fields_for(:comment, @post) { |c|
        concat c.text_field(:title)
      }
1026 1027
    end

1028
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
1029 1030
      "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />"
    end
1031 1032 1033 1034

    assert_dom_equal expected, output_buffer
  end

1035
  def test_nested_fields_for_with_index_radio_button
1036 1037 1038 1039
    form_for(@post) do |f|
      concat f.fields_for(:comment, @post, :index => 5) { |c|
        concat c.radio_button(:title, "hello")
      }
1040 1041
    end

1042 1043 1044
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />"
    end
1045 1046 1047 1048

    assert_dom_equal expected, output_buffer
  end

1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062
  def test_nested_fields_for_with_index_with_index_radio_button
    form_for(@post) do |f|
      concat f.fields_for_with_index(:comment, @post, :index => 5) { |c, index|
        concat c.radio_button(:title, "hello", "data-index" => index)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' data-index='5' />"
    end

    assert_dom_equal expected, output_buffer
  end

1063
  def test_nested_fields_for_with_auto_index_on_both
1064 1065 1066 1067
    form_for(@post, :as => "post[]") do |f|
      concat f.fields_for("comment[]", @post) { |c|
        concat c.text_field(:title)
      }
1068 1069
    end

1070
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
1071 1072
      "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />"
    end
1073 1074 1075 1076 1077

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_index_and_auto_index
1078 1079 1080 1081 1082
    output_buffer = form_for(@post, :as => "post[]") do |f|
      concat f.fields_for(:comment, @post, :index => 5) { |c|
        concat c.text_field(:title)
      }
    end
1083

1084 1085 1086 1087 1088
    output_buffer << form_for(@post, :as => :post, :index => 1) do |f|
      concat f.fields_for("comment[]", @post) { |c|
        concat c.text_field(:title)
      }
    end
1089

1090 1091 1092 1093
    expected = whole_form('/posts/123', 'post[]_edit', 'post[]_edit', 'put') do
      "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />"
    end + whole_form('/posts/123', 'post_edit', 'post_edit', 'put') do
      "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />"
1094
    end
1095 1096

    assert_dom_equal expected, output_buffer
1097 1098
  end

1099 1100 1101
  def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new

1102 1103 1104 1105 1106
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.text_field(:name)
      }
1107 1108
    end

1109 1110 1111 1112
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
        '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />'
    end
1113 1114 1115 1116

    assert_dom_equal expected, output_buffer
  end

1117
  def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
1118 1119 1120 1121
    form_for(@post) do |f|
      f.fields_for(:author, Author.new(123)) do |af|
        assert_not_nil af.object
        assert_equal 123, af.object.id
1122 1123 1124 1125
      end
    end
  end

1126 1127 1128
  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new(321)

1129 1130 1131 1132 1133
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.text_field(:name)
      }
1134 1135
    end

1136 1137 1138 1139 1140
   expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
     '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
     '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
     '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
   end
1141 1142 1143

    assert_dom_equal expected, output_buffer
  end
1144

1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_using_erb_and_inline_block
    @post.author = Author.new(321)

    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        af.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
    end

    assert_dom_equal expected, output_buffer
  end

1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id
    @post.author = Author.new(321)

    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author, :include_id => false) { |af|
        af.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
    end

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_inherited
    @post.author = Author.new(321)

    form_for(@post, :include_id => false) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        af.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
    end

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association_with_disabled_hidden_id_override
    @post.author = Author.new(321)

    form_for(@post, :include_id => false) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author, :include_id => true) { |af|
        af.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />'
    end

    assert_dom_equal expected, output_buffer
  end

1219 1220 1221
  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
    @post.author = Author.new(321)

1222 1223 1224 1225 1226 1227
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.hidden_field(:id)
        concat af.text_field(:name)
      }
1228
    end
1229

1230 1231 1232 1233 1234
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />'
    end
1235 1236 1237 1238 1239 1240 1241

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

1242 1243 1244 1245 1246 1247
    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.text_field(:name)
        }
1248 1249 1250
      end
    end

1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end

    assert_dom_equal expected, output_buffer
  end

1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
  def test_nested_fields_for_with_index_with_existing_records_on_a_nested_attributes_collection_association
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for_with_index(:comments, comment) { |cf, index|
          concat cf.text_field(:name, "data-index" => index)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" data-index="0" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" data-index="1" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end

    assert_dom_equal expected, output_buffer
  end

1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311
  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.author = Author.new(321)

    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.text_field(:name)
      }
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment, :include_id => false) { |cf|
          concat cf.text_field(:name)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
    end

    assert_dom_equal expected, output_buffer
  end

1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338
  def test_nested_fields_for_with_index_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.author = Author.new(321)

    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.text_field(:name)
      }
      @post.comments.each do |comment|
        concat f.fields_for_with_index(:comments, comment, :include_id => false) { |cf, index|
          concat cf.text_field(:name, 'data-index' => index)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" data-index="0" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" data-index="1" />'
    end

    assert_dom_equal expected, output_buffer
  end

1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id_inherited
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.author = Author.new(321)

    form_for(@post, :include_id => false) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author) { |af|
        concat af.text_field(:name)
      }
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.text_field(:name)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
    end

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_disabled_hidden_id_override
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.author = Author.new(321)

    form_for(@post, :include_id => false) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:author, :include_id => true) { |af|
        concat af.text_field(:name)
      }
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.text_field(:name)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
      '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
    end

    assert_dom_equal expected, output_buffer
  end

1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403
  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_using_erb_and_inline_block
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          cf.text_field(:name)
        }
      end
    end

1404 1405 1406 1407 1408 1409 1410
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end
1411 1412 1413 1414 1415 1416 1417

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

1418 1419 1420 1421 1422 1423 1424
    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.hidden_field(:id)
          concat cf.text_field(:name)
        }
1425 1426
      end
    end
1427

1428 1429 1430 1431 1432 1433 1434
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />'
    end
1435 1436 1437 1438 1439 1440 1441

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new, Comment.new]

1442 1443 1444 1445 1446 1447
    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.text_field(:name)
        }
1448 1449 1450
      end
    end

1451 1452 1453 1454 1455
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
    end
1456 1457 1458 1459

    assert_dom_equal expected, output_buffer
  end

1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481
  def test_nested_fields_for_with_index_with_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new, Comment.new]

    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for_with_index(:comments, comment) { |cf, index|
          concat cf.text_field(:name, "data-index" => index)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" data-index="0" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" data-index="1" />'
    end

    assert_dom_equal expected, output_buffer
  end


1482 1483 1484
  def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new(321), Comment.new]

1485 1486 1487 1488 1489 1490
    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for(:comments, comment) { |cf|
          concat cf.text_field(:name)
        }
1491 1492 1493
      end
    end

1494 1495 1496 1497 1498 1499
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
    end
1500 1501 1502 1503

    assert_dom_equal expected, output_buffer
  end

1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526
  def test_nested_fields_for_with_index_with_existing_and_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new(321), Comment.new]

    form_for(@post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        concat f.fields_for_with_index(:comments, comment) { |cf, index|
          concat cf.text_field(:name, "data-index" => index)
        }
      end
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" data-index="0" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" data-index="1" />'
    end

    assert_dom_equal expected, output_buffer
  end


1527
  def test_nested_fields_for_with_an_empty_supplied_attributes_collection
1528 1529 1530 1531
    form_for(@post) do |f|
      concat f.text_field(:title)
      f.fields_for(:comments, []) do |cf|
        concat cf.text_field(:name)
1532 1533 1534
      end
    end

1535 1536 1537
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />'
    end
1538 1539 1540 1541 1542 1543 1544

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

1545 1546 1547 1548 1549
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:comments, @post.comments) { |cf|
        concat cf.text_field(:name)
      }
1550 1551
    end

1552
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_arel_like
    @post.comments = ArelLike.new

    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:comments, @post.comments) { |cf|
        concat cf.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
1574 1575 1576 1577 1578 1579
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end
1580 1581 1582 1583 1584 1585 1586 1587

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection_different_from_record_one
    comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.comments = []

1588 1589 1590 1591 1592
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:comments, comments) { |cf|
        concat cf.text_field(:name)
      }
1593 1594
    end

1595 1596 1597 1598 1599 1600 1601
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
      '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />'
    end
1602 1603 1604 1605

    assert_dom_equal expected, output_buffer
  end

1606 1607 1608 1609
  def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
    @post.comments = [Comment.new(321), Comment.new]
    yielded_comments = []

1610 1611 1612 1613 1614 1615
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.fields_for(:comments) { |cf|
        concat cf.text_field(:name)
        yielded_comments << cf.object
      }
1616 1617
    end

1618 1619 1620 1621 1622 1623
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
      '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />'
    end
1624 1625 1626 1627 1628

    assert_dom_equal expected, output_buffer
    assert_equal yielded_comments, @post.comments
  end

1629 1630 1631
  def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
    @post.comments = []

1632 1633 1634 1635
    form_for(@post) do |f|
      concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
        concat cf.text_field(:name)
      }
1636 1637
    end

1638 1639 1640 1641
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
      '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />'
    end
1642 1643 1644 1645

    assert_dom_equal expected, output_buffer
  end

1646 1647 1648 1649 1650 1651
  def test_nested_fields_uses_unique_indices_for_different_collection_associations
    @post.comments = [Comment.new(321)]
    @post.tags = [Tag.new(123), Tag.new(456)]
    @post.comments[0].relevances = []
    @post.tags[0].relevances = []
    @post.tags[1].relevances = []
1652

1653 1654 1655 1656 1657
    form_for(@post) do |f|
      concat f.fields_for(:comments, @post.comments[0]) { |cf|
        concat cf.text_field(:name)
        concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
          concat crf.text_field(:value)
W
wycats 已提交
1658
        }
1659 1660 1661 1662 1663
      }
      concat f.fields_for(:tags, @post.tags[0]) { |tf|
        concat tf.text_field(:value)
        concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
          concat trf.text_field(:value)
W
wycats 已提交
1664
        }
1665 1666 1667 1668 1669
      }
      concat f.fields_for('tags', @post.tags[1]) { |tf|
        concat tf.text_field(:value)
        concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
          concat trf.text_field(:value)
W
wycats 已提交
1670
        }
1671
      }
1672 1673
    end

1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
      '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
      '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
      '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
      '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
      '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
      '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
      '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
      '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
      '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
      '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
      '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />'
    end
1688 1689 1690 1691

    assert_dom_equal expected, output_buffer
  end

1692
  def test_fields_for
W
wycats 已提交
1693
    output_buffer = fields_for(:post, @post) do |f|
1694 1695 1696
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1697 1698
    end

1699
    expected =
1700 1701
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1702 1703
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1704

1705
    assert_dom_equal expected, output_buffer
1706 1707 1708
  end

  def test_fields_for_with_index
W
wycats 已提交
1709
    output_buffer = fields_for("post[]", @post) do |f|
1710 1711 1712
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1713 1714 1715 1716 1717
    end

    expected =
      "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
      "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1718 1719
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
1720

1721
    assert_dom_equal expected, output_buffer
1722 1723 1724
  end

  def test_fields_for_with_nil_index_option_override
W
wycats 已提交
1725
    output_buffer = fields_for("post[]", @post, :index => nil) do |f|
1726 1727 1728
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1729 1730 1731 1732 1733
    end

    expected =
      "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
      "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1734 1735
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
1736

1737
    assert_dom_equal expected, output_buffer
1738 1739 1740
  end

  def test_fields_for_with_index_option_override
W
wycats 已提交
1741
    output_buffer = fields_for("post[]", @post, :index => "abc") do |f|
1742 1743 1744
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1745 1746 1747 1748 1749
    end

    expected =
      "<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
      "<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1750 1751
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
1752

1753
    assert_dom_equal expected, output_buffer
1754
  end
1755 1756

  def test_fields_for_without_object
W
wycats 已提交
1757
    output_buffer = fields_for(:post) do |f|
1758 1759 1760
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1761 1762
    end

1763
    expected =
1764 1765
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1766 1767
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1768

1769
    assert_dom_equal expected, output_buffer
1770 1771 1772
  end

  def test_fields_for_with_only_object
W
wycats 已提交
1773
    output_buffer = fields_for(@post) do |f|
1774 1775 1776
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1777 1778
    end

1779
    expected =
1780 1781
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
1782 1783
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1784

1785
    assert_dom_equal expected, output_buffer
1786 1787
  end

1788
  def test_fields_for_object_with_bracketed_name
W
wycats 已提交
1789
    output_buffer = fields_for("author[post]", @post) do |f|
1790 1791
      concat f.label(:title)
      concat f.text_field(:title)
1792 1793
    end

1794 1795
    assert_dom_equal "<label for=\"author_post_title\">Title</label>" +
    "<input name='author[post][title]' size='30' type='text' id='author_post_title' value='Hello World' />",
1796
      output_buffer
1797 1798
  end

1799
  def test_fields_for_object_with_bracketed_name_and_index
W
wycats 已提交
1800
    output_buffer = fields_for("author[post]", @post, :index => 1) do |f|
1801 1802
      concat f.label(:title)
      concat f.text_field(:title)
1803 1804 1805 1806
    end

    assert_dom_equal "<label for=\"author_post_1_title\">Title</label>" +
      "<input name='author[post][1][title]' size='30' type='text' id='author_post_1_title' value='Hello World' />",
1807
      output_buffer
1808 1809
  end

1810 1811 1812
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
1813

1814
  def test_form_for_and_fields_for
1815 1816 1817
    form_for(@post, :as => :post, :html => { :id => 'create-post' }) do |post_form|
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1818

1819 1820 1821
      concat fields_for(:parent_post, @post) { |parent_fields|
        concat parent_fields.check_box(:secret)
      }
1822 1823
    end

1824
    expected = whole_form('/posts/123', 'create-post', 'post_edit', :method => 'put') do
1825 1826 1827
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='parent_post[secret]' type='hidden' value='0' />" +
1828 1829
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />"
    end
1830

1831
    assert_dom_equal expected, output_buffer
1832
  end
1833

1834
  def test_form_for_and_fields_for_with_object
1835 1836 1837
    form_for(@post, :as => :post, :html => { :id => 'create-post' }) do |post_form|
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1838

1839 1840 1841
      concat post_form.fields_for(@comment) { |comment_fields|
        concat comment_fields.text_field(:name)
      }
1842 1843
    end

1844 1845 1846 1847 1848
    expected = whole_form('/posts/123', 'create-post', 'post_edit', :method => 'put') do
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />"
    end
1849

1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863
    assert_dom_equal expected, output_buffer
  end

  def test_form_for_and_fields_for_with_non_nested_association_and_without_object
    form_for(@post) do |f|
      concat f.fields_for(:category) { |c|
        concat c.text_field(:name)
      }
    end

    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', 'put') do
      "<input name='post[category][name]' type='text' size='30' id='post_category_name' />"
    end

1864
    assert_dom_equal expected, output_buffer
1865 1866
  end

1867
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1868
    (field_helpers - %w(hidden_field)).each do |selector|
1869
      class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
1870
        def #{selector}(field, *args, &proc)
1871
          ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe
1872
        end
1873
      RUBY_EVAL
1874 1875
    end
  end
1876

1877
  def test_form_for_with_labelled_builder
1878 1879 1880 1881
    form_for(@post, :builder => LabelledFormBuilder) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1882 1883
    end

1884 1885 1886 1887 1888
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
    end
1889

1890
    assert_dom_equal expected, output_buffer
1891
  end
1892

D
David Lee 已提交
1893
  def hidden_fields(method = nil)
W
wycats 已提交
1894
    txt =  %{<div style="margin:0;padding:0;display:inline">}
W
wycats 已提交
1895
    txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
1896
    if method && !method.to_s.in?(['get', 'post'])
1897 1898
      txt << %{<input name="_method" type="hidden" value="#{method}" />}
    end
W
wycats 已提交
1899 1900 1901
    txt << %{</div>}
  end

1902
  def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil)
W
wycats 已提交
1903
    txt =  %{<form accept-charset="UTF-8" action="#{action}"}
1904
    txt << %{ enctype="multipart/form-data"} if multipart
W
wycats 已提交
1905 1906 1907
    txt << %{ data-remote="true"} if remote
    txt << %{ class="#{html_class}"} if html_class
    txt << %{ id="#{id}"} if id
1908 1909
    method = method.to_s == "get" ? "get" : "post"
    txt << %{ method="#{method}">}
W
wycats 已提交
1910 1911
  end

1912
  def whole_form(action = "/", id = nil, html_class = nil, options = nil)
W
wycats 已提交
1913 1914 1915
    contents = block_given? ? yield : ""

    if options.is_a?(Hash)
1916
      method, remote, multipart = options.values_at(:method, :remote, :multipart)
W
wycats 已提交
1917 1918 1919 1920
    else
      method = options
    end

D
David Lee 已提交
1921
    form_text(action, id, html_class, remote, multipart, method) + hidden_fields(method) + contents + "</form>"
W
wycats 已提交
1922 1923
  end

1924
  def test_default_form_builder
1925 1926
    old_default_form_builder, ActionView::Base.default_form_builder =
      ActionView::Base.default_form_builder, LabelledFormBuilder
1927

1928 1929 1930 1931
    form_for(@post) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1932 1933
    end

1934
    expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', :method => 'put') do
1935 1936
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
W
wycats 已提交
1937 1938
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
    end
1939

1940
    assert_dom_equal expected, output_buffer
1941
  ensure
1942
    ActionView::Base.default_form_builder = old_default_form_builder
1943
  end
1944

1945
  def test_fields_for_with_labelled_builder
W
wycats 已提交
1946
    output_buffer = fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1947 1948 1949
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1950
    end
1951 1952

    expected =
1953 1954
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
1955
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
1956

1957
    assert_dom_equal expected, output_buffer
1958
  end
1959

1960 1961 1962
  def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
    klass = nil

1963 1964 1965 1966
    form_for(@post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new) do |nested_fields|
        klass = nested_fields.class
        ''
1967 1968 1969 1970 1971 1972 1973 1974 1975
      end
    end

    assert_equal LabelledFormBuilder, klass
  end

  def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
    klass = nil

1976 1977 1978 1979
    form_for(@post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
        klass = nested_fields.class
        ''
1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990
      end
    end

    assert_equal LabelledFormBuilder, klass
  end

  class LabelledFormBuilderSubclass < LabelledFormBuilder; end

  def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
    klass = nil

1991 1992 1993 1994
    form_for(@post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
        klass = nested_fields.class
        ''
1995 1996 1997 1998 1999 2000
      end
    end

    assert_equal LabelledFormBuilderSubclass, klass
  end

2001
  def test_form_for_with_html_options_adds_options_to_form_tag
2002 2003
    form_for(@post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
    expected = whole_form("/posts/123", "some_form", "some_class", 'put')
2004

2005
    assert_dom_equal expected, output_buffer
2006
  end
2007

2008
  def test_form_for_with_string_url_option
2009
    form_for(@post, :url => 'http://www.otherdomain.com') do |f| end
2010

2011
    assert_equal whole_form("http://www.otherdomain.com", 'edit_post_123', 'edit_post', 'put'), output_buffer
2012 2013 2014
  end

  def test_form_for_with_hash_url_option
2015
    form_for(@post, :url => {:controller => 'controller', :action => 'action'}) do |f| end
2016

2017 2018
    assert_equal 'controller', @url_for_options[:controller]
    assert_equal 'action', @url_for_options[:action]
2019
  end
2020

2021
  def test_form_for_with_record_url_option
2022
    form_for(@post, :url => @post) do |f| end
2023

2024
    expected = whole_form("/posts/123", 'edit_post_123', 'edit_post', 'put')
2025
    assert_equal expected, output_buffer
2026 2027 2028 2029 2030
  end

  def test_form_for_with_existing_object
    form_for(@post) do |f| end

W
wycats 已提交
2031
    expected = whole_form("/posts/123", "edit_post_123", "edit_post", "put")
2032
    assert_equal expected, output_buffer
2033 2034 2035 2036
  end

  def test_form_for_with_new_object
    post = Post.new
2037
    post.persisted = false
2038 2039 2040 2041
    def post.id() nil end

    form_for(post) do |f| end

W
wycats 已提交
2042
    expected = whole_form("/posts", "new_post", "new_post")
2043
    assert_equal expected, output_buffer
2044 2045
  end

2046 2047 2048 2049
  def test_form_for_with_existing_object_in_list
    @comment.save
    form_for([@post, @comment]) {}

2050
    expected = whole_form(post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
2051
    assert_dom_equal expected, output_buffer
2052 2053 2054 2055 2056
  end

  def test_form_for_with_new_object_in_list
    form_for([@post, @comment]) {}

2057
    expected = whole_form(post_comments_path(@post), "new_comment", "new_comment")
2058
    assert_dom_equal expected, output_buffer
2059 2060
  end

2061 2062 2063
  def test_form_for_with_existing_object_and_namespace_in_list
    @comment.save
    form_for([:admin, @post, @comment]) {}
2064

2065
    expected = whole_form(admin_post_comment_path(@post, @comment), "edit_comment_1", "edit_comment", "put")
2066
    assert_dom_equal expected, output_buffer
2067
  end
2068

2069 2070
  def test_form_for_with_new_object_and_namespace_in_list
    form_for([:admin, @post, @comment]) {}
2071

2072
    expected = whole_form(admin_post_comments_path(@post), "new_comment", "new_comment")
2073
    assert_dom_equal expected, output_buffer
2074 2075
  end

2076 2077 2078
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

W
wycats 已提交
2079
    expected = whole_form("/super_posts", "edit_post_123", "edit_post", "put")
2080
    assert_equal expected, output_buffer
2081
  end
2082

2083 2084 2085 2086 2087
  def test_fields_for_returns_block_result
    output = fields_for(Post.new) { |f| "fields" }
    assert_equal "fields", output
  end

2088
  protected
2089 2090
    def protect_against_forgery?
      false
2091
    end
2092

2093
end