form_helper_test.rb 51.9 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
  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 已提交
165
  def test_text_field
166
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
167 168
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
169
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
170 171
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
172
    assert_dom_equal(
173
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
174 175 176 177 178
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
179
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
180 181 182 183
      '<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

184 185 186 187 188 189 190 191
  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 已提交
192
  def test_text_field_with_options
193
    expected = '<input id="post_title" name="post[title]" size="35" type="text" value="Hello World" />'
194 195
    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 已提交
196
  end
197

D
Initial  
David Heinemeier Hansson 已提交
198
  def test_text_field_assuming_size
199
    expected = '<input id="post_title" maxlength="35" name="post[title]" size="35" type="text" value="Hello World" />'
200 201
    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 已提交
202
  end
203

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

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

217 218 219
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
220 221
      assert_dom_equal '<input id="post_secret" name="post[secret]" type="hidden" value="1" />',
        hidden_field("post", "secret?")
222 223 224 225 226 227 228 229 230 231 232 233 234
  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 已提交
235
  def test_check_box
236
    assert_dom_equal(
237
      '<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 已提交
238 239 240
      check_box("post", "secret")
    )
    @post.secret = 0
241
    assert_dom_equal(
242
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
243
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
244
    )
245
    assert_dom_equal(
246
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
247 248
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
249
    @post.secret = true
250
    assert_dom_equal(
251
      '<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 已提交
252 253
      check_box("post", "secret")
    )
254
    assert_dom_equal(
255
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
256 257
      check_box("post", "secret?")
    )
258 259 260

    @post.secret = ['0']
    assert_dom_equal(
261
      '<input name="post[secret]" type="hidden" value="0" /><input id="post_secret" name="post[secret]" type="checkbox" value="1" />',
262 263 264 265
      check_box("post", "secret")
    )
    @post.secret = ['1']
    assert_dom_equal(
266
      '<input name="post[secret]" type="hidden" value="0" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
267 268
      check_box("post", "secret")
    )
D
Initial  
David Heinemeier Hansson 已提交
269
  end
270

271 272
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
273
    assert_dom_equal(
274
      '<input name="post[secret]" type="hidden" value="off" /><input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" />',
275 276 277
      check_box("post", "secret", {}, "on", "off")
    )
  end
278

279 280
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
281
      '<input name="post[secret]" type="hidden" value="1" /><input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" />',
282 283 284 285
      check_box("post", "secret", { :disabled => :true })
    )
  end

286
  def test_radio_button
287
    assert_dom_equal('<input checked="checked" id="post_title_hello_world" name="post[title]" type="radio" value="Hello World" />',
288
      radio_button("post", "title", "Hello World")
289
    )
290
    assert_dom_equal('<input id="post_title_goodbye_world" name="post[title]" type="radio" value="Goodbye World" />',
291
      radio_button("post", "title", "Goodbye World")
292
    )
293 294 295
    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")
    )
296
  end
297

298 299 300 301 302
  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
303

304 305 306 307 308
  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
309

310 311 312 313 314 315 316 317 318 319
  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 已提交
320
  def test_text_area
321
    assert_dom_equal(
322
      '<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 已提交
323 324 325
      text_area("post", "body")
    )
  end
326

D
Initial  
David Heinemeier Hansson 已提交
327 328
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
329
    assert_dom_equal(
330
      '<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 已提交
331 332 333
      text_area("post", "body")
    )
  end
334

335 336 337 338 339 340
  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
341

342 343 344 345 346 347 348 349
  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

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

D
Initial  
David Heinemeier Hansson 已提交
357
  def test_explicit_name
358
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
359
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
360
    )
361
    assert_dom_equal(
362
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
363 364
      text_area("post", "body", "name" => "really!")
    )
365
    assert_dom_equal(
366
      '<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 已提交
367 368
      check_box("post", "secret", "name" => "i mean it")
    )
369
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
370
                 text_field("post", "title", :name => "dont guess")
371
    assert_dom_equal text_area("post", "body", "name" => "really!"),
372
                 text_area("post", "body", :name => "really!")
373
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
374
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
375
  end
376

D
Initial  
David Heinemeier Hansson 已提交
377
  def test_explicit_id
378
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
379
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
380
    )
381
    assert_dom_equal(
382
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
383 384
      text_area("post", "body", "id" => "really!")
    )
385
    assert_dom_equal(
386
      '<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 已提交
387 388
      check_box("post", "secret", "id" => "i mean it")
    )
389
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
390
                 text_field("post", "title", :id => "dont guess")
391
    assert_dom_equal text_area("post", "body", "id" => "really!"),
392
                 text_area("post", "body", :id => "really!")
393
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
394
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
395
  end
396 397 398

  def test_auto_index
    pid = @post.id
399 400 401 402
    assert_dom_equal(
      "<label for=\"post_#{pid}_title\">Title</label>",
      label("post[]", "title")
    )
403
    assert_dom_equal(
404 405
      "<input id=\"post_#{pid}_title\" name=\"post[#{pid}][title]\" size=\"30\" type=\"text\" value=\"Hello World\" />", text_field("post[]","title")
    )
406
    assert_dom_equal(
407
      "<textarea cols=\"40\" id=\"post_#{pid}_body\" name=\"post[#{pid}][body]\" rows=\"20\">Back to the hill and over it again!</textarea>",
408 409
      text_area("post[]", "body")
    )
410
    assert_dom_equal(
411
      "<input name=\"post[#{pid}][secret]\" type=\"hidden\" value=\"0\" /><input checked=\"checked\" id=\"post_#{pid}_secret\" name=\"post[#{pid}][secret]\" type=\"checkbox\" value=\"1\" />",
412 413
      check_box("post[]", "secret")
    )
414
   assert_dom_equal(
415
"<input checked=\"checked\" id=\"post_#{pid}_title_hello_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Hello World\" />",
416 417
      radio_button("post[]", "title", "Hello World")
    )
418
    assert_dom_equal("<input id=\"post_#{pid}_title_goodbye_world\" name=\"post[#{pid}][title]\" type=\"radio\" value=\"Goodbye World\" />",
419 420 421
      radio_button("post[]", "title", "Goodbye World")
    )
  end
422 423

  def test_form_for
424
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
425 426 427 428 429
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
430 431
    end

432
    expected =
433
      "<form action='http://www.example.com' id='create-post' method='post'>" +
434
      "<label for='post_title'>Title</label>" +
435 436
      "<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>" +
437
      "<input name='post[secret]' type='hidden' value='0' />" +
438
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
439
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
440 441
      "</form>"

442
    assert_dom_equal expected, output_buffer
443 444 445 446
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
447 448 449
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
450 451
    end

452
    expected =
453
      "<form action='http://www.example.com' id='create-post' method='post'>" +
454
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
455 456
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
457
      "<input name='post[secret]' type='hidden' value='0' />" +
458
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
459 460
      "</form>"

461
    assert_dom_equal expected, output_buffer
462 463
  end

464
  def test_form_for_without_object
465
    form_for(:post, :html => { :id => 'create-post' }) do |f|
466 467 468
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
469 470
    end

471
    expected =
472
      "<form action='http://www.example.com' id='create-post' method='post'>" +
473 474 475
      "<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' />" +
476
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
477 478
      "</form>"

479
    assert_dom_equal expected, output_buffer
480
  end
481

482 483
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
484 485 486 487
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
488
    end
489

490
    expected =
491
      "<form action='http://www.example.com' method='post'>" +
492
      "<label for=\"post_123_title\">Title</label>" +
493 494
      "<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>" +
495
      "<input name='post[123][secret]' type='hidden' value='0' />" +
496
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
497
      "</form>"
498

499
    assert_dom_equal expected, output_buffer
500 501
  end

502 503
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
504 505 506
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
507 508 509 510 511 512 513
    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' />" +
514
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
515 516
      "</form>"

517
    assert_dom_equal expected, output_buffer
518 519
  end

520 521 522
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
523
        concat c.text_field(:title)
524 525 526 527 528 529 530
      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>"

531
    assert_dom_equal expected, output_buffer
532
  end
533

534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549
  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

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

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

608 609 610 611 612 613 614 615 616 617 618 619 620 621
  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

622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
  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

659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
  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

677 678 679 680 681 682 683 684 685
  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

686 687 688 689 690 691 692 693 694 695 696 697
  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" />' +
698
               '<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
               '<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" />' +
719 720 721 722
               '<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" />' +
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741
               '</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" />' +
742 743
               '<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" />' +
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762
               '</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" />' +
763 764 765
               '<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" />' +
766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
               '</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" />' +
785 786 787
               '<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" />' +
788 789 790 791 792 793
               '</form>'

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

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

811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 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
  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

856
  def test_fields_for
857
    fields_for(:post, @post) do |f|
858 859 860
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
861 862
    end

863
    expected =
864 865
      "<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>" +
866 867
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
868

869
    assert_dom_equal expected, output_buffer
870 871 872 873
  end

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

885
    assert_dom_equal expected, output_buffer
886 887 888 889
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) 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[][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>" +
898 899
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
900

901
    assert_dom_equal expected, output_buffer
902 903 904 905
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") 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[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>" +
914 915
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
916

917
    assert_dom_equal expected, output_buffer
918
  end
919 920 921

  def test_fields_for_without_object
    fields_for(:post) do |f|
922 923 924
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
925 926
    end

927
    expected =
928 929
      "<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>" +
930 931
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
932

933
    assert_dom_equal expected, output_buffer
934 935 936 937
  end

  def test_fields_for_with_only_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
  end

952 953
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
954 955
      concat f.label(:title)
      concat f.text_field(:title)
956 957
    end

958 959
    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' />",
960
      output_buffer
961 962
  end

963 964
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
965 966
      concat f.label(:title)
      concat f.text_field(:title)
967 968 969 970
    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' />",
971
      output_buffer
972 973
  end

974 975 976
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
977

978
  def test_form_for_and_fields_for
979
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
980 981
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
982

983
      fields_for(:parent_post, @post) do |parent_fields|
984
        concat parent_fields.check_box(:secret)
985 986 987
      end
    end

988
    expected =
989
      "<form action='http://www.example.com' id='create-post' method='post'>" +
990 991 992
      "<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' />" +
993
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
994 995
      "</form>"

996
    assert_dom_equal expected, output_buffer
997
  end
998

999 1000
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
1001 1002
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
1003 1004

      post_form.fields_for(@comment) do |comment_fields|
1005
        concat comment_fields.text_field(:name)
1006 1007 1008
      end
    end

1009
    expected =
1010 1011 1012 1013 1014 1015
      "<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>"

1016
    assert_dom_equal expected, output_buffer
1017 1018
  end

1019
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1020 1021 1022 1023 1024 1025 1026 1027 1028
    (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
1029

1030
  def test_form_for_with_labelled_builder
1031
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1032 1033 1034
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1035 1036
    end

1037
    expected =
1038 1039 1040
      "<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/>" +
1041
      "<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/>" +
1042 1043
      "</form>"

1044
    assert_dom_equal expected, output_buffer
1045
  end
1046 1047

  def test_default_form_builder
1048 1049
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1050 1051

    form_for(:post, @post) do |f|
1052 1053 1054
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1055 1056
    end

1057
    expected =
1058 1059 1060
      "<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/>" +
1061
      "<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/>" +
1062 1063
      "</form>"

1064
    assert_dom_equal expected, output_buffer
1065
  ensure
1066
    ActionView.default_form_builder = old_default_form_builder
1067
  end
1068

1069 1070
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1071 1072
       concat f.error_message_on('author_name')
       concat f.error_messages
1073 1074 1075 1076
    end

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

1080
    assert_dom_equal expected, output_buffer
1081 1082

  end
1083

1084 1085 1086
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1087

1088
    form_for(:post, post) do |f|
1089 1090
       concat f.error_message_on('author_name')
       concat f.error_messages
1091 1092 1093 1094
    end

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

1098
    assert_dom_equal expected, output_buffer
1099

1100
  end
1101

1102 1103 1104 1105
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1106
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1107 1108 1109
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1110 1111
     end

1112
     expected =
1113
       %(<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">) +
1114 1115
       "<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/>" +
1116
       "<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/>" +
1117 1118
       "</form>"

1119
     assert_dom_equal expected, output_buffer
1120
  end
1121

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

    expected =
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
    assert_dom_equal expected, output_buffer
1135
  end
1136

1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 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
  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

1178 1179 1180
  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>"
1181

1182
    assert_dom_equal expected, output_buffer
1183
  end
1184

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

1188
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1189 1190 1191 1192 1193 1194 1195 1196
  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
1197

1198 1199 1200 1201
  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>"
1202
    assert_equal expected, output_buffer
1203 1204 1205 1206 1207
  end

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

1208
    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>"
1209
    assert_equal expected, output_buffer
1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
  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>"
1220
    assert_equal expected, output_buffer
1221 1222
  end

1223 1224 1225
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1226

1227 1228
    form_for([@post, @comment]) {}

1229
    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>)
1230
    assert_dom_equal expected, output_buffer
1231 1232 1233 1234
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1235

1236 1237 1238
    form_for([@post, @comment]) {}

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

1242 1243 1244
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1245

1246
    form_for([:admin, @post, @comment]) {}
1247

1248
    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>)
1249
    assert_dom_equal expected, output_buffer
1250
  end
1251

1252 1253
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1254

1255
    form_for([:admin, @post, @comment]) {}
1256

1257
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1258
    assert_dom_equal expected, output_buffer
1259 1260
  end

1261 1262 1263
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1264
    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>"
1265
    assert_equal expected, output_buffer
1266
  end
1267

1268 1269
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1270

1271 1272
    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>"
1273

1274
    assert_dom_equal expected, output_buffer
1275
  end
1276 1277

  protected
1278 1279 1280
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1281
    alias_method :post_comments_path, :comments_path
1282 1283 1284 1285

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

1288 1289 1290 1291
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1292

1293 1294 1295 1296
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1297

1298 1299
    def posts_path
      "/posts"
1300 1301
    end

1302 1303
    def post_path(post)
      "/posts/#{post.id}"
1304
    end
1305 1306 1307

    def protect_against_forgery?
      false
1308
    end
1309
end