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

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

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

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

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

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

60
    @post.persisted   = true
D
Initial  
David Heinemeier Hansson 已提交
61 62 63 64 65
    @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)
66
  end
67

68 69 70 71 72 73
  def url_for(object)
    @url_for_options = object
    if object.is_a?(Hash)
      "http://www.example.com"
    else
      super
74
    end
D
Initial  
David Heinemeier Hansson 已提交
75 76
  end

77 78 79 80 81 82 83
  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')
    )
84
    assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
85
  end
86

87 88
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
89
    assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
90 91
  end

92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
  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

113 114 115 116 117 118 119 120
  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

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
  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

137 138 139 140 141
  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 已提交
142
  def test_text_field
143
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
144 145
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
146
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
147 148
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
149
    assert_dom_equal(
150
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
151 152 153 154 155
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
156
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
157 158 159 160
      '<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

161 162 163 164 165 166 167 168
  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 已提交
169
  def test_text_field_with_options
170
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
171 172
    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 已提交
173
  end
174

D
Initial  
David Heinemeier Hansson 已提交
175
  def test_text_field_assuming_size
176
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
177 178
    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 已提交
179
  end
180

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

187 188 189 190 191 192 193
  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

194 195 196
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
197 198
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
199 200 201 202 203 204 205 206 207 208 209 210 211
  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

212 213 214 215 216
  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 已提交
217
  def test_check_box
218
    assert_dom_equal(
219
      '<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 已提交
220 221 222
      check_box("post", "secret")
    )
    @post.secret = 0
223
    assert_dom_equal(
224
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
225
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
226
    )
227
    assert_dom_equal(
228
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
229 230
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
231
    @post.secret = true
232
    assert_dom_equal(
233
      '<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 已提交
234 235
      check_box("post", "secret")
    )
236
    assert_dom_equal(
237
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
238 239
      check_box("post", "secret?")
    )
240 241 242

    @post.secret = ['0']
    assert_dom_equal(
243
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
244 245 246 247
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
248
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
249 250
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
251
  end
252

253 254
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
255
    assert_dom_equal(
256
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
257 258 259
      check_box("post", "secret", {}, "on", "off")
    )
  end
260

261 262 263 264 265 266 267 268 269 270 271 272 273
  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


274 275
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
276
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
277 278 279 280
      check_box("post", "secret", { :disabled => :true })
    )
  end

281
  def test_radio_button
282
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
283
      radio_button("post", "title", "Hello World")
284
    )
285
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
286
      radio_button("post", "title", "Goodbye World")
287
    )
288 289 290
    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")
    )
291
  end
292

293 294 295 296 297
  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
298

299 300 301 302 303
  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
304

305 306 307 308 309 310 311 312 313 314
  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 已提交
315
  def test_text_area
316
    assert_dom_equal(
317
      '<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 已提交
318 319 320
      text_area("post", "body")
    )
  end
321

D
Initial  
David Heinemeier Hansson 已提交
322 323
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
324
    assert_dom_equal(
325
      '<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 已提交
326 327 328
      text_area("post", "body")
    )
  end
329

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

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

345 346 347 348 349 350
  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
351

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

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

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

  def test_form_for
419
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
420 421 422 423 424
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
425 426
    end

427
    expected =
428
      "<form action='http://www.example.com' id='create-post' method='post'>" +
429
      "<label for='post_title'>Title</label>" +
430 431
      "<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>" +
432
      "<input name='post[secret]' type='hidden' value='0' />" +
433
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
434
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
435 436
      "</form>"

437
    assert_dom_equal expected, output_buffer
438 439 440 441
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
442 443 444
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
445 446
    end

447
    expected =
448
      "<form action='http://www.example.com' id='create-post' method='post'>" +
449
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
450 451
      "<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>" +
452
      "<input name='post[secret]' type='hidden' value='0' />" +
453
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
454 455
      "</form>"

456
    assert_dom_equal expected, output_buffer
457 458
  end

459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477
  def test_form_for_with_remote
    form_for(:post, @post, :remote => true, :html => { :id => 'create-post', :method => :put }) do |f|
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
    end

    expected =
      "<form action='http://www.example.com' id='create-post' method='post' data-remote='true'>" +
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "</form>"

    assert_dom_equal expected, output_buffer
  end

478
  def test_form_for_without_object
479
    form_for(:post, :html => { :id => 'create-post' }) do |f|
480 481 482
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
483 484
    end

485
    expected =
486
      "<form action='http://www.example.com' id='create-post' method='post'>" +
487 488 489
      "<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' />" +
490
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
491 492
      "</form>"

493
    assert_dom_equal expected, output_buffer
494
  end
495

496 497
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
498 499 500 501
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
502
    end
503

504
    expected =
505
      "<form action='http://www.example.com' method='post'>" +
506
      "<label for=\"post_123_title\">Title</label>" +
507 508
      "<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>" +
509
      "<input name='post[123][secret]' type='hidden' value='0' />" +
510
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
511
      "</form>"
512

513
    assert_dom_equal expected, output_buffer
514 515
  end

516 517
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
518 519 520
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
521 522 523 524 525 526 527
    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' />" +
528
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
529 530
      "</form>"

531
    assert_dom_equal expected, output_buffer
532 533
  end

534 535 536
  def test_submit_with_object_as_new_record_and_locale_strings
    old_locale, I18n.locale = I18n.locale, :submit

537
    @post.persisted = false
538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568
    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|
569
      concat f.submit :class => "extra"
570 571 572
    end

    expected = "<form action='http://www.example.com' method='post'>" +
573
               "<input name='commit' class='extra' id='post_submit' type='submit' value='Save changes' />" +
574 575 576 577 578 579
               "</form>"
    assert_dom_equal expected, output_buffer
  ensure
    I18n.locale = old_locale
  end

580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
  def test_submit_with_object_and_nested_lookup
    old_locale, I18n.locale = I18n.locale, :submit

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

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

595 596
  def test_nested_fields_for
    form_for(:post, @post) do |f|
W
wycats 已提交
597
      concat f.fields_for(:comment, @post) { |c|
598
        concat c.text_field(:title)
W
wycats 已提交
599
      }
600 601 602 603 604 605
    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>"

606
    assert_dom_equal expected, output_buffer
607
  end
608

609 610 611
  def test_nested_fields_for_with_nested_collections
    form_for('post[]', @post) do |f|
      concat f.text_field(:title)
W
wycats 已提交
612
      concat f.fields_for('comment[]', @comment) { |c|
613
        concat c.text_field(:name)
W
wycats 已提交
614
      }
615 616 617 618 619 620 621 622 623 624
    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

625
  def test_nested_fields_for_with_index_and_parent_fields
626 627
    form_for('post', @post, :index => 1) do |c|
      concat c.text_field(:title)
W
wycats 已提交
628
      concat c.fields_for('comment', @comment, :index => 1) { |r|
629
        concat r.text_field(:name)
W
wycats 已提交
630
      }
631 632 633 634 635 636 637 638 639 640
    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

641
  def test_form_for_with_index_and_nested_fields_for
W
wycats 已提交
642 643
    output_buffer = form_for(:post, @post, :index => 1) do |f|
      concat f.fields_for(:comment, @post) { |c|
644
        concat c.text_field(:title)
W
wycats 已提交
645
      }
646 647 648 649 650 651 652 653 654 655 656
    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|
W
wycats 已提交
657
      concat f.fields_for(:comment, @post, :index => 5) { |c|
658
        concat c.text_field(:title)
W
wycats 已提交
659
      }
660 661 662 663 664 665 666 667 668 669 670
    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|
W
wycats 已提交
671
      concat f.fields_for(:comment, @post) { |c|
672
        concat c.text_field(:title)
W
wycats 已提交
673
      }
674 675 676 677 678 679 680 681 682
    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

683 684
  def test_nested_fields_for_with_index_radio_button
    form_for(:post, @post) do |f|
W
wycats 已提交
685
      concat f.fields_for(:comment, @post, :index => 5) { |c|
686
        concat c.radio_button(:title, "hello")
W
wycats 已提交
687
      }
688 689 690 691 692 693 694 695 696
    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

697 698
  def test_nested_fields_for_with_auto_index_on_both
    form_for("post[]", @post) do |f|
W
wycats 已提交
699
      concat f.fields_for("comment[]", @post) { |c|
700
        concat c.text_field(:title)
W
wycats 已提交
701
      }
702 703 704 705 706 707 708 709 710 711
    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
W
wycats 已提交
712 713
    output_buffer = form_for("post[]", @post) do |f|
      concat f.fields_for(:comment, @post, :index => 5) { |c|
714
        concat c.text_field(:title)
W
wycats 已提交
715
      }
716 717
    end

W
wycats 已提交
718 719
    output_buffer << form_for(:post, @post, :index => 1) do |f|
      concat f.fields_for("comment[]", @post) { |c|
720
        concat c.text_field(:title)
W
wycats 已提交
721
      }
722 723 724 725 726 727 728 729 730 731 732 733
    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

734 735 736 737 738
  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)
W
wycats 已提交
739
      concat f.fields_for(:author) { |af|
740
        concat af.text_field(:name)
W
wycats 已提交
741
      }
742 743 744 745 746 747 748 749 750 751
    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

752 753 754 755 756 757 758 759 760
  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

761 762 763 764 765
  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)
W
wycats 已提交
766
      concat f.fields_for(:author) { |af|
767
        concat af.text_field(:name)
W
wycats 已提交
768
      }
769 770
    end

771 772 773 774 775 776 777 778
    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
779

780 781 782 783 784
  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)
W
wycats 已提交
785
      concat f.fields_for(:author) { |af|
786 787
        concat af.hidden_field(:id)
        concat af.text_field(:name)
W
wycats 已提交
788
      }
789
    end
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" />' +
793
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
794 795 796 797 798 799 800 801 802 803 804 805
               '<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|
W
wycats 已提交
806
        concat f.fields_for(:comments, comment) { |cf|
807
          concat cf.text_field(:name)
W
wycats 已提交
808
        }
809 810 811
      end
    end

812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828
    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|
W
wycats 已提交
829
        concat f.fields_for(:comments, comment) { |cf|
830 831
          concat cf.hidden_field(:id)
          concat cf.text_field(:name)
W
wycats 已提交
832
        }
833 834
      end
    end
835

836 837
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
838 839 840 841
               '<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" />' +
842 843 844 845 846 847 848 849 850 851 852
               '</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|
W
wycats 已提交
853
        concat f.fields_for(:comments, comment) { |cf|
854
          concat cf.text_field(:name)
W
wycats 已提交
855
        }
856 857 858 859 860
      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" />' +
861 862
               '<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" />' +
863 864 865 866 867 868 869 870 871 872 873
               '</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|
W
wycats 已提交
874
        concat f.fields_for(:comments, comment) { |cf|
875
          concat cf.text_field(:name)
W
wycats 已提交
876
        }
877 878 879 880 881
      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" />' +
882
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
883
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
884
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
885 886 887 888 889
               '</form>'

    assert_dom_equal expected, output_buffer
  end

890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909
  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)
W
wycats 已提交
910
      concat f.fields_for(:comments, @post.comments) { |cf|
911
        concat cf.text_field(:name)
W
wycats 已提交
912
      }
913 914
    end

915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931
    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_supplied_nested_attributes_collection_different_from_record_one
    comments = Array.new(2) { |id| Comment.new(id + 1) }
    @post.comments = []

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
W
wycats 已提交
932
      concat f.fields_for(:comments, comments) { |cf|
933
        concat cf.text_field(:name)
W
wycats 已提交
934
      }
935 936
    end

937 938 939
    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" />' +
940
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
941
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
942
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
943 944 945 946 947
               '</form>'

    assert_dom_equal expected, output_buffer
  end

948 949 950 951 952 953
  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)
W
wycats 已提交
954
      concat f.fields_for(:comments) { |cf|
955 956
        concat cf.text_field(:name)
        yielded_comments << cf.object
W
wycats 已提交
957
      }
958 959 960 961
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
962
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
963
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
964
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
965 966 967 968 969 970
               '</form>'

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

971 972 973 974
  def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
    @post.comments = []

    form_for(:post, @post) do |f|
W
wycats 已提交
975
      concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf|
976
        concat cf.text_field(:name)
W
wycats 已提交
977
      }
978 979 980 981
    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" />' +
982
               '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
983 984 985 986 987
               '</form>'

    assert_dom_equal expected, output_buffer
  end

988 989 990 991 992 993 994
  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|
W
wycats 已提交
995
      concat f.fields_for(:comments, @post.comments[0]) { |cf|
996
        concat cf.text_field(:name)
W
wycats 已提交
997
        concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf|
998
          concat crf.text_field(:value)
W
wycats 已提交
999 1000 1001
        }
      }
      concat f.fields_for(:tags, @post.tags[0]) { |tf|
1002
        concat tf.text_field(:value)
W
wycats 已提交
1003
        concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf|
1004
          concat trf.text_field(:value)
W
wycats 已提交
1005 1006 1007
        }
      }
      concat f.fields_for('tags', @post.tags[1]) { |tf|
1008
        concat tf.text_field(:value)
W
wycats 已提交
1009
        concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf|
1010
          concat trf.text_field(:value)
W
wycats 已提交
1011 1012
        }
      }
1013 1014 1015 1016 1017
    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" />' +
1018 1019
               '<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" />' +
1020 1021
               '<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" />' +
1022 1023
               '<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" />' +
1024 1025
               '<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" />' +
1026 1027
               '<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" />' +
1028 1029 1030 1031 1032
               '</form>'

    assert_dom_equal expected, output_buffer
  end

1033
  def test_fields_for
W
wycats 已提交
1034
    output_buffer = fields_for(:post, @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
  end

  def test_fields_for_with_index
W
wycats 已提交
1050
    output_buffer = fields_for("post[]", @post) do |f|
1051 1052 1053
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1054 1055 1056 1057 1058
    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>" +
1059 1060
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
1061

1062
    assert_dom_equal expected, output_buffer
1063 1064 1065
  end

  def test_fields_for_with_nil_index_option_override
W
wycats 已提交
1066
    output_buffer = fields_for("post[]", @post, :index => nil) do |f|
1067 1068 1069
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1070 1071 1072 1073 1074
    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>" +
1075 1076
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
1077

1078
    assert_dom_equal expected, output_buffer
1079 1080 1081
  end

  def test_fields_for_with_index_option_override
W
wycats 已提交
1082
    output_buffer = fields_for("post[]", @post, :index => "abc") do |f|
1083 1084 1085
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1086 1087 1088 1089 1090
    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>" +
1091 1092
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
1093

1094
    assert_dom_equal expected, output_buffer
1095
  end
1096 1097

  def test_fields_for_without_object
W
wycats 已提交
1098
    output_buffer = fields_for(:post) do |f|
1099 1100 1101
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1102 1103
    end

1104
    expected =
1105 1106
      "<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>" +
1107 1108
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1109

1110
    assert_dom_equal expected, output_buffer
1111 1112 1113
  end

  def test_fields_for_with_only_object
W
wycats 已提交
1114
    output_buffer = fields_for(@post) do |f|
1115 1116 1117
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1118 1119
    end

1120
    expected =
1121 1122
      "<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>" +
1123 1124
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1125

1126
    assert_dom_equal expected, output_buffer
1127 1128
  end

1129
  def test_fields_for_object_with_bracketed_name
W
wycats 已提交
1130
    output_buffer = fields_for("author[post]", @post) do |f|
1131 1132
      concat f.label(:title)
      concat f.text_field(:title)
1133 1134
    end

1135 1136
    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' />",
1137
      output_buffer
1138 1139
  end

1140
  def test_fields_for_object_with_bracketed_name_and_index
W
wycats 已提交
1141
    output_buffer = fields_for("author[post]", @post, :index => 1) do |f|
1142 1143
      concat f.label(:title)
      concat f.text_field(:title)
1144 1145 1146 1147
    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' />",
1148
      output_buffer
1149 1150
  end

1151 1152 1153
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
1154

1155
  def test_form_for_and_fields_for
1156
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1157 1158
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1159

W
wycats 已提交
1160
      concat fields_for(:parent_post, @post) { |parent_fields|
1161
        concat parent_fields.check_box(:secret)
W
wycats 已提交
1162
      }
1163 1164
    end

1165
    expected =
1166
      "<form action='http://www.example.com' id='create-post' method='post'>" +
1167 1168 1169
      "<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' />" +
1170
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
1171 1172
      "</form>"

1173
    assert_dom_equal expected, output_buffer
1174
  end
1175

1176 1177
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1178 1179
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1180

W
wycats 已提交
1181
      concat post_form.fields_for(@comment) { |comment_fields|
1182
        concat comment_fields.text_field(:name)
W
wycats 已提交
1183
      }
1184 1185
    end

1186
    expected =
1187 1188 1189 1190 1191 1192
      "<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>"

1193
    assert_dom_equal expected, output_buffer
1194 1195
  end

1196
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1197 1198 1199
    (field_helpers - %w(hidden_field)).each do |selector|
      src = <<-END_SRC
        def #{selector}(field, *args, &proc)
1200
          ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe
1201 1202 1203 1204 1205
        end
      END_SRC
      class_eval src, __FILE__, __LINE__
    end
  end
1206

1207
  def test_form_for_with_labelled_builder
1208
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1209 1210 1211
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1212 1213
    end

1214
    expected =
1215 1216 1217
      "<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/>" +
1218
      "<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/>" +
1219 1220
      "</form>"

1221
    assert_dom_equal expected, output_buffer
1222
  end
1223 1224

  def test_default_form_builder
1225 1226
    old_default_form_builder, ActionView::Base.default_form_builder =
      ActionView::Base.default_form_builder, LabelledFormBuilder
1227 1228

    form_for(:post, @post) do |f|
1229 1230 1231
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1232 1233
    end

1234
    expected =
1235 1236 1237
      "<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/>" +
1238
      "<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/>" +
1239 1240
      "</form>"

1241
    assert_dom_equal expected, output_buffer
1242
  ensure
1243
    ActionView::Base.default_form_builder = old_default_form_builder
1244
  end
1245

1246 1247
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1248 1249
       concat f.error_message_on('author_name')
       concat f.error_messages
1250 1251 1252 1253
    end

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

1257
    assert_dom_equal expected, output_buffer
1258 1259

  end
1260

1261 1262 1263
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1264

1265
    form_for(:post, post) do |f|
1266 1267
       concat f.error_message_on('author_name')
       concat f.error_messages
1268 1269 1270 1271
    end

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

1275
    assert_dom_equal expected, output_buffer
1276

1277
  end
1278

1279
  def test_fields_for_with_labelled_builder
W
wycats 已提交
1280
    output_buffer = fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1281 1282 1283
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1284
    end
1285 1286

    expected =
1287 1288
      "<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/>" +
1289
      "<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/>"
1290

1291
    assert_dom_equal expected, output_buffer
1292
  end
1293

1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334
  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

1335 1336 1337
  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>"
1338

1339
    assert_dom_equal expected, output_buffer
1340
  end
1341

1342 1343 1344
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

1345
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1346 1347 1348 1349 1350
  end

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

1351 1352
    assert_equal 'controller', @url_for_options[:controller]
    assert_equal 'action', @url_for_options[:action]
1353
  end
1354

1355 1356 1357 1358
  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>"
1359
    assert_equal expected, output_buffer
1360 1361 1362 1363 1364
  end

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

1365
    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>"
1366
    assert_equal expected, output_buffer
1367 1368 1369 1370
  end

  def test_form_for_with_new_object
    post = Post.new
1371
    post.persisted = false
1372 1373 1374 1375 1376
    def post.id() nil end

    form_for(post) do |f| end

    expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
1377
    assert_equal expected, output_buffer
1378 1379
  end

1380 1381 1382 1383
  def test_form_for_with_existing_object_in_list
    @comment.save
    form_for([@post, @comment]) {}

1384
    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>)
1385
    assert_dom_equal expected, output_buffer
1386 1387 1388 1389 1390 1391
  end

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

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

1395 1396 1397
  def test_form_for_with_existing_object_and_namespace_in_list
    @comment.save
    form_for([:admin, @post, @comment]) {}
1398

1399
    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>)
1400
    assert_dom_equal expected, output_buffer
1401
  end
1402

1403 1404
  def test_form_for_with_new_object_and_namespace_in_list
    form_for([:admin, @post, @comment]) {}
1405

1406
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1407
    assert_dom_equal expected, output_buffer
1408 1409
  end

1410 1411 1412
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1413
    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>"
1414
    assert_equal expected, output_buffer
1415
  end
1416

1417
  protected
1418 1419 1420
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1421
    alias_method :post_comments_path, :comments_path
1422 1423 1424 1425

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

1428 1429 1430 1431
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1432

1433 1434 1435 1436
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1437

1438 1439
    def posts_path
      "/posts"
1440 1441
    end

1442 1443
    def post_path(post)
      "/posts/#{post.id}"
1444
    end
1445 1446 1447

    def protect_against_forgery?
      false
1448
    end
1449
end