form_helper_test.rb 51.7 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 614 615
  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

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
616
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636
               '<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

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
637 638 639 640
               '<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" />' +
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659
               '</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" />' +
660 661
               '<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" />' +
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
               '</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" />' +
681 682 683
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<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_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
684 685 686 687 688
               '</form>'

    assert_dom_equal expected, output_buffer
  end

689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
  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_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" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

725 726 727 728 729 730 731 732 733 734 735 736 737 738
  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" />' +
739 740 741
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<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_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
742 743 744 745 746 747
               '</form>'

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

748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
  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_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
               '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809
  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_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<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_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
               '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
               '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
               '<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_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
               '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
               '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
               '<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_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
               '<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" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

810
  def test_fields_for
811
    fields_for(:post, @post) do |f|
812 813 814
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
815 816
    end

817
    expected =
818 819
      "<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>" +
820 821
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
822

823
    assert_dom_equal expected, output_buffer
824 825 826 827
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
828 829 830
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
831 832 833 834 835
    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>" +
836 837
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
838

839
    assert_dom_equal expected, output_buffer
840 841 842 843
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
844 845 846
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
847 848 849 850 851
    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>" +
852 853
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
854

855
    assert_dom_equal expected, output_buffer
856 857 858 859
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
860 861 862
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
863 864 865 866 867
    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>" +
868 869
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
870

871
    assert_dom_equal expected, output_buffer
872
  end
873 874 875

  def test_fields_for_without_object
    fields_for(:post) do |f|
876 877 878
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
879 880
    end

881
    expected =
882 883
      "<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>" +
884 885
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
886

887
    assert_dom_equal expected, output_buffer
888 889 890 891
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
892 893 894
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
895 896
    end

897
    expected =
898 899
      "<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>" +
900 901
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
902

903
    assert_dom_equal expected, output_buffer
904 905
  end

906 907
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
908 909
      concat f.label(:title)
      concat f.text_field(:title)
910 911
    end

912 913
    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' />",
914
      output_buffer
915 916
  end

917 918
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
919 920
      concat f.label(:title)
      concat f.text_field(:title)
921 922 923 924
    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' />",
925
      output_buffer
926 927
  end

928 929 930
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
931

932
  def test_form_for_and_fields_for
933
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
934 935
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
936

937
      fields_for(:parent_post, @post) do |parent_fields|
938
        concat parent_fields.check_box(:secret)
939 940 941
      end
    end

942
    expected =
943
      "<form action='http://www.example.com' id='create-post' method='post'>" +
944 945 946
      "<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' />" +
947
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
948 949
      "</form>"

950
    assert_dom_equal expected, output_buffer
951
  end
952

953 954
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
955 956
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
957 958

      post_form.fields_for(@comment) do |comment_fields|
959
        concat comment_fields.text_field(:name)
960 961 962
      end
    end

963
    expected =
964 965 966 967 968 969
      "<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>"

970
    assert_dom_equal expected, output_buffer
971 972
  end

973
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
974 975 976
    (field_helpers - %w(hidden_field)).each do |selector|
      src = <<-END_SRC
        def #{selector}(field, *args, &proc)
977
          ("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
978 979 980 981 982
        end
      END_SRC
      class_eval src, __FILE__, __LINE__
    end
  end
983

984
  def test_form_for_with_labelled_builder
985
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
986 987 988
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
989 990
    end

991
    expected =
992 993 994
      "<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/>" +
995
      "<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/>" +
996 997
      "</form>"

998
    assert_dom_equal expected, output_buffer
999
  end
1000 1001

  def test_default_form_builder
1002 1003
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1004 1005

    form_for(:post, @post) do |f|
1006 1007 1008
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1009 1010
    end

1011
    expected =
1012 1013 1014
      "<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/>" +
1015
      "<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/>" +
1016 1017
      "</form>"

1018
    assert_dom_equal expected, output_buffer
1019
  ensure
1020
    ActionView.default_form_builder = old_default_form_builder
1021
  end
1022

1023 1024
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1025 1026
       concat f.error_message_on('author_name')
       concat f.error_messages
1027 1028 1029 1030
    end

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

1034
    assert_dom_equal expected, output_buffer
1035 1036

  end
1037

1038 1039 1040
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1041

1042
    form_for(:post, post) do |f|
1043 1044
       concat f.error_message_on('author_name')
       concat f.error_messages
1045 1046 1047 1048
    end

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

1052
    assert_dom_equal expected, output_buffer
1053

1054
  end
1055

1056 1057 1058 1059
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1060
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1061 1062 1063
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1064 1065
     end

1066
     expected =
1067
       %(<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">) +
1068 1069
       "<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/>" +
1070
       "<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/>" +
1071 1072
       "</form>"

1073
     assert_dom_equal expected, output_buffer
1074
  end
1075

1076
  def test_fields_for_with_labelled_builder
1077
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1078 1079 1080
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1081
    end
1082 1083

    expected =
1084 1085
      "<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/>" +
1086
      "<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/>"
1087

1088
    assert_dom_equal expected, output_buffer
1089
  end
1090

1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131
  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

1132 1133 1134
  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>"
1135

1136
    assert_dom_equal expected, output_buffer
1137
  end
1138

1139 1140 1141
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

1142
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1143 1144 1145 1146 1147 1148 1149 1150
  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
1151

1152 1153 1154 1155
  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>"
1156
    assert_equal expected, output_buffer
1157 1158 1159 1160 1161
  end

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

1162
    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>"
1163
    assert_equal expected, output_buffer
1164 1165 1166 1167 1168 1169 1170 1171 1172 1173
  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>"
1174
    assert_equal expected, output_buffer
1175 1176
  end

1177 1178 1179
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1180

1181 1182
    form_for([@post, @comment]) {}

1183
    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>)
1184
    assert_dom_equal expected, output_buffer
1185 1186 1187 1188
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1189

1190 1191 1192
    form_for([@post, @comment]) {}

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

1196 1197 1198
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1199

1200
    form_for([:admin, @post, @comment]) {}
1201

1202
    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>)
1203
    assert_dom_equal expected, output_buffer
1204
  end
1205

1206 1207
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1208

1209
    form_for([:admin, @post, @comment]) {}
1210

1211
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1212
    assert_dom_equal expected, output_buffer
1213 1214
  end

1215 1216 1217
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1218
    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>"
1219
    assert_equal expected, output_buffer
1220
  end
1221

1222 1223
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1224

1225 1226
    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>"
1227

1228
    assert_dom_equal expected, output_buffer
1229
  end
1230 1231

  protected
1232 1233 1234
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1235
    alias_method :post_comments_path, :comments_path
1236 1237 1238 1239

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

1242 1243 1244 1245
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1246

1247 1248 1249 1250
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1251

1252 1253
    def posts_path
      "/posts"
1254 1255
    end

1256 1257
    def post_path(post)
      "/posts/#{post.id}"
1258
    end
1259 1260 1261

    def protect_against_forgery?
      false
1262
    end
1263
end