form_helper_test.rb 54.2 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
               '</form>'

    assert_dom_equal expected, output_buffer
  end

787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
  def test_nested_fields_for_with_an_empty_supplied_attributes_collection
    form_for(:post, @post) do |f|
      concat f.text_field(:title)
      f.fields_for(:comments, []) do |cf|
        concat cf.text_field(:name)
      end
    end

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

    assert_dom_equal expected, output_buffer
  end

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

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

    expected = '<form action="http://www.example.com" method="post">' +
               '<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
               '<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
               '<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
               '<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
               '<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
               '</form>'

    assert_dom_equal expected, output_buffer
  end

823 824 825 826 827 828 829 830 831 832 833 834 835 836
  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" />' +
837 838 839
               '<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" />' +
840 841 842 843 844 845
               '</form>'

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

846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862
  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

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
  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

908
  def test_fields_for
909
    fields_for(:post, @post) do |f|
910 911 912
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
913 914
    end

915
    expected =
916 917
      "<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>" +
918 919
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
920

921
    assert_dom_equal expected, output_buffer
922 923 924 925
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
926 927 928
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
929 930 931 932 933
    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>" +
934 935
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
936

937
    assert_dom_equal expected, output_buffer
938 939 940 941
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
942 943 944
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
945 946 947 948 949
    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>" +
950 951
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
952

953
    assert_dom_equal expected, output_buffer
954 955 956 957
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
958 959 960
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
961 962 963 964 965
    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>" +
966 967
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
968

969
    assert_dom_equal expected, output_buffer
970
  end
971 972 973

  def test_fields_for_without_object
    fields_for(:post) do |f|
974 975 976
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
977 978
    end

979
    expected =
980 981
      "<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>" +
982 983
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
984

985
    assert_dom_equal expected, output_buffer
986 987 988 989
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
990 991 992
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
993 994
    end

995
    expected =
996 997
      "<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>" +
998 999
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
1000

1001
    assert_dom_equal expected, output_buffer
1002 1003
  end

1004 1005
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
1006 1007
      concat f.label(:title)
      concat f.text_field(:title)
1008 1009
    end

1010 1011
    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' />",
1012
      output_buffer
1013 1014
  end

1015 1016
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
1017 1018
      concat f.label(:title)
      concat f.text_field(:title)
1019 1020 1021 1022
    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' />",
1023
      output_buffer
1024 1025
  end

1026 1027 1028
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
1029

1030
  def test_form_for_and_fields_for
1031
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1032 1033
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1034

1035
      fields_for(:parent_post, @post) do |parent_fields|
1036
        concat parent_fields.check_box(:secret)
1037 1038 1039
      end
    end

1040
    expected =
1041
      "<form action='http://www.example.com' id='create-post' method='post'>" +
1042 1043 1044
      "<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' />" +
1045
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
1046 1047
      "</form>"

1048
    assert_dom_equal expected, output_buffer
1049
  end
1050

1051 1052
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1053 1054
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1055 1056

      post_form.fields_for(@comment) do |comment_fields|
1057
        concat comment_fields.text_field(:name)
1058 1059 1060
      end
    end

1061
    expected =
1062 1063 1064 1065 1066 1067
      "<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>"

1068
    assert_dom_equal expected, output_buffer
1069 1070
  end

1071
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1072 1073 1074 1075 1076 1077 1078 1079 1080
    (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
1081

1082
  def test_form_for_with_labelled_builder
1083
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1084 1085 1086
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1087 1088
    end

1089
    expected =
1090 1091 1092
      "<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/>" +
1093
      "<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/>" +
1094 1095
      "</form>"

1096
    assert_dom_equal expected, output_buffer
1097
  end
1098 1099

  def test_default_form_builder
1100 1101
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1102 1103

    form_for(:post, @post) do |f|
1104 1105 1106
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1107 1108
    end

1109
    expected =
1110 1111 1112
      "<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/>" +
1113
      "<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/>" +
1114 1115
      "</form>"

1116
    assert_dom_equal expected, output_buffer
1117
  ensure
1118
    ActionView.default_form_builder = old_default_form_builder
1119
  end
1120

1121 1122
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1123 1124
       concat f.error_message_on('author_name')
       concat f.error_messages
1125 1126 1127 1128
    end

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

1132
    assert_dom_equal expected, output_buffer
1133 1134

  end
1135

1136 1137 1138
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1139

1140
    form_for(:post, post) do |f|
1141 1142
       concat f.error_message_on('author_name')
       concat f.error_messages
1143 1144 1145 1146
    end

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

1150
    assert_dom_equal expected, output_buffer
1151

1152
  end
1153

1154 1155 1156 1157
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1158
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1159 1160 1161
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1162 1163
     end

1164
     expected =
1165
       %(<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">) +
1166 1167
       "<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/>" +
1168
       "<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/>" +
1169 1170
       "</form>"

1171
     assert_dom_equal expected, output_buffer
1172
  end
1173

1174
  def test_fields_for_with_labelled_builder
1175
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1176 1177 1178
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1179
    end
1180 1181

    expected =
1182 1183
      "<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/>" +
1184
      "<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/>"
1185

1186
    assert_dom_equal expected, output_buffer
1187
  end
1188

1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229
  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

1230 1231 1232
  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>"
1233

1234
    assert_dom_equal expected, output_buffer
1235
  end
1236

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

1240
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1241 1242 1243 1244 1245 1246 1247 1248
  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
1249

1250 1251 1252 1253
  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>"
1254
    assert_equal expected, output_buffer
1255 1256 1257 1258 1259
  end

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

1260
    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>"
1261
    assert_equal expected, output_buffer
1262 1263 1264 1265 1266 1267 1268 1269 1270 1271
  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>"
1272
    assert_equal expected, output_buffer
1273 1274
  end

1275 1276 1277
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1278

1279 1280
    form_for([@post, @comment]) {}

1281
    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>)
1282
    assert_dom_equal expected, output_buffer
1283 1284 1285 1286
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1287

1288 1289 1290
    form_for([@post, @comment]) {}

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

1294 1295 1296
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1297

1298
    form_for([:admin, @post, @comment]) {}
1299

1300
    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>)
1301
    assert_dom_equal expected, output_buffer
1302
  end
1303

1304 1305
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1306

1307
    form_for([:admin, @post, @comment]) {}
1308

1309
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1310
    assert_dom_equal expected, output_buffer
1311 1312
  end

1313 1314 1315
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1316
    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>"
1317
    assert_equal expected, output_buffer
1318
  end
1319

1320 1321
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1322

1323 1324
    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>"
1325

1326
    assert_dom_equal expected, output_buffer
1327
  end
1328 1329

  protected
1330 1331 1332
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1333
    alias_method :post_comments_path, :comments_path
1334 1335 1336 1337

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

1340 1341 1342 1343
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1344

1345 1346 1347 1348
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1349

1350 1351
    def posts_path
      "/posts"
1352 1353
    end

1354 1355
    def post_path(post)
      "/posts/#{post.id}"
1356
    end
1357 1358 1359

    def protect_against_forgery?
      false
1360
    end
1361
end