form_helper_test.rb 38.2 KB
Newer Older
1
require 'abstract_unit'
D
Initial  
David Heinemeier Hansson 已提交
2

3 4 5 6 7 8
silence_warnings do
  Post = Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
  Post.class_eval do
    alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
    alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
    alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
9
    alias_method :secret?, :secret
10

11 12 13
    def new_record=(boolean)
      @new_record = boolean
    end
14

15 16 17 18
    def new_record?
      @new_record
    end
  end
19 20 21 22 23 24

  class Comment
    attr_reader :id
    attr_reader :post_id
    def save; @id = 1; @post_id = 1 end
    def new_record?; @id.nil? end
25
    def to_param; @id; end
26 27 28 29
    def name
      @id.nil? ? 'new comment' : "comment ##{@id}"
    end
  end
30 31
end

32 33
class Comment::Nested < Comment; end

34 35
class FormHelperTest < ActionView::TestCase
  tests ActionView::Helpers::FormHelper
D
Initial  
David Heinemeier Hansson 已提交
36 37

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

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

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

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

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

83 84 85 86 87 88 89 90
  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

D
Initial  
David Heinemeier Hansson 已提交
91
  def test_text_field
92
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
93 94
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
95
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
96 97
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
98
    assert_dom_equal(
99
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
100 101 102 103 104
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
105
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
106 107 108 109
      '<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

110 111 112 113 114 115 116 117
  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 已提交
118
  def test_text_field_with_options
119
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
120 121
    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 已提交
122
  end
123

D
Initial  
David Heinemeier Hansson 已提交
124
  def test_text_field_assuming_size
125
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
126 127
    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 已提交
128
  end
129

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

136 137 138 139 140 141 142
  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

143 144 145
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
146 147
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
148 149 150 151 152 153 154 155 156 157 158 159 160
  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 已提交
161
  def test_check_box
162
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
163 164 165 166
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
    @post.secret = 0
167
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
168
      '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
169
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
170
    )
171
    assert_dom_equal(
172
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
173 174
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
175
    @post.secret = true
176
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
177 178 179
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
180 181 182 183
    assert_dom_equal(
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret?")
    )
184 185 186 187 188 189 190 191 192 193 194

    @post.secret = ['0']
    assert_dom_equal(
      '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
195
  end
196

197 198
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
199
    assert_dom_equal(
200 201 202 203
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" /><input name="post[secret]" type="hidden" value="off" />',
      check_box("post", "secret", {}, "on", "off")
    )
  end
204

205 206 207 208 209 210 211
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
      '<input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="1" />',
      check_box("post", "secret", { :disabled => :true })
    )
  end

212
  def test_radio_button
213
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
214
      radio_button("post", "title", "Hello World")
215
    )
216
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
217
      radio_button("post", "title", "Goodbye World")
218
    )
219 220 221
    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")
    )
222
  end
223

224 225 226 227 228
  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
229

230 231 232 233 234
  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
235

D
Initial  
David Heinemeier Hansson 已提交
236
  def test_text_area
237
    assert_dom_equal(
238
      '<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 已提交
239 240 241
      text_area("post", "body")
    )
  end
242

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

251 252 253 254 255 256
  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
257

258 259 260 261 262 263 264 265
  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

266 267 268 269 270 271
  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
272

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

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

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

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

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

358
    assert_dom_equal expected, output_buffer
359 360 361 362
  end

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

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

377
    assert_dom_equal expected, output_buffer
378 379
  end

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

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

395
    assert_dom_equal expected, output_buffer
396
  end
397

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

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

415
    assert_dom_equal expected, output_buffer
416 417
  end

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

433
    assert_dom_equal expected, output_buffer
434 435
  end

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

447
    assert_dom_equal expected, output_buffer
448
  end
449

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

466
  def test_nested_fields_for_with_index_and_parent_fields
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 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 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
    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

  def test_nested_fields_for_with_index
    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

  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

561
  def test_fields_for
562
    fields_for(:post, @post) do |f|
563 564 565
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
566 567
    end

568
    expected =
569 570 571 572 573
      "<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]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />"

574
    assert_dom_equal expected, output_buffer
575 576 577 578
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
579 580 581
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
582 583 584 585 586 587 588 589
    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>" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
      "<input name='post[123][secret]' type='hidden' value='0' />"

590
    assert_dom_equal expected, output_buffer
591 592 593 594
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
595 596 597
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
598 599 600 601 602 603 604 605
    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>" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
      "<input name='post[][secret]' type='hidden' value='0' />"

606
    assert_dom_equal expected, output_buffer
607 608 609 610
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
611 612 613
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
614 615 616 617 618 619 620 621
    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>" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />" +
      "<input name='post[abc][secret]' type='hidden' value='0' />"

622
    assert_dom_equal expected, output_buffer
623
  end
624 625 626

  def test_fields_for_without_object
    fields_for(:post) do |f|
627 628 629
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
630 631
    end

632
    expected =
633 634 635
      "<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]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
636 637
      "<input name='post[secret]' type='hidden' value='0' />"

638
    assert_dom_equal expected, output_buffer
639 640 641 642
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
643 644 645
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
646 647
    end

648
    expected =
649 650 651
      "<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]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
652 653
      "<input name='post[secret]' type='hidden' value='0' />"

654
    assert_dom_equal expected, output_buffer
655 656
  end

657 658
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
659 660
      concat f.label(:title)
      concat f.text_field(:title)
661 662
    end

663 664
    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' />",
665
      output_buffer
666 667
  end

668 669
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
670 671
      concat f.label(:title)
      concat f.text_field(:title)
672 673 674 675
    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' />",
676
      output_buffer
677 678
  end

679 680 681
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
682

683
  def test_form_for_and_fields_for
684
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
685 686
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
687

688
      fields_for(:parent_post, @post) do |parent_fields|
689
        concat parent_fields.check_box(:secret)
690 691 692
      end
    end

693
    expected =
694
      "<form action='http://www.example.com' id='create-post' method='post'>" +
695 696 697 698 699 700
      "<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]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
      "<input name='parent_post[secret]' type='hidden' value='0' />" +
      "</form>"

701
    assert_dom_equal expected, output_buffer
702
  end
703

704 705
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
706 707
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
708 709

      post_form.fields_for(@comment) do |comment_fields|
710
        concat comment_fields.text_field(:name)
711 712 713
      end
    end

714
    expected =
715 716 717 718 719 720
      "<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>"

721
    assert_dom_equal expected, output_buffer
722 723
  end

724
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
725 726 727 728 729 730 731 732 733
    (field_helpers - %w(hidden_field)).each do |selector|
      src = <<-END_SRC
        def #{selector}(field, *args, &proc)
          "<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>"
        end
      END_SRC
      class_eval src, __FILE__, __LINE__
    end
  end
734

735
  def test_form_for_with_labelled_builder
736
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
737 738 739
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
740 741
    end

742
    expected =
743 744 745 746 747 748 749
      "<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/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>" +
      "</form>"

750
    assert_dom_equal expected, output_buffer
751
  end
752 753 754 755 756 757

  def test_default_form_builder
    old_default_form_builder, ActionView::Base.default_form_builder =
      ActionView::Base.default_form_builder, LabelledFormBuilder

    form_for(:post, @post) do |f|
758 759 760
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
761 762
    end

763
    expected =
764 765 766 767 768 769 770
      "<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/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>" +
      "</form>"

771
    assert_dom_equal expected, output_buffer
772 773 774
  ensure
    ActionView::Base.default_form_builder = old_default_form_builder
  end
775

776 777
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
778 779
       concat f.error_message_on('author_name')
       concat f.error_messages
780 781 782 783
    end

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

787
    assert_dom_equal expected, output_buffer
788 789

  end
790

791 792 793
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
794

795
    form_for(:post, post) do |f|
796 797
       concat f.error_message_on('author_name')
       concat f.error_messages
798 799 800 801
    end

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

805
    assert_dom_equal expected, output_buffer
806

807
  end
808

809 810 811 812
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

813
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
814 815 816
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
817 818
     end

819
     expected =
820
       %(<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">) +
821 822 823 824 825 826
       "<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/>" +
       "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
       "<input name='post[secret]' type='hidden' value='0' /><br/>" +
       "</form>"

827
     assert_dom_equal expected, output_buffer
828
  end
829

830
  def test_fields_for_with_labelled_builder
831
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
832 833 834
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
835
    end
836 837

    expected =
838 839 840 841
      "<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/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>"
842

843
    assert_dom_equal expected, output_buffer
844
  end
845

846 847 848
  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>"
849

850
    assert_dom_equal expected, output_buffer
851
  end
852

853 854 855
  def test_form_for_with_string_url_option
    form_for(:post, @post, :url => 'http://www.otherdomain.com') do |f| end

856
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
857 858 859 860 861 862 863 864
  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
865

866 867 868 869
  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>"
870
    assert_equal expected, output_buffer
871 872 873 874 875 876
  end

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

    expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
877
    assert_equal expected, output_buffer
878 879 880 881 882 883 884 885 886 887
  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>"
888
    assert_equal expected, output_buffer
889 890
  end

891 892 893
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
894

895 896 897
    form_for([@post, @comment]) {}

    expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
898
    assert_dom_equal expected, output_buffer
899 900 901 902
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
903

904 905 906
    form_for([@post, @comment]) {}

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

910 911 912
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
913

914
    form_for([:admin, @post, @comment]) {}
915

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

920 921
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
922

923
    form_for([:admin, @post, @comment]) {}
924

925
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
926
    assert_dom_equal expected, output_buffer
927 928
  end

929 930 931 932
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

    expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
933
    assert_equal expected, output_buffer
934
  end
935

936 937
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
938

939 940
    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>"
941

942
    assert_dom_equal expected, output_buffer
943
  end
944 945

  protected
946 947 948
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
949
    alias_method :post_comments_path, :comments_path
950 951 952 953

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

956 957 958 959
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
960

961 962 963 964
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
965

966 967
    def posts_path
      "/posts"
968 969
    end

970 971
    def post_path(post)
      "/posts/#{post.id}"
972
    end
973 974 975

    def protect_against_forgery?
      false
976
    end
977
end