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

3
silence_warnings do
4
  class Post < Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
J
Joshua Peek 已提交
5 6
    extend ActiveModel::Naming
    include ActiveModel::Conversion
7

8
    alias_method :secret?, :secret
9

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

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

    attr_accessor :author
    def author_attributes=(attributes); end

    attr_accessor :comments
    def comments_attributes=(attributes); end
23 24 25

    attr_accessor :tags
    def tags_attributes=(attributes); end
26
  end
27 28

  class Comment
J
Joshua Peek 已提交
29 30
    extend ActiveModel::Naming
    include ActiveModel::Conversion
31

32 33
    attr_reader :id
    attr_reader :post_id
34
    def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
35 36
    def save; @id = 1; @post_id = 1 end
    def new_record?; @id.nil? end
37
    def to_param; @id; end
38
    def name
39
      @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
40
    end
41 42 43 44 45 46 47

    attr_accessor :relevances
    def relevances_attributes=(attributes); end

  end

  class Tag
J
Joshua Peek 已提交
48 49
    extend ActiveModel::Naming
    include ActiveModel::Conversion
Y
Yehuda Katz 已提交
50

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
    attr_reader :id
    attr_reader :post_id
    def initialize(id = nil, post_id = nil); @id, @post_id = id, post_id end
    def save; @id = 1; @post_id = 1 end
    def new_record?; @id.nil? end
    def to_param; @id; end
    def value
      @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
    end

    attr_accessor :relevances
    def relevances_attributes=(attributes); end

  end

  class CommentRelevance
J
Joshua Peek 已提交
67 68
    extend ActiveModel::Naming
    include ActiveModel::Conversion
Y
Yehuda Katz 已提交
69

70 71 72 73 74 75 76 77 78 79 80 81
    attr_reader :id
    attr_reader :comment_id
    def initialize(id = nil, comment_id = nil); @id, @comment_id = id, comment_id end
    def save; @id = 1; @comment_id = 1 end
    def new_record?; @id.nil? end
    def to_param; @id; end
    def value
      @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
    end
  end

  class TagRelevance
J
Joshua Peek 已提交
82 83
    extend ActiveModel::Naming
    include ActiveModel::Conversion
Y
Yehuda Katz 已提交
84

85 86 87 88 89 90 91 92 93
    attr_reader :id
    attr_reader :tag_id
    def initialize(id = nil, tag_id = nil); @id, @tag_id = id, tag_id end
    def save; @id = 1; @tag_id = 1 end
    def new_record?; @id.nil? end
    def to_param; @id; end
    def value
      @id.nil? ? "new #{self.class.name.downcase}" : "#{self.class.name.downcase} ##{@id}"
    end
94
  end
95

96 97 98 99 100
  class Author < Comment
    attr_accessor :post
    def post_attributes=(attributes); end
  end
end
101

102 103
class FormHelperTest < ActionView::TestCase
  tests ActionView::Helpers::FormHelper
D
Initial  
David Heinemeier Hansson 已提交
104 105

  def setup
106
    super
107
    @post = Post.new
108
    @comment = Comment.new
109 110
    def @post.errors()
      Class.new{
111
        def [](field); field == "author_name" ? ["can't be empty"] : [] end
112
        def empty?() false end
113
        def count() 1 end
114 115
        def full_messages() [ "Author name can't be empty" ] end
      }.new
116
    end
117
    def @post.id; 123; end
118
    def @post.id_before_type_cast; 123; end
119
    def @post.to_param; '123'; end
120

D
Initial  
David Heinemeier Hansson 已提交
121 122 123 124 125
    @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)
126 127

    @controller = Class.new do
128
      attr_reader :url_for_options
129
      def url_for(options)
130
        @url_for_options = options
131 132 133 134
        "http://www.example.com"
      end
    end
    @controller = @controller.new
D
Initial  
David Heinemeier Hansson 已提交
135 136
  end

137 138 139 140 141 142 143
  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')
    )
144
    assert_dom_equal('<label for="post_secret">Secret?</label>', label("post", "secret?"))
145
  end
146

147 148
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
149
    assert_dom_equal('<label for="post_secret">Secret?</label>', label(:post, :secret?))
150 151
  end

152 153 154 155 156 157 158 159
  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

160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
  def test_label_with_id_attribute_as_symbol
    assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, :id => "my_id"))
  end

  def test_label_with_id_attribute_as_string
    assert_dom_equal('<label for="post_title" id="my_id">Title</label>', label(:post, :title, nil, "id" => "my_id"))
  end

  def test_label_with_for_and_id_attributes_as_symbol
    assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, :for => "my_for", :id => "my_id"))
  end

  def test_label_with_for_and_id_attributes_as_string
    assert_dom_equal('<label for="my_for" id="my_id">Title</label>', label(:post, :title, nil, "for" => "my_for", "id" => "my_id"))
  end

176 177 178 179 180
  def test_label_for_radio_buttons_with_value
    assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great_title"))
    assert_dom_equal('<label for="post_title_great_title">The title goes here</label>', label("post", "title", "The title goes here", :value => "great title"))
  end

D
Initial  
David Heinemeier Hansson 已提交
181
  def test_text_field
182
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
183 184
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
185
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
186 187
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
188
    assert_dom_equal(
189
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
190 191 192 193 194
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
195
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
196 197 198 199
      '<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

200 201 202 203 204 205 206 207
  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 已提交
208
  def test_text_field_with_options
209
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
210 211
    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 已提交
212
  end
213

D
Initial  
David Heinemeier Hansson 已提交
214
  def test_text_field_assuming_size
215
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
216 217
    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 已提交
218
  end
219

220 221 222 223 224 225
  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

226 227 228 229 230 231 232
  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

233 234 235
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
236 237
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
238 239 240 241 242 243 244 245 246 247 248 249 250
  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 已提交
251
  def test_check_box
252
    assert_dom_equal(
253
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
254 255 256
      check_box("post", "secret")
    )
    @post.secret = 0
257
    assert_dom_equal(
258
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
259
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
260
    )
261
    assert_dom_equal(
262
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
263 264
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
265
    @post.secret = true
266
    assert_dom_equal(
267
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
268 269
      check_box("post", "secret")
    )
270
    assert_dom_equal(
271
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
272 273
      check_box("post", "secret?")
    )
274 275 276

    @post.secret = ['0']
    assert_dom_equal(
277
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
278 279 280 281
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
282
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
283 284
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
285
  end
286

287 288
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
289
    assert_dom_equal(
290
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
291 292 293
      check_box("post", "secret", {}, "on", "off")
    )
  end
294

295 296
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
297
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
298 299 300 301
      check_box("post", "secret", { :disabled => :true })
    )
  end

302
  def test_radio_button
303
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
304
      radio_button("post", "title", "Hello World")
305
    )
306
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
307
      radio_button("post", "title", "Goodbye World")
308
    )
309 310 311
    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")
    )
312
  end
313

314 315 316 317 318
  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
319

320 321 322 323 324
  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
325

326 327 328 329 330 331 332 333 334 335
  def test_radio_button_with_booleans
    assert_dom_equal('<input id="post_secret_true" name="post[secret]" type="radio" value="true" />',
      radio_button("post", "secret", true)
    )

    assert_dom_equal('<input id="post_secret_false" name="post[secret]" type="radio" value="false" />',
      radio_button("post", "secret", false)
    )
  end

D
Initial  
David Heinemeier Hansson 已提交
336
  def test_text_area
337
    assert_dom_equal(
338
      '<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 已提交
339 340 341
      text_area("post", "body")
    )
  end
342

D
Initial  
David Heinemeier Hansson 已提交
343 344
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
345
    assert_dom_equal(
346
      '<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 已提交
347 348 349
      text_area("post", "body")
    )
  end
350

351 352 353 354 355 356
  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
357

358 359 360 361 362 363 364 365
  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

366 367 368 369 370 371
  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
372

D
Initial  
David Heinemeier Hansson 已提交
373
  def test_explicit_name
374
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
375
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
376
    )
377
    assert_dom_equal(
378
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
379 380
      text_area("post", "body", "name" => "really!")
    )
381
    assert_dom_equal(
382
      '<input name="i mean it" type="hidden" value="0" /><input checked="checked" id="post_secret" name="i mean it" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
383 384
      check_box("post", "secret", "name" => "i mean it")
    )
385
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
386
                 text_field("post", "title", :name => "dont guess")
387
    assert_dom_equal text_area("post", "body", "name" => "really!"),
388
                 text_area("post", "body", :name => "really!")
389
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
390
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
391
  end
392

D
Initial  
David Heinemeier Hansson 已提交
393
  def test_explicit_id
394
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
395
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
396
    )
397
    assert_dom_equal(
398
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
399 400
      text_area("post", "body", "id" => "really!")
    )
401
    assert_dom_equal(
402
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="i mean it" name="post[secret]" type="checkbox" value="1" />',
D
Initial  
David Heinemeier Hansson 已提交
403 404
      check_box("post", "secret", "id" => "i mean it")
    )
405
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
406
                 text_field("post", "title", :id => "dont guess")
407
    assert_dom_equal text_area("post", "body", "id" => "really!"),
408
                 text_area("post", "body", :id => "really!")
409
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
410
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
411
  end
412 413 414

  def test_auto_index
    pid = @post.id
415 416 417 418
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
419
    assert_dom_equal(
420 421
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
422
    assert_dom_equal(
423
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
424 425
      text_area("post[]", "body")
    )
426
    assert_dom_equal(
427
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
428 429
      check_box("post[]", "secret")
    )
430
   assert_dom_equal(
431
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
432 433
      radio_button("post[]", "title", "Hello World")
    )
434
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
435 436 437
      radio_button("post[]", "title", "Goodbye World")
    )
  end
438 439

  def test_form_for
440
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
441 442 443 444 445
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
446 447
    end

448
    expected =
449
      "<form action='http://www.example.com' id='create-post' method='post'>" +
450
      "<label for='post_title'>Title</label>" +
451 452
      "<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>" +
453
      "<input name='post[secret]' type='hidden' value='0' />" +
454
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
455
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
456 457
      "</form>"

458
    assert_dom_equal expected, output_buffer
459 460 461 462
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
463 464 465
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
466 467
    end

468
    expected =
469
      "<form action='http://www.example.com' id='create-post' method='post'>" +
470
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
471 472
      "<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>" +
473
      "<input name='post[secret]' type='hidden' value='0' />" +
474
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
475 476
      "</form>"

477
    assert_dom_equal expected, output_buffer
478 479
  end

480
  def test_form_for_without_object
481
    form_for(:post, :html => { :id => 'create-post' }) do |f|
482 483 484
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
485 486
    end

487
    expected =
488
      "<form action='http://www.example.com' id='create-post' method='post'>" +
489 490 491
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' type='hidden' value='0' />" +
492
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
493 494
      "</form>"

495
    assert_dom_equal expected, output_buffer
496
  end
497

498 499
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
500 501 502 503
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
504
    end
505

506
    expected =
507
      "<form action='http://www.example.com' method='post'>" +
508
      "<label for=\"post_123_title\">Title</label>" +
509 510
      "<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>" +
511
      "<input name='post[123][secret]' type='hidden' value='0' />" +
512
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
513
      "</form>"
514

515
    assert_dom_equal expected, output_buffer
516 517
  end

518 519
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
520 521 522
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
523 524 525 526 527 528 529
    end

    expected =
      "<form action='http://www.example.com' method='post'>" +
      "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
      "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[][secret]' type='hidden' value='0' />" +
530
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
531 532
      "</form>"

533
    assert_dom_equal expected, output_buffer
534 535
  end

536 537 538
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
539
        concat c.text_field(:title)
540 541 542 543 544 545 546
      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>"

547
    assert_dom_equal expected, output_buffer
548
  end
549

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
  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

566
  def test_nested_fields_for_with_index_and_parent_fields
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
    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

582
  def test_form_for_with_index_and_nested_fields_for
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623
    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

624 625 626 627 628 629 630 631 632 633 634 635 636 637
  def test_nested_fields_for_with_index_radio_button
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post, :index => 5) do |c|
        concat c.radio_button(:title, "hello")
      end
    end

    expected = "<form action='http://www.example.com' method='post'>" +
               "<input name='post[comment][5][title]' type='radio' id='post_comment_5_title_hello' value='hello' />" +
               "</form>"

    assert_dom_equal expected, output_buffer
  end

638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
  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

675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
  def test_nested_fields_for_with_a_new_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:author) do |af|
        concat af.text_field(:name)
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
               '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="new author" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

693 694 695 696 697 698 699 700 701
  def test_nested_fields_for_with_explicitly_passed_object_on_a_nested_attributes_one_to_one_association
    form_for(:post, @post) do |f|
      f.fields_for(:author, Author.new(123)) do |af|
        assert_not_nil af.object
        assert_equal 123, af.object.id
      end
    end
  end

702 703 704 705 706 707 708 709 710 711 712 713
  def test_nested_fields_for_with_an_existing_record_on_a_nested_attributes_one_to_one_association
    @post.author = Author.new(321)

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:author) do |af|
        concat af.text_field(:name)
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
714
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734
               '<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association
    @post.comments = Array.new(2) { |id| Comment.new(id + 1) }

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        f.fields_for(:comments, comment) do |cf|
          concat cf.text_field(:name)
        end
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
735 736 737 738
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757
               '</form>'

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new, Comment.new]

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        f.fields_for(:comments, comment) do |cf|
          concat cf.text_field(:name)
        end
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
758 759
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="new comment" />' +
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
               '</form>'

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_with_existing_and_new_records_on_a_nested_attributes_collection_association
    @post.comments = [Comment.new(321), Comment.new]

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      @post.comments.each do |comment|
        f.fields_for(:comments, comment) do |cf|
          concat cf.text_field(:name)
        end
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
779 780 781
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
               '</form>'

    assert_dom_equal expected, output_buffer
  end

  def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
    @post.comments = [Comment.new(321), Comment.new]
    yielded_comments = []

    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:comments) do |cf|
        concat cf.text_field(:name)
        yielded_comments << cf.object
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
801 802 803
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
804 805 806 807 808 809
               '</form>'

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

810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
  def test_nested_fields_for_with_child_index_option_override_on_a_nested_attributes_collection_association
    @post.comments = []

    form_for(:post, @post) do |f|
      f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf|
        concat cf.text_field(:name)
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
               '<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871
  def test_nested_fields_uses_unique_indices_for_different_collection_associations
    @post.comments = [Comment.new(321)]
    @post.tags = [Tag.new(123), Tag.new(456)]
    @post.comments[0].relevances = []
    @post.tags[0].relevances = []
    @post.tags[1].relevances = []
    form_for(:post, @post) do |f|
      f.fields_for(:comments, @post.comments[0]) do |cf|
        concat cf.text_field(:name)
        cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf|
          concat crf.text_field(:value)
        end
      end
      f.fields_for(:tags, @post.tags[0]) do |tf|
        concat tf.text_field(:value)
        tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf|
          concat trf.text_field(:value)
        end
      end
      f.fields_for('tags', @post.tags[1]) do |tf|
        concat tf.text_field(:value)
        tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf|
          concat trf.text_field(:value)
        end
      end
    end

    expected = '<form action="http://www.example.com" method="post">' +
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
               '<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
               '<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
               '<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
               '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
               '<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
               '<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
               '<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
               '<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
               '<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
               '<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

872
  def test_fields_for
873
    fields_for(:post, @post) do |f|
874 875 876
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
877 878
    end

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

885
    assert_dom_equal expected, output_buffer
886 887 888 889
  end

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

901
    assert_dom_equal expected, output_buffer
902 903 904 905
  end

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

917
    assert_dom_equal expected, output_buffer
918 919 920 921
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
922 923 924
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
925 926 927 928 929
    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>" +
930 931
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
932

933
    assert_dom_equal expected, output_buffer
934
  end
935 936 937

  def test_fields_for_without_object
    fields_for(:post) do |f|
938 939 940
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
941 942
    end

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

949
    assert_dom_equal expected, output_buffer
950 951 952 953
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
954 955 956
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
957 958
    end

959
    expected =
960 961
      "<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>" +
962 963
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
964

965
    assert_dom_equal expected, output_buffer
966 967
  end

968 969
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
970 971
      concat f.label(:title)
      concat f.text_field(:title)
972 973
    end

974 975
    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' />",
976
      output_buffer
977 978
  end

979 980
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
981 982
      concat f.label(:title)
      concat f.text_field(:title)
983 984 985 986
    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' />",
987
      output_buffer
988 989
  end

990 991 992
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
993

994
  def test_form_for_and_fields_for
995
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
996 997
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
998

999
      fields_for(:parent_post, @post) do |parent_fields|
1000
        concat parent_fields.check_box(:secret)
1001 1002 1003
      end
    end

1004
    expected =
1005
      "<form action='http://www.example.com' id='create-post' method='post'>" +
1006 1007 1008
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='parent_post[secret]' type='hidden' value='0' />" +
1009
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
1010 1011
      "</form>"

1012
    assert_dom_equal expected, output_buffer
1013
  end
1014

1015 1016
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1017 1018
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1019 1020

      post_form.fields_for(@comment) do |comment_fields|
1021
        concat comment_fields.text_field(:name)
1022 1023 1024
      end
    end

1025
    expected =
1026 1027 1028 1029 1030 1031
      "<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>"

1032
    assert_dom_equal expected, output_buffer
1033 1034
  end

1035
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1036 1037 1038 1039 1040 1041 1042 1043 1044
    (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
1045

1046
  def test_form_for_with_labelled_builder
1047
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1048 1049 1050
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1051 1052
    end

1053
    expected =
1054 1055 1056
      "<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/>" +
1057
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
1058 1059
      "</form>"

1060
    assert_dom_equal expected, output_buffer
1061
  end
1062 1063

  def test_default_form_builder
1064 1065
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1066 1067

    form_for(:post, @post) do |f|
1068 1069 1070
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1071 1072
    end

1073
    expected =
1074 1075 1076
      "<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/>" +
1077
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
1078 1079
      "</form>"

1080
    assert_dom_equal expected, output_buffer
1081
  ensure
1082
    ActionView.default_form_builder = old_default_form_builder
1083
  end
1084

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

    expected = %(<form action='http://www.example.com' method='post'>) +
               %(<div class='formError'>can't be empty</div>) +
1093 1094
               %(<div class="errorExplanation" id="errorExplanation"><h2>1 error prohibited this post from being saved</h2><p>There were problems with the following fields:</p><ul><li>Author name can't be empty</li></ul></div>) +
               %(</form>)
1095

1096
    assert_dom_equal expected, output_buffer
1097 1098

  end
1099

1100 1101 1102
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1103

1104
    form_for(:post, post) do |f|
1105 1106
       concat f.error_message_on('author_name')
       concat f.error_messages
1107 1108 1109 1110
    end

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

1114
    assert_dom_equal expected, output_buffer
1115

1116
  end
1117

1118 1119 1120 1121
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

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

1128
     expected =
1129
       %(<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">) +
1130 1131
       "<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/>" +
1132
       "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>" +
1133 1134
       "</form>"

1135
     assert_dom_equal expected, output_buffer
1136
  end
1137

1138
  def test_fields_for_with_labelled_builder
1139
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1140 1141 1142
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1143
    end
1144 1145

    expected =
1146 1147
      "<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/>" +
1148
      "<label for='secret'>Secret:</label> <input name='post[secret]' type='hidden' value='0' /><input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' /><br/>"
1149

1150
    assert_dom_equal expected, output_buffer
1151
  end
1152

1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
  def test_form_for_with_labelled_builder_with_nested_fields_for_without_options_hash
    klass = nil

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new) do |nested_fields|
        klass = nested_fields.class
        ''
      end
    end

    assert_equal LabelledFormBuilder, klass
  end

  def test_form_for_with_labelled_builder_with_nested_fields_for_with_options_hash
    klass = nil

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :index => 'foo') do |nested_fields|
        klass = nested_fields.class
        ''
      end
    end

    assert_equal LabelledFormBuilder, klass
  end

  class LabelledFormBuilderSubclass < LabelledFormBuilder; end

  def test_form_for_with_labelled_builder_with_nested_fields_for_with_custom_builder
    klass = nil

    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
      f.fields_for(:comments, Comment.new, :builder => LabelledFormBuilderSubclass) do |nested_fields|
        klass = nested_fields.class
        ''
      end
    end

    assert_equal LabelledFormBuilderSubclass, klass
  end

1194 1195 1196
  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>"
1197

1198
    assert_dom_equal expected, output_buffer
1199
  end
1200

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

1204
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1205 1206 1207 1208 1209 1210 1211 1212
  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
1213

1214 1215 1216 1217
  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>"
1218
    assert_equal expected, output_buffer
1219 1220 1221 1222 1223
  end

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

1224
    expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
1225
    assert_equal expected, output_buffer
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
  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>"
1236
    assert_equal expected, output_buffer
1237 1238
  end

1239 1240 1241
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1242

1243 1244
    form_for([@post, @comment]) {}

1245
    expected = %(<form action="#{comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0;display:inline"><input name="_method" type="hidden" value="put" /></div></form>)
1246
    assert_dom_equal expected, output_buffer
1247 1248 1249 1250
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1251

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

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

1258 1259 1260
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1261

1262
    form_for([:admin, @post, @comment]) {}
1263

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

1268 1269
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1270

1271
    form_for([:admin, @post, @comment]) {}
1272

1273
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1274
    assert_dom_equal expected, output_buffer
1275 1276
  end

1277 1278 1279
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1280
    expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
1281
    assert_equal expected, output_buffer
1282
  end
1283

1284 1285
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1286

1287 1288
    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>"
1289

1290
    assert_dom_equal expected, output_buffer
1291
  end
1292 1293

  protected
1294 1295 1296
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1297
    alias_method :post_comments_path, :comments_path
1298 1299 1300 1301

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

1304 1305 1306 1307
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1308

1309 1310 1311 1312
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1313

1314 1315
    def posts_path
      "/posts"
1316 1317
    end

1318 1319
    def post_path(post)
      "/posts/#{post.id}"
1320
    end
1321 1322 1323

    def protect_against_forgery?
      false
1324
    end
1325
end