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

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

14 15 16 17
    def new_record?
      @new_record
    end
  end
18 19 20 21 22 23 24 25 26 27

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

30 31 32
class Comment::Nested < Comment; end


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

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

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

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

67 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')
    )
  end
75

76 77 78 79
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
  end

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

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

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

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

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

133 134 135 136 137 138 139
  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

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
  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 已提交
156
  def test_check_box
157
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
158 159 160 161
      '<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
162
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
163
      '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
164
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
165
    )
166
    assert_dom_equal(
167
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
168 169
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
170
    @post.secret = true
171
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
172 173 174 175
      '<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")
    )
  end
176

177 178
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
179
    assert_dom_equal(
180 181 182 183
      '<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
184

185 186 187 188 189 190 191
  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

192
  def test_radio_button
193
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
194
      radio_button("post", "title", "Hello World")
195
    )
196
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
197
      radio_button("post", "title", "Goodbye World")
198
    )
199 200 201
    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")
    )
202
  end
203

204 205 206 207 208
  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
209

210 211 212 213 214
  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
215

D
Initial  
David Heinemeier Hansson 已提交
216
  def test_text_area
217
    assert_dom_equal(
218
      '<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 已提交
219 220 221
      text_area("post", "body")
    )
  end
222

D
Initial  
David Heinemeier Hansson 已提交
223 224
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
225
    assert_dom_equal(
226
      '<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 已提交
227 228 229
      text_area("post", "body")
    )
  end
230

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

238 239 240 241 242 243 244 245
  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

246 247 248 249 250 251
  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
252

D
Initial  
David Heinemeier Hansson 已提交
253
  def test_explicit_name
254
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
255
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
256
    )
257
    assert_dom_equal(
258
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
259 260
      text_area("post", "body", "name" => "really!")
    )
261
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
262 263 264
      '<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")
    )
265
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
266
                 text_field("post", "title", :name => "dont guess")
267
    assert_dom_equal text_area("post", "body", "name" => "really!"),
268
                 text_area("post", "body", :name => "really!")
269
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
270
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
271
  end
272

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

  def test_auto_index
    pid = @post.id
295 296 297 298
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
299
    assert_dom_equal(
300 301
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
302
    assert_dom_equal(
303
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
304 305
      text_area("post[]", "body")
    )
306
    assert_dom_equal(
307 308 309
      "<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")
    )
310
   assert_dom_equal(
311
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
312 313
      radio_button("post[]", "title", "Hello World")
    )
314
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
315 316 317
      radio_button("post[]", "title", "Goodbye World")
    )
  end
318 319 320 321

  def test_form_for
    _erbout = ''

322
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
323
      _erbout.concat f.label(:title)
324 325 326
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
327
      _erbout.concat f.submit('Create post')
328 329
    end

330
    expected =
331
      "<form action='http://www.example.com' id='create-post' method='post'>" +
332
      "<label for='post_title'>Title</label>" +
333 334
      "<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>" +
335 336
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />" +
337
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
338 339 340 341 342 343 344 345 346 347 348 349 350 351
      "</form>"

    assert_dom_equal expected, _erbout
  end

  def test_form_for_with_method
    _erbout = ''

    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

352
    expected =
353
      "<form action='http://www.example.com' id='create-post' method='post'>" +
354
      "<div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>" +
355 356
      "<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>" +
357 358 359 360 361 362 363
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />" +
      "</form>"

    assert_dom_equal expected, _erbout
  end

364 365 366
  def test_form_for_without_object
    _erbout = ''

367
    form_for(:post, :html => { :id => 'create-post' }) do |f|
368 369 370 371 372
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

373
    expected =
374
      "<form action='http://www.example.com' id='create-post' method='post'>" +
375 376 377 378 379 380 381 382
      "<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>"

    assert_dom_equal expected, _erbout
  end
383

384 385
  def test_form_for_with_index
    _erbout = ''
386

387
    form_for("post[]", @post) do |f|
388
      _erbout.concat f.label(:title)
389 390 391 392
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end
393

394
    expected =
395
      "<form action='http://www.example.com' method='post'>" +
396
      "<label for=\"post_123_title\">Title</label>" +
397 398 399
      "<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' />" +
400 401
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "</form>"
402 403 404 405

    assert_dom_equal expected, _erbout
  end

406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
  def test_form_for_with_nil_index_option_override
    _erbout = ''

    form_for("post[]", @post, :index => nil) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    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>"

    assert_dom_equal expected, _erbout
  end

426 427 428 429 430 431 432 433 434 435 436 437 438
  def test_nested_fields_for
    _erbout = ''
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
        _erbout.concat c.text_field(:title)
      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>"

    assert_dom_equal expected, _erbout
439
  end
440

441 442 443
  def test_fields_for
    _erbout = ''

444
    fields_for(:post, @post) do |f|
445 446 447 448 449
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

450
    expected =
451 452 453 454 455 456
      "<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' />"

    assert_dom_equal expected, _erbout
457 458 459 460 461 462 463 464 465 466 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
  end

  def test_fields_for_with_index
    _erbout = ''

    fields_for("post[]", @post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    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' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_nil_index_option_override
    _erbout = ''

    fields_for("post[]", @post, :index => nil) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    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' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_index_option_override
    _erbout = ''

    fields_for("post[]", @post, :index => "abc") do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    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' />"

    assert_dom_equal expected, _erbout
511
  end
512 513 514 515 516 517 518 519 520

  def test_fields_for_without_object
    _erbout = ''
    fields_for(:post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

521
    expected =
522 523 524
      "<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' />" +
525 526 527 528 529 530 531 532 533 534 535 536 537
      "<input name='post[secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_only_object
    _erbout = ''
    fields_for(@post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

538
    expected =
539 540 541
      "<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' />" +
542 543 544 545 546
      "<input name='post[secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

547 548 549
  def test_fields_for_object_with_bracketed_name
    _erbout = ''
    fields_for("author[post]", @post) do |f|
550
      _erbout.concat f.label(:title)
551 552 553
      _erbout.concat f.text_field(:title)
    end

554 555
    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' />",
556 557 558
      _erbout
  end

559 560 561 562 563 564 565 566 567 568 569 570
  def test_fields_for_object_with_bracketed_name_and_index
    _erbout = ''
    fields_for("author[post]", @post, :index => 1) do |f|
      _erbout.concat f.label(:title)
      _erbout.concat f.text_field(:title)
    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' />",
      _erbout
  end

571 572 573
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
574

575 576 577
  def test_form_for_and_fields_for
    _erbout = ''

578
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
579 580 581
      _erbout.concat post_form.text_field(:title)
      _erbout.concat post_form.text_area(:body)

582
      fields_for(:parent_post, @post) do |parent_fields|
583 584 585 586
        _erbout.concat parent_fields.check_box(:secret)
      end
    end

587
    expected =
588
      "<form action='http://www.example.com' id='create-post' method='post'>" +
589 590 591 592 593 594 595 596
      "<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>"

    assert_dom_equal expected, _erbout
  end
597

598 599 600 601 602 603 604 605 606 607 608 609
  def test_form_for_and_fields_for_with_object
    _erbout = ''

    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
      _erbout.concat post_form.text_field(:title)
      _erbout.concat post_form.text_area(:body)

      post_form.fields_for(@comment) do |comment_fields|
        _erbout.concat comment_fields.text_field(:name)
      end
    end

610
    expected =
611 612 613 614 615 616 617 618 619
      "<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>"

    assert_dom_equal expected, _erbout
  end

620
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
621 622 623 624 625 626 627 628 629
    (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
630

631 632 633
  def test_form_for_with_labelled_builder
    _erbout = ''

634
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
635 636 637 638 639
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

640
    expected =
641 642 643 644 645 646 647 648 649
      "<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>"

    assert_dom_equal expected, _erbout
  end
650 651 652 653 654 655 656 657 658 659 660 661

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

    _erbout = ''
    form_for(:post, @post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

662
    expected =
663 664 665 666 667 668 669 670 671 672 673
      "<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>"

    assert_dom_equal expected, _erbout
  ensure
    ActionView::Base.default_form_builder = old_default_form_builder
  end
674

675
  def test_default_form_builder_with_active_record_helpers
676 677

    _erbout = ''
678 679 680
    form_for(:post, @post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
681 682 683 684
    end

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

688 689 690
    assert_dom_equal expected, _erbout

  end
691

692 693 694
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
695 696

    _erbout = ''
697 698 699
    form_for(:post, post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
700 701 702 703
    end

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

707
    assert_dom_equal expected, _erbout
708

709
  end
710

711 712 713 714 715
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper
     _erbout = ''

716
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
717 718 719 720 721
       _erbout.concat f.text_field(:title)
       _erbout.concat f.text_area(:body)
       _erbout.concat f.check_box(:secret)
     end

722
     expected =
723
       %(<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">) +
724 725 726 727 728 729 730 731
       "<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>"

     assert_dom_equal expected, _erbout
  end
732

733 734
  def test_fields_for_with_labelled_builder
    _erbout = ''
735

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

    expected =
743 744 745 746
      "<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/>"
747

748 749
    assert_dom_equal expected, _erbout
  end
750

751 752
  def test_form_for_with_html_options_adds_options_to_form_tag
    _erbout = ''
753

754 755
    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>"
756

757 758
    assert_dom_equal expected, _erbout
  end
759

760 761 762 763 764
  def test_form_for_with_string_url_option
    _erbout = ''

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

765
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', _erbout
766 767 768 769 770 771 772 773 774 775
  end

  def test_form_for_with_hash_url_option
    _erbout = ''

    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
776

777 778 779 780 781 782
  def test_form_for_with_record_url_option
    _erbout = ''

    form_for(:post, @post, :url => @post) do |f| end

    expected = "<form action=\"/posts/123\" method=\"post\"></form>"
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
    assert_equal expected, _erbout
  end

  def test_form_for_with_existing_object
    _erbout = ''

    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>"
    assert_equal expected, _erbout
  end

  def test_form_for_with_new_object
    _erbout = ''

    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>"
    assert_equal expected, _erbout
  end

808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
    _erbout = ''
    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>)
    assert_dom_equal expected, _erbout
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
    _erbout = ''
    form_for([@post, @comment]) {}

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

827 828 829 830 831
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
832

833 834 835
    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>)
    assert_dom_equal expected, _erbout
  end
836

837 838 839 840
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
841

842 843 844 845
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
    assert_dom_equal expected, _erbout
  end

846 847 848 849 850 851 852
  def test_form_for_with_existing_object_and_custom_url
    _erbout = ''

    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>"
    assert_equal expected, _erbout
853
  end
854

855 856 857
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
    _erbout = ''
858

859 860
    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>"
861

862 863
    assert_dom_equal expected, _erbout
  end
864 865 866


  protected
867 868 869
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
870
    alias_method :post_comments_path, :comments_path
871 872 873 874

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

877 878 879 880
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
881

882 883 884 885
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
886

887 888
    def posts_path
      "/posts"
889 890
    end

891 892
    def post_path(post)
      "/posts/#{post.id}"
893
    end
894 895 896

    def protect_against_forgery?
      false
897
    end
898
end