form_helper_test.rb 57.2 KB
Newer Older
1
require 'abstract_unit'
2
require 'controller/fake_models'
3

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

  def setup
8
    super
9 10 11 12 13 14 15 16 17 18

    # Create "label" locale for testing I18n label helpers
    I18n.backend.store_translations 'label', {
      :activemodel => {
        :attributes => {
          :post => {
            :cost => "Total cost"
          }
        }
      },
19 20
      :helpers => {
        :label => {
21 22 23 24 25 26 27
          :post => {
            :body => "Write entire text here"
          }
        }
      }
    }

28 29 30 31 32 33 34 35 36 37 38
    # Create "submit" locale for testing I18n submit helpers
    I18n.backend.store_translations 'submit', {
      :helpers => {
        :submit => {
          :create => 'Create {{model}}',
          :update => 'Confirm {{model}} changes',
          :submit => 'Save changes'
        }
      }
    }

39
    @post = Post.new
40
    @comment = Comment.new
41 42
    def @post.errors()
      Class.new{
43
        def [](field); field == "author_name" ? ["can't be empty"] : [] end
44
        def empty?() false end
45
        def count() 1 end
46 47
        def full_messages() [ "Author name can't be empty" ] end
      }.new
48
    end
49
    def @post.id; 123; end
50
    def @post.id_before_type_cast; 123; end
51
    def @post.to_param; '123'; end
52

D
Initial  
David Heinemeier Hansson 已提交
53 54 55 56 57
    @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)
58 59

    @controller = Class.new do
60
      attr_reader :url_for_options
61
      def url_for(options)
62
        @url_for_options = options
63 64 65 66
        "http://www.example.com"
      end
    end
    @controller = @controller.new
D
Initial  
David Heinemeier Hansson 已提交
67 68
  end

69 70 71 72 73 74 75
  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')
    )
76
    assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
77
  end
78

79 80
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
81
    assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
82 83
  end

84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
  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

105 106 107 108 109 110 111 112
  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

113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
  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

129 130 131 132 133
  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

D
Initial  
David Heinemeier Hansson 已提交
134
  def test_text_field
135
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
136 137
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
138
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
139 140
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
141
    assert_dom_equal(
142
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
143 144 145 146 147
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
148
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
149 150 151 152
      '<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

153 154 155 156 157 158 159 160
  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 已提交
161
  def test_text_field_with_options
162
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
163 164
    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 已提交
165
  end
166

D
Initial  
David Heinemeier Hansson 已提交
167
  def test_text_field_assuming_size
168
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
169 170
    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 已提交
171
  end
172

173 174 175 176 177 178
  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

179 180 181 182 183 184 185
  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

186 187 188
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
189 190
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
191 192 193 194 195 196 197 198 199 200 201 202 203
  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

  def test_text_field_with_options
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
      hidden_field("post", "title", :value => "Something Else")
  end

D
Initial  
David Heinemeier Hansson 已提交
204
  def test_check_box
205
    assert_dom_equal(
206
      '<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 已提交
207 208 209
      check_box("post", "secret")
    )
    @post.secret = 0
210
    assert_dom_equal(
211
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
212
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
213
    )
214
    assert_dom_equal(
215
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
216 217
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
218
    @post.secret = true
219
    assert_dom_equal(
220
      '<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 已提交
221 222
      check_box("post", "secret")
    )
223
    assert_dom_equal(
224
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
225 226
      check_box("post", "secret?")
    )
227 228 229

    @post.secret = ['0']
    assert_dom_equal(
230
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
231 232 233 234
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
235
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
236 237
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
238
  end
239

240 241
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
242
    assert_dom_equal(
243
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
244 245 246
      check_box("post", "secret", {}, "on", "off")
    )
  end
247

248 249 250 251 252 253 254 255 256 257 258 259 260
  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


261 262
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
263
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
264 265 266 267
      check_box("post", "secret", { :disabled => :true })
    )
  end

268
  def test_radio_button
269
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
270
      radio_button("post", "title", "Hello World")
271
    )
272
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
273
      radio_button("post", "title", "Goodbye World")
274
    )
275 276 277
    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")
    )
278
  end
279

280 281 282 283 284
  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
285

286 287 288 289 290
  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
291

292 293 294 295 296 297 298 299 300 301
  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 已提交
302
  def test_text_area
303
    assert_dom_equal(
304
      '<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 已提交
305 306 307
      text_area("post", "body")
    )
  end
308

D
Initial  
David Heinemeier Hansson 已提交
309 310
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
311
    assert_dom_equal(
312
      '<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 已提交
313 314 315
      text_area("post", "body")
    )
  end
316

317 318 319 320 321 322
  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
323

324 325 326 327 328 329 330 331
  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

332 333 334 335 336 337
  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
338

D
Initial  
David Heinemeier Hansson 已提交
339
  def test_explicit_name
340
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
341
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
342
    )
343
    assert_dom_equal(
344
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
345 346
      text_area("post", "body", "name" => "really!")
    )
347
    assert_dom_equal(
348
      '<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 已提交
349 350
      check_box("post", "secret", "name" => "i mean it")
    )
351
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
352
                 text_field("post", "title", :name => "dont guess")
353
    assert_dom_equal text_area("post", "body", "name" => "really!"),
354
                 text_area("post", "body", :name => "really!")
355
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
356
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
357
  end
358

D
Initial  
David Heinemeier Hansson 已提交
359
  def test_explicit_id
360
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
361
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
362
    )
363
    assert_dom_equal(
364
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
365 366
      text_area("post", "body", "id" => "really!")
    )
367
    assert_dom_equal(
368
      '<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 已提交
369 370
      check_box("post", "secret", "id" => "i mean it")
    )
371
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
372
                 text_field("post", "title", :id => "dont guess")
373
    assert_dom_equal text_area("post", "body", "id" => "really!"),
374
                 text_area("post", "body", :id => "really!")
375
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
376
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
377
  end
378 379 380

  def test_auto_index
    pid = @post.id
381 382 383 384
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
385
    assert_dom_equal(
386 387
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
388
    assert_dom_equal(
389
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
390 391
      text_area("post[]", "body")
    )
392
    assert_dom_equal(
393
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
394 395
      check_box("post[]", "secret")
    )
396
   assert_dom_equal(
397
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
398 399
      radio_button("post[]", "title", "Hello World")
    )
400
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
401 402 403
      radio_button("post[]", "title", "Goodbye World")
    )
  end
404 405

  def test_form_for
406
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
407 408 409 410 411
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
412 413
    end

414
    expected =
415
      "<form action='http://www.example.com' id='create-post' method='post'>" +
416
      "<label for='post_title'>Title</label>" +
417 418
      "<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>" +
419
      "<input name='post[secret]' type='hidden' value='0' />" +
420
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
421
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
422 423
      "</form>"

424
    assert_dom_equal expected, output_buffer
425 426 427 428
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
429 430 431
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
432 433
    end

434
    expected =
435
      "<form action='http://www.example.com' id='create-post' method='post'>" +
436
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
437 438
      "<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>" +
439
      "<input name='post[secret]' type='hidden' value='0' />" +
440
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
441 442
      "</form>"

443
    assert_dom_equal expected, output_buffer
444 445
  end

446
  def test_form_for_without_object
447
    form_for(:post, :html => { :id => 'create-post' }) do |f|
448 449 450
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
451 452
    end

453
    expected =
454
      "<form action='http://www.example.com' id='create-post' method='post'>" +
455 456 457
      "<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' />" +
458
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
459 460
      "</form>"

461
    assert_dom_equal expected, output_buffer
462
  end
463

464 465
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
466 467 468 469
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
470
    end
471

472
    expected =
473
      "<form action='http://www.example.com' method='post'>" +
474
      "<label for=\"post_123_title\">Title</label>" +
475 476
      "<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>" +
477
      "<input name='post[123][secret]' type='hidden' value='0' />" +
478
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
479
      "</form>"
480

481
    assert_dom_equal expected, output_buffer
482 483
  end

484 485
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
486 487 488
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
489 490 491 492 493 494 495
    end

    expected =
      "<form action='http://www.example.com' method='post'>" +
      "<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' />" +
496
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
497 498
      "</form>"

499
    assert_dom_equal expected, output_buffer
500 501
  end

502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536
  def test_submit_with_object_as_new_record_and_locale_strings
    old_locale, I18n.locale = I18n.locale, :submit

    def @post.new_record?() true; end
    form_for(:post, @post) do |f|
      concat f.submit
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='commit' id='post_submit' type='submit' value='Create Post' />" +
               "</form>"
    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

    form_for(:post, @post) do |f|
      concat f.submit
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='commit' id='post_submit' type='submit' value='Confirm Post changes' />" +
               "</form>"
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

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

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

    expected = "<form action='http://www.example.com' method='post'>" +
541
               "<input name='commit' class='extra' id='post_submit' type='submit' value='Save changes' />" +
542 543 544 545 546 547
               "</form>"
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

548 549 550
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
551
        concat c.text_field(:title)
552 553 554 555 556 557 558
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[comment][title]' size='30' type='text' id='post_comment_title' value='Hello World' />" +
               "</form>"

559
    assert_dom_equal expected, output_buffer
560
  end
561

562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
  def test_nested_fields_for_with_nested_collections
    form_for('post[]', @post) do |f|
      concat f.text_field(:title)
      f.fields_for('comment[]', @comment) do |c|
        concat c.text_field(:name)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<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' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

578
  def test_nested_fields_for_with_index_and_parent_fields
579 580 581 582 583 584 585 586 587 588 589 590 591 592 593
    form_for('post', @post, :index => 1) do |c|
      concat c.text_field(:title)
      c.fields_for('comment', @comment, :index => 1) do |r|
        concat r.text_field(:name)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<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' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

594
  def test_form_for_with_index_and_nested_fields_for
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
    form_for(:post, @post, :index => 1) do |f|
      f.fields_for(:comment, @post) do |c|
        concat c.text_field(:title)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[1][comment][title]' size='30' type='text' id='post_1_comment_title' value='Hello World' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_index_on_both
    form_for(:post, @post, :index => 1) do |f|
      f.fields_for(:comment, @post, :index => 5) do |c|
        concat c.text_field(:title)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[1][comment][5][title]' size='30' type='text' id='post_1_comment_5_title' value='Hello World' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_auto_index
    form_for("post[]", @post) do |f|
      f.fields_for(:comment, @post) do |c|
        concat c.text_field(:title)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[123][comment][title]' size='30' type='text' id='post_123_comment_title' value='Hello World' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

636 637 638 639 640 641 642 643 644 645 646 647 648 649
  def test_nested_fields_for_with_index_radio_button
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post, :index => 5) do |c|
        concat c.radio_button(:title, "hello")
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686
  def test_nested_fields_for_with_auto_index_on_both
    form_for("post[]", @post) do |f|
      f.fields_for("comment[]", @post) do |c|
        concat c.text_field(:title)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[123][comment][123][title]' size='30' type='text' id='post_123_comment_123_title' value='Hello World' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_index_and_auto_index
    form_for("post[]", @post) do |f|
      f.fields_for(:comment, @post, :index => 5) do |c|
        concat c.text_field(:title)
      end
    end

    form_for(:post, @post, :index => 1) do |f|
      f.fields_for("comment[]", @post) do |c|
        concat c.text_field(:title)
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[123][comment][5][title]' size='30' type='text' id='post_123_comment_5_title' value='Hello World' />" +
               "</form>" +
               "<form action='http://www.example.com' method='post'>" +
               "<input name='post[1][comment][123][title]' size='30' type='text' id='post_1_comment_123_title' value='Hello World' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704
  def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new

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

    expected = '<form action="http://www.example.com" method="post">' +
               '<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" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

705 706 707 708 709 710 711 712 713
  def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
    form_for(:post, @post) do |f|
      f.fields_for(:author, Author.new(123)) do |af|
        assert_not_nil af.object
        assert_equal 123, af.object.id
      end
    end
  end

714 715 716 717 718 719 720 721 722 723
  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new(321)

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

724 725 726 727 728 729 730 731
    expected = '<form action="http://www.example.com" method="post">' +
               '<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" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end
732

733 734 735 736 737 738 739 740 741 742
  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)

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:author) do |af|
        concat af.hidden_field(:id)
        concat af.text_field(:name)
      end
    end
743

744 745
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
746
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
               '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
               '</form>'

    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) }

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

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787
    expected = '<form action="http://www.example.com" method="post">' +
               '<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" />' +
               '</form>'

    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) }

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

789 790
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
791 792 793 794
               '<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" />' +
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813
               '</form>'

    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]

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

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
814 815
               '<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" />' +
816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834
               '</form>'

    assert_dom_equal expected, output_buffer
  end

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

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

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
835
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
836
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
837
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
838 839 840 841 842
               '</form>'

    assert_dom_equal expected, output_buffer
  end

843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
  def test_nested_fields_for_with_an_empty_supplied_attributes_collection
    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:comments, []) do |cf|
        concat cf.text_field(:name)
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
               '</form>'

    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) }

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

    expected = '<form action="http://www.example.com" method="post">' +
               '<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" />' +
871
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
872
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
873
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
874 875 876 877 878
               '</form>'

    assert_dom_equal expected, output_buffer
  end

879 880 881 882 883 884 885 886 887 888 889 890 891 892
  def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
    @post.comments = [Comment.new(321), Comment.new]
    yielded_comments = []

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:comments) do |cf|
        concat cf.text_field(:name)
        yielded_comments << cf.object
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
893
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
894
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
895
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
896 897 898 899 900 901
               '</form>'

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

902 903 904 905 906 907 908 909 910 911 912
  def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
    @post.comments = []

    form_for(:post, @post) do |f|
      f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf|
        concat cf.text_field(:name)
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
913
               '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
914 915 916 917 918
               '</form>'

    assert_dom_equal expected, output_buffer
  end

919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948
  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 = []
    form_for(:post, @post) do |f|
      f.fields_for(:comments, @post.comments[0]) do |cf|
        concat cf.text_field(:name)
        cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
          concat crf.text_field(:value)
        end
      end
      f.fields_for(:tags, @post.tags[0]) do |tf|
        concat tf.text_field(:value)
        tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
          concat trf.text_field(:value)
        end
      end
      f.fields_for('tags', @post.tags[1]) do |tf|
        concat tf.text_field(:value)
        tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
          concat trf.text_field(:value)
        end
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<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" />' +
949 950
               '<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" />' +
951 952
               '<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" />' +
953 954
               '<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" />' +
955 956
               '<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" />' +
957 958
               '<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" />' +
959 960 961 962 963
               '</form>'

    assert_dom_equal expected, output_buffer
  end

964
  def test_fields_for
965
    fields_for(:post, @post) do |f|
966 967 968
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
969 970
    end

971
    expected =
972 973
      "<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>" +
974 975
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
976

977
    assert_dom_equal expected, output_buffer
978 979 980 981
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
982 983 984
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
985 986 987 988 989
    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>" +
990 991
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
992

993
    assert_dom_equal expected, output_buffer
994 995 996 997
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
998 999 1000
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1001 1002 1003 1004 1005
    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>" +
1006 1007
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
1008

1009
    assert_dom_equal expected, output_buffer
1010 1011 1012 1013
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
1014 1015 1016
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1017 1018 1019 1020 1021
    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>" +
1022 1023
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
1024

1025
    assert_dom_equal expected, output_buffer
1026
  end
1027 1028 1029

  def test_fields_for_without_object
    fields_for(:post) do |f|
1030 1031 1032
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1033 1034
    end

1035
    expected =
1036 1037
      "<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>" +
1038 1039
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1040

1041
    assert_dom_equal expected, output_buffer
1042 1043 1044 1045
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
1046 1047 1048
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1049 1050
    end

1051
    expected =
1052 1053
      "<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>" +
1054 1055
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1056

1057
    assert_dom_equal expected, output_buffer
1058 1059
  end

1060 1061
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
1062 1063
      concat f.label(:title)
      concat f.text_field(:title)
1064 1065
    end

1066 1067
    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' />",
1068
      output_buffer
1069 1070
  end

1071 1072
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
1073 1074
      concat f.label(:title)
      concat f.text_field(:title)
1075 1076 1077 1078
    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' />",
1079
      output_buffer
1080 1081
  end

1082 1083 1084
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
1085

1086
  def test_form_for_and_fields_for
1087
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1088 1089
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1090

1091
      fields_for(:parent_post, @post) do |parent_fields|
1092
        concat parent_fields.check_box(:secret)
1093 1094 1095
      end
    end

1096
    expected =
1097
      "<form action='http://www.example.com' id='create-post' method='post'>" +
1098 1099 1100
      "<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' />" +
1101
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
1102 1103
      "</form>"

1104
    assert_dom_equal expected, output_buffer
1105
  end
1106

1107 1108
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1109 1110
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1111 1112

      post_form.fields_for(@comment) do |comment_fields|
1113
        concat comment_fields.text_field(:name)
1114 1115 1116
      end
    end

1117
    expected =
1118 1119 1120 1121 1122 1123
      "<form action='http://www.example.com' id='create-post' method='post'>" +
      "<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' />" +
      "</form>"

1124
    assert_dom_equal expected, output_buffer
1125 1126
  end

1127
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1128 1129 1130
    (field_helpers - %w(hidden_field)).each do |selector|
      src = <<-END_SRC
        def #{selector}(field, *args, &proc)
1131
          ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
1132 1133 1134 1135 1136
        end
      END_SRC
      class_eval src, __FILE__, __LINE__
    end
  end
1137

1138
  def test_form_for_with_labelled_builder
1139
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1140 1141 1142
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1143 1144
    end

1145
    expected =
1146 1147 1148
      "<form action='http://www.example.com' method='post'>" +
      "<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/>" +
1149
      "<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/>" +
1150 1151
      "</form>"

1152
    assert_dom_equal expected, output_buffer
1153
  end
1154 1155

  def test_default_form_builder
1156 1157
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1158 1159

    form_for(:post, @post) do |f|
1160 1161 1162
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1163 1164
    end

1165
    expected =
1166 1167 1168
      "<form action='http://www.example.com' method='post'>" +
      "<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/>" +
1169
      "<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/>" +
1170 1171
      "</form>"

1172
    assert_dom_equal expected, output_buffer
1173
  ensure
1174
    ActionView.default_form_builder = old_default_form_builder
1175
  end
1176

1177 1178
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1179 1180
       concat f.error_message_on('author_name')
       concat f.error_messages
1181 1182 1183 1184
    end

    expected = %(<form action='http://www.example.com' method='post'>) +
               %(<div class='formError'>can't be empty</div>) +
1185 1186
               %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
               %(</form>)
1187

1188
    assert_dom_equal expected, output_buffer
1189 1190

  end
1191

1192 1193 1194
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1195

1196
    form_for(:post, post) do |f|
1197 1198
       concat f.error_message_on('author_name')
       concat f.error_messages
1199 1200 1201 1202
    end

    expected = %(<form action='http://www.example.com' method='post'>) +
               %(<div class='formError'>can't be empty</div>) +
1203 1204
               %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
               %(</form>)
1205

1206
    assert_dom_equal expected, output_buffer
1207

1208
  end
1209

1210 1211 1212 1213
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1214
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1215 1216 1217
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1218 1219
     end

1220
     expected =
1221
       %(<form action="http://www.example.com" onsubmit="new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;" method="post">) +
1222 1223
       "<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/>" +
1224
       "<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/>" +
1225 1226
       "</form>"

1227
     assert_dom_equal expected, output_buffer
1228
  end
1229

1230
  def test_fields_for_with_labelled_builder
1231
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1232 1233 1234
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1235
    end
1236 1237

    expected =
1238 1239
      "<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/>" +
1240
      "<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/>"
1241

1242
    assert_dom_equal expected, output_buffer
1243
  end
1244

1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285
  def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
    klass = nil

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new) do |nested_fields|
        klass = nested_fields.class
        ''
      end
    end

    assert_equal LabelledFormBuilder, klass
  end

  def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
    klass = nil

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
        klass = nested_fields.class
        ''
      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

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
        klass = nested_fields.class
        ''
      end
    end

    assert_equal LabelledFormBuilderSubclass, klass
  end

1286 1287 1288
  def test_form_for_with_html_options_adds_options_to_form_tag
    form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
    expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\"></form>"
1289

1290
    assert_dom_equal expected, output_buffer
1291
  end
1292

1293 1294 1295
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

1296
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1297 1298 1299 1300 1301 1302 1303 1304
  end

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

    assert_equal 'controller', @controller.url_for_options[:controller]
    assert_equal 'action', @controller.url_for_options[:action]
  end
1305

1306 1307 1308 1309
  def test_form_for_with_record_url_option
    form_for(:post, @post, :url => @post) do |f| end

    expected = "<form action=\"/posts/123\" method=\"post\"></form>"
1310
    assert_equal expected, output_buffer
1311 1312 1313 1314 1315
  end

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

1316
    expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
1317
    assert_equal expected, output_buffer
1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
  end

  def test_form_for_with_new_object
    post = Post.new
    post.new_record = true
    def post.id() nil end

    form_for(post) do |f| end

    expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
1328
    assert_equal expected, output_buffer
1329 1330
  end

1331 1332 1333
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1334

1335 1336
    form_for([@post, @comment]) {}

1337
    expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
1338
    assert_dom_equal expected, output_buffer
1339 1340 1341 1342
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1343

1344 1345 1346
    form_for([@post, @comment]) {}

    expected = %(<form action="#{comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1347
    assert_dom_equal expected, output_buffer
1348 1349
  end

1350 1351 1352
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1353

1354
    form_for([:admin, @post, @comment]) {}
1355

1356
    expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
1357
    assert_dom_equal expected, output_buffer
1358
  end
1359

1360 1361
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1362

1363
    form_for([:admin, @post, @comment]) {}
1364

1365
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1366
    assert_dom_equal expected, output_buffer
1367 1368
  end

1369 1370 1371
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1372
    expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
1373
    assert_equal expected, output_buffer
1374
  end
1375

1376 1377
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1378

1379 1380
    remote_form_for(:post, @post, :html => {:id => 'some_form', :class => 'some_class'}) do |f| end
    expected = "<form action=\"http://www.example.com\" class=\"some_class\" id=\"some_form\" method=\"post\" onsubmit=\"new Ajax.Request('http://www.example.com', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;\"></form>"
1381

1382
    assert_dom_equal expected, output_buffer
1383
  end
1384 1385

  protected
1386 1387 1388
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1389
    alias_method :post_comments_path, :comments_path
1390 1391 1392 1393

    def comment_path(post, comment)
      "/posts/#{post.id}/comments/#{comment.id}"
    end
1394
    alias_method :post_comment_path, :comment_path
1395

1396 1397 1398 1399
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1400

1401 1402 1403 1404
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1405

1406 1407
    def posts_path
      "/posts"
1408 1409
    end

1410 1411
    def post_path(post)
      "/posts/#{post.id}"
1412
    end
1413 1414 1415

    def protect_against_forgery?
      false
1416
    end
1417
end