form_helper_test.rb 33.5 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 107
      '<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

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

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

119 120 121 122 123 124
  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

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

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
  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 已提交
148
  def test_check_box
149
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
150 151 152 153
      '<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
154
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
155
      '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
156
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
157
    )
158
    assert_dom_equal(
159
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
160 161
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
162
    @post.secret = true
163
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
164 165 166 167
      '<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
168

169 170
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
171
    assert_dom_equal(
172 173 174 175
      '<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
176

177 178 179 180 181 182 183
  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

184
  def test_radio_button
185
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
186
      radio_button("post", "title", "Hello World")
187
    )
188
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
189
      radio_button("post", "title", "Goodbye World")
190
    )
191 192 193
    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")
    )
194
  end
195

196 197 198 199 200
  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
201

202 203 204 205 206
  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
207

D
Initial  
David Heinemeier Hansson 已提交
208
  def test_text_area
209
    assert_dom_equal(
210
      '<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 已提交
211 212 213
      text_area("post", "body")
    )
  end
214

D
Initial  
David Heinemeier Hansson 已提交
215 216
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
217
    assert_dom_equal(
218
      '<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 已提交
219 220 221
      text_area("post", "body")
    )
  end
222

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

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

D
Initial  
David Heinemeier Hansson 已提交
237
  def test_explicit_name
238
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
239
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
240
    )
241
    assert_dom_equal(
242
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
243 244
      text_area("post", "body", "name" => "really!")
    )
245
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
246 247 248
      '<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")
    )
249
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
250
                 text_field("post", "title", :name => "dont guess")
251
    assert_dom_equal text_area("post", "body", "name" => "really!"),
252
                 text_area("post", "body", :name => "really!")
253
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
254
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
255
  end
256

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

  def test_auto_index
    pid = @post.id
279 280 281 282
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
283
    assert_dom_equal(
284 285
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
286
    assert_dom_equal(
287
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
288 289
      text_area("post[]", "body")
    )
290
    assert_dom_equal(
291 292 293
      "<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")
    )
294
   assert_dom_equal(
295
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
296 297
      radio_button("post[]", "title", "Hello World")
    )
298
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
299 300 301
      radio_button("post[]", "title", "Goodbye World")
    )
  end
302 303 304 305

  def test_form_for
    _erbout = ''

306
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
307
      _erbout.concat f.label(:title)
308 309 310
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
311
      _erbout.concat f.submit('Create post')
312 313
    end

314
    expected =
315
      "<form action='http://www.example.com' id='create-post' method='post'>" +
316
      "<label for='post_title'>Title</label>" +
317 318
      "<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>" +
319 320
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />" +
321
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
322 323 324 325 326 327 328 329 330 331 332 333 334 335
      "</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

336
    expected =
337
      "<form action='http://www.example.com' id='create-post' method='post'>" +
338
      "<div style='margin:0;padding:0'><input name='_method' type='hidden' value='put' /></div>" +
339 340
      "<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>" +
341 342 343 344 345 346 347
      "<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

348 349 350
  def test_form_for_without_object
    _erbout = ''

351
    form_for(:post, :html => { :id => 'create-post' }) do |f|
352 353 354 355 356
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

357
    expected =
358
      "<form action='http://www.example.com' id='create-post' method='post'>" +
359 360 361 362 363 364 365 366
      "<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
367

368 369
  def test_form_for_with_index
    _erbout = ''
370

371
    form_for("post[]", @post) do |f|
372
      _erbout.concat f.label(:title)
373 374 375 376
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end
377

378
    expected =
379
      "<form action='http://www.example.com' method='post'>" +
380
      "<label for=\"post_123_title\">Title</label>" +
381 382 383
      "<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' />" +
384 385
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "</form>"
386 387 388 389

    assert_dom_equal expected, _erbout
  end

390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
  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

410 411 412 413 414 415 416 417 418 419 420 421 422
  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
423
  end
424

425 426 427
  def test_fields_for
    _erbout = ''

428
    fields_for(:post, @post) do |f|
429 430 431 432 433
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

434
    expected =
435 436 437 438 439 440
      "<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
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 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
  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
495
  end
496 497 498 499 500 501 502 503 504

  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

505
    expected =
506 507 508
      "<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' />" +
509 510 511 512 513 514 515 516 517 518 519 520 521
      "<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

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

    assert_dom_equal expected, _erbout
  end

531 532 533
  def test_fields_for_object_with_bracketed_name
    _erbout = ''
    fields_for("author[post]", @post) do |f|
534
      _erbout.concat f.label(:title)
535 536 537
      _erbout.concat f.text_field(:title)
    end

538 539
    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' />",
540 541 542
      _erbout
  end

543 544 545 546 547 548 549 550 551 552 553 554
  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

555 556 557
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
558

559 560 561
  def test_form_for_and_fields_for
    _erbout = ''

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

566
      fields_for(:parent_post, @post) do |parent_fields|
567 568 569 570
        _erbout.concat parent_fields.check_box(:secret)
      end
    end

571
    expected =
572
      "<form action='http://www.example.com' id='create-post' method='post'>" +
573 574 575 576 577 578 579 580
      "<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
581

582 583 584 585 586 587 588 589 590 591 592 593
  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

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

604
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
605 606 607 608 609 610 611 612 613
    (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
614

615 616 617
  def test_form_for_with_labelled_builder
    _erbout = ''

618
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
619 620 621 622 623
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

624
    expected =
625 626 627 628 629 630 631 632 633
      "<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
634 635 636 637 638 639 640 641 642 643 644 645

  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

646
    expected =
647 648 649 650 651 652 653 654 655 656 657
      "<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
658

659
  def test_default_form_builder_with_active_record_helpers
660 661

    _erbout = ''
662 663 664
    form_for(:post, @post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
665 666 667 668
    end

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

672 673 674
    assert_dom_equal expected, _erbout

  end
675

676 677 678
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
679 680

    _erbout = ''
681 682 683
    form_for(:post, post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
684 685 686 687
    end

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

691
    assert_dom_equal expected, _erbout
692

693
  end
694

695 696 697 698 699
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper
     _erbout = ''

700
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
701 702 703 704 705
       _erbout.concat f.text_field(:title)
       _erbout.concat f.text_area(:body)
       _erbout.concat f.check_box(:secret)
     end

706
     expected =
707
       %(<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">) +
708 709 710 711 712 713 714 715
       "<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
716

717 718
  def test_fields_for_with_labelled_builder
    _erbout = ''
719

720
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
721 722 723 724
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end
725 726

    expected =
727 728 729 730
      "<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/>"
731

732 733
    assert_dom_equal expected, _erbout
  end
734

735 736
  def test_form_for_with_html_options_adds_options_to_form_tag
    _erbout = ''
737

738 739
    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>"
740

741 742
    assert_dom_equal expected, _erbout
  end
743

744 745 746 747 748
  def test_form_for_with_string_url_option
    _erbout = ''

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

749
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', _erbout
750 751 752 753 754 755 756 757 758 759
  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
760

761 762 763 764 765 766
  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>"
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
    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

792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
  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

811 812 813 814 815
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
816

817 818 819
    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
820

821 822 823 824
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
825

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

830 831 832 833 834 835 836
  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
837
  end
838

839 840 841
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
    _erbout = ''
842

843 844
    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>"
845

846 847
    assert_dom_equal expected, _erbout
  end
848 849 850


  protected
851 852 853
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
854
    alias_method :post_comments_path, :comments_path
855 856 857 858

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

861 862 863 864
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
865

866 867 868 869
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
870

871 872
    def posts_path
      "/posts"
873 874
    end

875 876
    def post_path(post)
      "/posts/#{post.id}"
877
    end
878 879 880

    def protect_against_forgery?
      false
881
    end
882
end