form_helper_test.rb 57.4 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

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

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

245 246
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
247
    assert_dom_equal(
248
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
249 250 251
      check_box("post", "secret", {}, "on", "off")
    )
  end
252

253 254 255 256 257 258 259 260 261 262 263 264 265
  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


266 267
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
268
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
269 270 271 272
      check_box("post", "secret", { :disabled => :true })
    )
  end

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

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

291 292 293 294 295
  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
296

297 298 299 300 301 302 303 304 305 306
  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 已提交
307
  def test_text_area
308
    assert_dom_equal(
309
      '<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 已提交
310 311 312
      text_area("post", "body")
    )
  end
313

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

322 323 324 325 326 327
  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
328

329 330 331 332 333 334 335 336
  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

337 338 339 340 341 342
  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
343

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

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

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

  def test_form_for
411
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
412 413 414 415 416
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
417 418
    end

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

429
    assert_dom_equal expected, output_buffer
430 431 432 433
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
434 435 436
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
437 438
    end

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

448
    assert_dom_equal expected, output_buffer
449 450
  end

451
  def test_form_for_without_object
452
    form_for(:post, :html => { :id => 'create-post' }) do |f|
453 454 455
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
456 457
    end

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

466
    assert_dom_equal expected, output_buffer
467
  end
468

469 470
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
471 472 473 474
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
475
    end
476

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

486
    assert_dom_equal expected, output_buffer
487 488
  end

489 490
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
491 492 493
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
494 495 496 497 498 499 500
    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' />" +
501
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
502 503
      "</form>"

504
    assert_dom_equal expected, output_buffer
505 506
  end

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 537 538 539 540 541
  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|
542
      concat f.submit :class => "extra"
543 544 545
    end

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

553 554 555
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
556
        concat c.text_field(:title)
557 558 559 560 561 562 563
      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>"

564
    assert_dom_equal expected, output_buffer
565
  end
566

567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582
  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

583
  def test_nested_fields_for_with_index_and_parent_fields
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
    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

599
  def test_form_for_with_index_and_nested_fields_for
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 636 637 638 639 640
    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

641 642 643 644 645 646 647 648 649 650 651 652 653 654
  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

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 687 688 689 690 691
  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

692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709
  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

710 711 712 713 714 715 716 717 718
  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

719 720 721 722 723 724 725 726 727 728
  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

729 730 731 732 733 734 735 736
    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
737

738 739 740 741 742 743 744 745 746 747
  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
748

749 750
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
751
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769
               '<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

770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792
    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
793

794 795
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
796 797 798 799
               '<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" />' +
800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818
               '</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" />' +
819 820
               '<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" />' +
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
               '</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" />' +
840
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
841
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
842
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
843 844 845 846 847
               '</form>'

    assert_dom_equal expected, output_buffer
  end

848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875
  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" />' +
876
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
877
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
878
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
879 880 881 882 883
               '</form>'

    assert_dom_equal expected, output_buffer
  end

884 885 886 887 888 889 890 891 892 893 894 895 896 897
  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" />' +
898
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
899
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
900
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
901 902 903 904 905 906
               '</form>'

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

907 908 909 910 911 912 913 914 915 916 917
  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" />' +
918
               '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
919 920 921 922 923
               '</form>'

    assert_dom_equal expected, output_buffer
  end

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 949 950 951 952 953
  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" />' +
954 955
               '<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" />' +
956 957
               '<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" />' +
958 959
               '<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" />' +
960 961
               '<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" />' +
962 963
               '<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" />' +
964 965 966 967 968
               '</form>'

    assert_dom_equal expected, output_buffer
  end

969
  def test_fields_for
970
    fields_for(:post, @post) do |f|
971 972 973
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
974 975
    end

976
    expected =
977 978
      "<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>" +
979 980
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
981

982
    assert_dom_equal expected, output_buffer
983 984 985 986
  end

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

998
    assert_dom_equal expected, output_buffer
999 1000 1001 1002
  end

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

1014
    assert_dom_equal expected, output_buffer
1015 1016 1017 1018
  end

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

1030
    assert_dom_equal expected, output_buffer
1031
  end
1032 1033 1034

  def test_fields_for_without_object
    fields_for(:post) do |f|
1035 1036 1037
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1038 1039
    end

1040
    expected =
1041 1042
      "<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>" +
1043 1044
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1045

1046
    assert_dom_equal expected, output_buffer
1047 1048 1049 1050
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
1051 1052 1053
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1054 1055
    end

1056
    expected =
1057 1058
      "<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>" +
1059 1060
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1061

1062
    assert_dom_equal expected, output_buffer
1063 1064
  end

1065 1066
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
1067 1068
      concat f.label(:title)
      concat f.text_field(:title)
1069 1070
    end

1071 1072
    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' />",
1073
      output_buffer
1074 1075
  end

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

1087 1088 1089
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
1090

1091
  def test_form_for_and_fields_for
1092
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1093 1094
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1095

1096
      fields_for(:parent_post, @post) do |parent_fields|
1097
        concat parent_fields.check_box(:secret)
1098 1099 1100
      end
    end

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

1109
    assert_dom_equal expected, output_buffer
1110
  end
1111

1112 1113
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1114 1115
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1116 1117

      post_form.fields_for(@comment) do |comment_fields|
1118
        concat comment_fields.text_field(:name)
1119 1120 1121
      end
    end

1122
    expected =
1123 1124 1125 1126 1127 1128
      "<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>"

1129
    assert_dom_equal expected, output_buffer
1130 1131
  end

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

1143
  def test_form_for_with_labelled_builder
1144
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1145 1146 1147
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1148 1149
    end

1150
    expected =
1151 1152 1153
      "<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/>" +
1154
      "<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/>" +
1155 1156
      "</form>"

1157
    assert_dom_equal expected, output_buffer
1158
  end
1159 1160

  def test_default_form_builder
1161 1162
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1163 1164

    form_for(:post, @post) do |f|
1165 1166 1167
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1168 1169
    end

1170
    expected =
1171 1172 1173
      "<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/>" +
1174
      "<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/>" +
1175 1176
      "</form>"

1177
    assert_dom_equal expected, output_buffer
1178
  ensure
1179
    ActionView.default_form_builder = old_default_form_builder
1180
  end
1181

1182 1183
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1184 1185
       concat f.error_message_on('author_name')
       concat f.error_messages
1186 1187 1188 1189
    end

    expected = %(<form action='http://www.example.com' method='post'>) +
               %(<div class='formError'>can't be empty</div>) +
1190 1191
               %(<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>)
1192

1193
    assert_dom_equal expected, output_buffer
1194 1195

  end
1196

1197 1198 1199
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1200

1201
    form_for(:post, post) do |f|
1202 1203
       concat f.error_message_on('author_name')
       concat f.error_messages
1204 1205 1206 1207
    end

    expected = %(<form action='http://www.example.com' method='post'>) +
               %(<div class='formError'>can't be empty</div>) +
1208 1209
               %(<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>)
1210

1211
    assert_dom_equal expected, output_buffer
1212

1213
  end
1214

1215 1216 1217 1218
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1219
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1220 1221 1222
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1223 1224
     end

1225
     expected =
1226
       %(<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">) +
1227 1228
       "<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/>" +
1229
       "<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/>" +
1230 1231
       "</form>"

1232
     assert_dom_equal expected, output_buffer
1233
  end
1234

1235
  def test_fields_for_with_labelled_builder
1236
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1237 1238 1239
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1240
    end
1241 1242

    expected =
1243 1244
      "<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/>" +
1245
      "<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/>"
1246

1247
    assert_dom_equal expected, output_buffer
1248
  end
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 1286 1287 1288 1289 1290
  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

1291 1292 1293
  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>"
1294

1295
    assert_dom_equal expected, output_buffer
1296
  end
1297

1298 1299 1300
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

1301
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1302 1303 1304 1305 1306 1307 1308 1309
  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
1310

1311 1312 1313 1314
  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>"
1315
    assert_equal expected, output_buffer
1316 1317 1318 1319 1320
  end

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

1321
    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>"
1322
    assert_equal expected, output_buffer
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332
  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>"
1333
    assert_equal expected, output_buffer
1334 1335
  end

1336 1337 1338
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1339

1340 1341
    form_for([@post, @comment]) {}

1342
    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>)
1343
    assert_dom_equal expected, output_buffer
1344 1345 1346 1347
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1348

1349 1350 1351
    form_for([@post, @comment]) {}

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

1355 1356 1357
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1358

1359
    form_for([:admin, @post, @comment]) {}
1360

1361
    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>)
1362
    assert_dom_equal expected, output_buffer
1363
  end
1364

1365 1366
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1367

1368
    form_for([:admin, @post, @comment]) {}
1369

1370
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1371
    assert_dom_equal expected, output_buffer
1372 1373
  end

1374 1375 1376
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1377
    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>"
1378
    assert_equal expected, output_buffer
1379
  end
1380

1381 1382
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1383

1384 1385
    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>"
1386

1387
    assert_dom_equal expected, output_buffer
1388
  end
1389 1390

  protected
1391 1392 1393
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1394
    alias_method :post_comments_path, :comments_path
1395 1396 1397 1398

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

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

1406 1407 1408 1409
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1410

1411 1412
    def posts_path
      "/posts"
1413 1414
    end

1415 1416
    def post_path(post)
      "/posts/#{post.id}"
1417
    end
1418 1419 1420

    def protect_against_forgery?
      false
1421
    end
1422
end