form_helper_test.rb 53.8 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
    @post = Post.new
10
    @comment = Comment.new
11 12
    def @post.errors()
      Class.new{
13
        def [](field); field == "author_name" ? ["can't be empty"] : [] end
14
        def empty?() false end
15
        def count() 1 end
16 17
        def full_messages() [ "Author name can't be empty" ] end
      }.new
18
    end
19
    def @post.id; 123; end
20
    def @post.id_before_type_cast; 123; end
21
    def @post.to_param; '123'; end
22

D
Initial  
David Heinemeier Hansson 已提交
23 24 25 26 27
    @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)
28 29

    @controller = Class.new do
30
      attr_reader :url_for_options
31
      def url_for(options)
32
        @url_for_options = options
33 34 35 36
        "http://www.example.com"
      end
    end
    @controller = @controller.new
D
Initial  
David Heinemeier Hansson 已提交
37 38
  end

39 40 41 42 43 44 45
  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')
    )
46
    assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
47
  end
48

49 50
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
51
    assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
52 53
  end

54 55 56 57 58 59 60 61
  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

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
  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

78 79 80 81 82
  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 已提交
83
  def test_text_field
84
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
85 86
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
87
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
88 89
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
90
    assert_dom_equal(
91
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
92 93 94 95 96
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
97
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
98 99 100 101
      '<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

102 103 104 105 106 107 108 109
  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 已提交
110
  def test_text_field_with_options
111
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
112 113
    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 已提交
114
  end
115

D
Initial  
David Heinemeier Hansson 已提交
116
  def test_text_field_assuming_size
117
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
118 119
    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 已提交
120
  end
121

122 123 124 125 126 127
  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

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

135 136 137
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
138 139
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
140 141 142 143 144 145 146 147 148 149 150 151 152
  end

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

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

D
Initial  
David Heinemeier Hansson 已提交
153
  def test_check_box
154
    assert_dom_equal(
155
      '<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 已提交
156 157 158
      check_box("post", "secret")
    )
    @post.secret = 0
159
    assert_dom_equal(
160
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
161
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
162
    )
163
    assert_dom_equal(
164
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
165 166
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
167
    @post.secret = true
168
    assert_dom_equal(
169
      '<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 已提交
170 171
      check_box("post", "secret")
    )
172
    assert_dom_equal(
173
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
174 175
      check_box("post", "secret?")
    )
176 177 178

    @post.secret = ['0']
    assert_dom_equal(
179
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
180 181 182 183
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
184
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
185 186
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
187
  end
188

189 190
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
191
    assert_dom_equal(
192
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
193 194 195
      check_box("post", "secret", {}, "on", "off")
    )
  end
196

197 198
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
199
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
200 201 202 203
      check_box("post", "secret", { :disabled => :true })
    )
  end

204
  def test_radio_button
205
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
206
      radio_button("post", "title", "Hello World")
207
    )
208
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
209
      radio_button("post", "title", "Goodbye World")
210
    )
211 212 213
    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")
    )
214
  end
215

216 217 218 219 220
  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
221

222 223 224 225 226
  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
227

228 229 230 231 232 233 234 235 236 237
  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 已提交
238
  def test_text_area
239
    assert_dom_equal(
240
      '<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 已提交
241 242 243
      text_area("post", "body")
    )
  end
244

D
Initial  
David Heinemeier Hansson 已提交
245 246
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
247
    assert_dom_equal(
248
      '<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 已提交
249 250 251
      text_area("post", "body")
    )
  end
252

253 254 255 256 257 258
  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
259

260 261 262 263 264 265 266 267
  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

268 269 270 271 272 273
  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
274

D
Initial  
David Heinemeier Hansson 已提交
275
  def test_explicit_name
276
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
277
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
278
    )
279
    assert_dom_equal(
280
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
281 282
      text_area("post", "body", "name" => "really!")
    )
283
    assert_dom_equal(
284
      '<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 已提交
285 286
      check_box("post", "secret", "name" => "i mean it")
    )
287
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
288
                 text_field("post", "title", :name => "dont guess")
289
    assert_dom_equal text_area("post", "body", "name" => "really!"),
290
                 text_area("post", "body", :name => "really!")
291
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
292
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
293
  end
294

D
Initial  
David Heinemeier Hansson 已提交
295
  def test_explicit_id
296
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
297
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
298
    )
299
    assert_dom_equal(
300
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
301 302
      text_area("post", "body", "id" => "really!")
    )
303
    assert_dom_equal(
304
      '<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 已提交
305 306
      check_box("post", "secret", "id" => "i mean it")
    )
307
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
308
                 text_field("post", "title", :id => "dont guess")
309
    assert_dom_equal text_area("post", "body", "id" => "really!"),
310
                 text_area("post", "body", :id => "really!")
311
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
312
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
313
  end
314 315 316

  def test_auto_index
    pid = @post.id
317 318 319 320
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
321
    assert_dom_equal(
322 323
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
324
    assert_dom_equal(
325
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
326 327
      text_area("post[]", "body")
    )
328
    assert_dom_equal(
329
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
330 331
      check_box("post[]", "secret")
    )
332
   assert_dom_equal(
333
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
334 335
      radio_button("post[]", "title", "Hello World")
    )
336
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
337 338 339
      radio_button("post[]", "title", "Goodbye World")
    )
  end
340 341

  def test_form_for
342
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
343 344 345 346 347
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
348 349
    end

350
    expected =
351
      "<form action='http://www.example.com' id='create-post' method='post'>" +
352
      "<label for='post_title'>Title</label>" +
353 354
      "<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>" +
355
      "<input name='post[secret]' type='hidden' value='0' />" +
356
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
357
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
358 359
      "</form>"

360
    assert_dom_equal expected, output_buffer
361 362 363 364
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
365 366 367
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
368 369
    end

370
    expected =
371
      "<form action='http://www.example.com' id='create-post' method='post'>" +
372
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
373 374
      "<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>" +
375
      "<input name='post[secret]' type='hidden' value='0' />" +
376
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
377 378
      "</form>"

379
    assert_dom_equal expected, output_buffer
380 381
  end

382
  def test_form_for_without_object
383
    form_for(:post, :html => { :id => 'create-post' }) do |f|
384 385 386
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
387 388
    end

389
    expected =
390
      "<form action='http://www.example.com' id='create-post' method='post'>" +
391 392 393
      "<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' />" +
394
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
395 396
      "</form>"

397
    assert_dom_equal expected, output_buffer
398
  end
399

400 401
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
402 403 404 405
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
406
    end
407

408
    expected =
409
      "<form action='http://www.example.com' method='post'>" +
410
      "<label for=\"post_123_title\">Title</label>" +
411 412
      "<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>" +
413
      "<input name='post[123][secret]' type='hidden' value='0' />" +
414
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
415
      "</form>"
416

417
    assert_dom_equal expected, output_buffer
418 419
  end

420 421
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
422 423 424
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
425 426 427 428 429 430 431
    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' />" +
432
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
433 434
      "</form>"

435
    assert_dom_equal expected, output_buffer
436 437
  end

438 439 440
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
441
        concat c.text_field(:title)
442 443 444 445 446 447 448
      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>"

449
    assert_dom_equal expected, output_buffer
450
  end
451

452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
  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

468
  def test_nested_fields_for_with_index_and_parent_fields
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483
    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

484
  def test_form_for_with_index_and_nested_fields_for
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
    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

526 527 528 529 530 531 532 533 534 535 536 537 538 539
  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

540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576
  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

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
  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

595 596 597 598 599 600 601 602 603
  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

604 605 606 607 608 609 610 611 612 613
  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

614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633
    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
  
  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
    
634 635
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
636
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654
               '<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

655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678
    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
    
679 680
    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
681 682 683 684
               '<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" />' +
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
               '</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" />' +
704 705
               '<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" />' +
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
               '</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" />' +
725
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
726
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
727
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
728 729 730 731 732
               '</form>'

    assert_dom_equal expected, output_buffer
  end

733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760
  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" />' +
761
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
762
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
763
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
764 765 766 767 768
               '</form>'

    assert_dom_equal expected, output_buffer
  end

769 770 771 772 773 774 775 776 777 778 779 780 781 782
  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" />' +
783
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
784
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
785
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
786 787 788 789 790 791
               '</form>'

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

792 793 794 795 796 797 798 799 800 801 802
  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" />' +
803
               '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
804 805 806 807 808
               '</form>'

    assert_dom_equal expected, output_buffer
  end

809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
  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" />' +
839 840
               '<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" />' +
841 842
               '<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" />' +
843 844
               '<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" />' +
845 846
               '<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" />' +
847 848
               '<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" />' +
849 850 851 852 853
               '</form>'

    assert_dom_equal expected, output_buffer
  end

854
  def test_fields_for
855
    fields_for(:post, @post) do |f|
856 857 858
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
859 860
    end

861
    expected =
862 863
      "<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>" +
864 865
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
866

867
    assert_dom_equal expected, output_buffer
868 869 870 871
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
872 873 874
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
875 876 877 878 879
    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>" +
880 881
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
882

883
    assert_dom_equal expected, output_buffer
884 885 886 887
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
888 889 890
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
891 892 893 894 895
    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>" +
896 897
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
898

899
    assert_dom_equal expected, output_buffer
900 901 902 903
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
904 905 906
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
907 908 909 910 911
    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>" +
912 913
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
914

915
    assert_dom_equal expected, output_buffer
916
  end
917 918 919

  def test_fields_for_without_object
    fields_for(:post) do |f|
920 921 922
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
923 924
    end

925
    expected =
926 927
      "<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>" +
928 929
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
930

931
    assert_dom_equal expected, output_buffer
932 933 934 935
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
936 937 938
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
939 940
    end

941
    expected =
942 943
      "<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>" +
944 945
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
946

947
    assert_dom_equal expected, output_buffer
948 949
  end

950 951
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
952 953
      concat f.label(:title)
      concat f.text_field(:title)
954 955
    end

956 957
    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' />",
958
      output_buffer
959 960
  end

961 962
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
963 964
      concat f.label(:title)
      concat f.text_field(:title)
965 966 967 968
    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' />",
969
      output_buffer
970 971
  end

972 973 974
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
975

976
  def test_form_for_and_fields_for
977
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
978 979
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
980

981
      fields_for(:parent_post, @post) do |parent_fields|
982
        concat parent_fields.check_box(:secret)
983 984 985
      end
    end

986
    expected =
987
      "<form action='http://www.example.com' id='create-post' method='post'>" +
988 989 990
      "<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' />" +
991
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
992 993
      "</form>"

994
    assert_dom_equal expected, output_buffer
995
  end
996

997 998
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
999 1000
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1001 1002

      post_form.fields_for(@comment) do |comment_fields|
1003
        concat comment_fields.text_field(:name)
1004 1005 1006
      end
    end

1007
    expected =
1008 1009 1010 1011 1012 1013
      "<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>"

1014
    assert_dom_equal expected, output_buffer
1015 1016
  end

1017
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1018 1019 1020
    (field_helpers - %w(hidden_field)).each do |selector|
      src = <<-END_SRC
        def #{selector}(field, *args, &proc)
1021
          ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
1022 1023 1024 1025 1026
        end
      END_SRC
      class_eval src, __FILE__, __LINE__
    end
  end
1027

1028
  def test_form_for_with_labelled_builder
1029
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1030 1031 1032
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1033 1034
    end

1035
    expected =
1036 1037 1038
      "<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/>" +
1039
      "<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/>" +
1040 1041
      "</form>"

1042
    assert_dom_equal expected, output_buffer
1043
  end
1044 1045

  def test_default_form_builder
1046 1047
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1048 1049

    form_for(:post, @post) do |f|
1050 1051 1052
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1053 1054
    end

1055
    expected =
1056 1057 1058
      "<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/>" +
1059
      "<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/>" +
1060 1061
      "</form>"

1062
    assert_dom_equal expected, output_buffer
1063
  ensure
1064
    ActionView.default_form_builder = old_default_form_builder
1065
  end
1066

1067 1068
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1069 1070
       concat f.error_message_on('author_name')
       concat f.error_messages
1071 1072 1073 1074
    end

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

1078
    assert_dom_equal expected, output_buffer
1079 1080

  end
1081

1082 1083 1084
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1085

1086
    form_for(:post, post) do |f|
1087 1088
       concat f.error_message_on('author_name')
       concat f.error_messages
1089 1090 1091 1092
    end

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

1096
    assert_dom_equal expected, output_buffer
1097

1098
  end
1099

1100 1101 1102 1103
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1104
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1105 1106 1107
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1108 1109
     end

1110
     expected =
1111
       %(<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">) +
1112 1113
       "<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/>" +
1114
       "<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/>" +
1115 1116
       "</form>"

1117
     assert_dom_equal expected, output_buffer
1118
  end
1119

1120
  def test_fields_for_with_labelled_builder
1121
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1122 1123 1124
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1125
    end
1126 1127

    expected =
1128 1129
      "<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/>" +
1130
      "<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/>"
1131

1132
    assert_dom_equal expected, output_buffer
1133
  end
1134

1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175
  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

1176 1177 1178
  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>"
1179

1180
    assert_dom_equal expected, output_buffer
1181
  end
1182

1183 1184 1185
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

1186
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1187 1188 1189 1190 1191 1192 1193 1194
  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
1195

1196 1197 1198 1199
  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>"
1200
    assert_equal expected, output_buffer
1201 1202 1203 1204 1205
  end

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

1206
    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>"
1207
    assert_equal expected, output_buffer
1208 1209 1210 1211 1212 1213 1214 1215 1216 1217
  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>"
1218
    assert_equal expected, output_buffer
1219 1220
  end

1221 1222 1223
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1224

1225 1226
    form_for([@post, @comment]) {}

1227
    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>)
1228
    assert_dom_equal expected, output_buffer
1229 1230 1231 1232
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1233

1234 1235 1236
    form_for([@post, @comment]) {}

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

1240 1241 1242
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1243

1244
    form_for([:admin, @post, @comment]) {}
1245

1246
    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>)
1247
    assert_dom_equal expected, output_buffer
1248
  end
1249

1250 1251
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1252

1253
    form_for([:admin, @post, @comment]) {}
1254

1255
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1256
    assert_dom_equal expected, output_buffer
1257 1258
  end

1259 1260 1261
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1262
    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>"
1263
    assert_equal expected, output_buffer
1264
  end
1265

1266 1267
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1268

1269 1270
    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>"
1271

1272
    assert_dom_equal expected, output_buffer
1273
  end
1274 1275

  protected
1276 1277 1278
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1279
    alias_method :post_comments_path, :comments_path
1280 1281 1282 1283

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

1286 1287 1288 1289
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1290

1291 1292 1293 1294
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1295

1296 1297
    def posts_path
      "/posts"
1298 1299
    end

1300 1301
    def post_path(post)
      "/posts/#{post.id}"
1302
    end
1303 1304 1305

    def protect_against_forgery?
      false
1306
    end
1307
end