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

D
Initial  
David Heinemeier Hansson 已提交
310
  def test_text_area
311
    assert_dom_equal(
312
      '<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 已提交
313 314 315
      text_area("post", "body")
    )
  end
316

D
Initial  
David Heinemeier Hansson 已提交
317 318
  def test_text_area_with_escapes
    @post.body        = "Back to <i>the</i> hill and over it again!"
319
    assert_dom_equal(
320
      '<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 已提交
321 322 323
      text_area("post", "body")
    )
  end
324

325 326 327 328 329 330
  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
331

332 333 334 335 336 337 338 339
  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

340 341 342 343 344 345
  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
346

D
Initial  
David Heinemeier Hansson 已提交
347
  def test_explicit_name
348
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
349
      '<input id="post_title" name="dont guess" size="30" type="text" value="Hello World" />', text_field("post", "title", "name" => "dont guess")
350
    )
351
    assert_dom_equal(
352
      '<textarea cols="40" id="post_body" name="really!" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
353 354
      text_area("post", "body", "name" => "really!")
    )
355
    assert_dom_equal(
356
      '<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 已提交
357 358
      check_box("post", "secret", "name" => "i mean it")
    )
359
    assert_dom_equal text_field("post", "title", "name" => "dont guess"),
360
                 text_field("post", "title", :name => "dont guess")
361
    assert_dom_equal text_area("post", "body", "name" => "really!"),
362
                 text_area("post", "body", :name => "really!")
363
    assert_dom_equal check_box("post", "secret", "name" => "i mean it"),
364
                 check_box("post", "secret", :name => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
365
  end
366

D
Initial  
David Heinemeier Hansson 已提交
367
  def test_explicit_id
368
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
369
      '<input id="dont guess" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title", "id" => "dont guess")
370
    )
371
    assert_dom_equal(
372
      '<textarea cols="40" id="really!" name="post[body]" rows="20">Back to the hill and over it again!</textarea>',
D
Initial  
David Heinemeier Hansson 已提交
373 374
      text_area("post", "body", "id" => "really!")
    )
375
    assert_dom_equal(
376
      '<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 已提交
377 378
      check_box("post", "secret", "id" => "i mean it")
    )
379
    assert_dom_equal text_field("post", "title", "id" => "dont guess"),
380
                 text_field("post", "title", :id => "dont guess")
381
    assert_dom_equal text_area("post", "body", "id" => "really!"),
382
                 text_area("post", "body", :id => "really!")
383
    assert_dom_equal check_box("post", "secret", "id" => "i mean it"),
384
                 check_box("post", "secret", :id => "i mean it")
D
Initial  
David Heinemeier Hansson 已提交
385
  end
386 387 388

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

  def test_form_for
414
    form_for(:post, @post, :html => { :id => 'create-post' }) do |f|
415 416 417 418 419
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
      concat f.submit('Create post')
420 421
    end

422
    expected =
423
      "<form action='http://www.example.com' id='create-post' method='post'>" +
424
      "<label for='post_title'>Title</label>" +
425 426
      "<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>" +
427
      "<input name='post[secret]' type='hidden' value='0' />" +
428
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
429
      "<input name='commit' id='post_submit' type='submit' value='Create post' />" +
430 431
      "</form>"

432
    assert_dom_equal expected, output_buffer
433 434 435 436
  end

  def test_form_for_with_method
    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
437 438 439
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
440 441
    end

442
    expected =
443
      "<form action='http://www.example.com' id='create-post' method='post'>" +
444
      "<div style='margin:0;padding:0;display:inline'><input name='_method' type='hidden' value='put' /></div>" +
445 446
      "<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>" +
447
      "<input name='post[secret]' type='hidden' value='0' />" +
448
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
449 450
      "</form>"

451
    assert_dom_equal expected, output_buffer
452 453
  end

454
  def test_form_for_without_object
455
    form_for(:post, :html => { :id => 'create-post' }) do |f|
456 457 458
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
459 460
    end

461
    expected =
462
      "<form action='http://www.example.com' id='create-post' method='post'>" +
463 464 465
      "<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' />" +
466
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
467 468
      "</form>"

469
    assert_dom_equal expected, output_buffer
470
  end
471

472 473
  def test_form_for_with_index
    form_for("post[]", @post) do |f|
474 475 476 477
      concat f.label(:title)
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
478
    end
479

480
    expected =
481
      "<form action='http://www.example.com' method='post'>" +
482
      "<label for=\"post_123_title\">Title</label>" +
483 484
      "<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>" +
485
      "<input name='post[123][secret]' type='hidden' value='0' />" +
486
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
487
      "</form>"
488

489
    assert_dom_equal expected, output_buffer
490 491
  end

492 493
  def test_form_for_with_nil_index_option_override
    form_for("post[]", @post, :index => nil) do |f|
494 495 496
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
497 498 499 500 501 502 503
    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' />" +
504
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
505 506
      "</form>"

507
    assert_dom_equal expected, output_buffer
508 509
  end

510 511 512
  def test_nested_fields_for
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
513
        concat c.text_field(:title)
514 515 516 517 518 519 520
      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>"

521
    assert_dom_equal expected, output_buffer
522
  end
523

524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
  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

540
  def test_nested_fields_for_with_index_and_parent_fields
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
    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

556
  def test_form_for_with_index_and_nested_fields_for
557 558 559 560 561 562 563 564 565 566 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
    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

598 599 600 601 602 603 604 605 606 607 608 609 610 611
  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

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

649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666
  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

667 668 669 670 671 672 673 674 675
  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

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

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

784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800
  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

801 802 803 804 805 806 807 808 809 810 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
  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

846
  def test_fields_for
847
    fields_for(:post, @post) do |f|
848 849 850
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
851 852
    end

853
    expected =
854 855
      "<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>" +
856 857
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
858

859
    assert_dom_equal expected, output_buffer
860 861 862 863
  end

  def test_fields_for_with_index
    fields_for("post[]", @post) do |f|
864 865 866
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
867 868 869 870 871
    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>" +
872 873
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />"
874

875
    assert_dom_equal expected, output_buffer
876 877 878 879
  end

  def test_fields_for_with_nil_index_option_override
    fields_for("post[]", @post, :index => nil) do |f|
880 881 882
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
883 884 885 886 887
    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>" +
888 889
      "<input name='post[][secret]' type='hidden' value='0' />" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />"
890

891
    assert_dom_equal expected, output_buffer
892 893 894 895
  end

  def test_fields_for_with_index_option_override
    fields_for("post[]", @post, :index => "abc") do |f|
896 897 898
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
899 900 901 902 903
    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>" +
904 905
      "<input name='post[abc][secret]' type='hidden' value='0' />" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />"
906

907
    assert_dom_equal expected, output_buffer
908
  end
909 910 911

  def test_fields_for_without_object
    fields_for(:post) do |f|
912 913 914
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
915 916
    end

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

923
    assert_dom_equal expected, output_buffer
924 925 926 927
  end

  def test_fields_for_with_only_object
    fields_for(@post) do |f|
928 929 930
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
931 932
    end

933
    expected =
934 935
      "<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>" +
936 937
      "<input name='post[secret]' type='hidden' value='0' />" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
938

939
    assert_dom_equal expected, output_buffer
940 941
  end

942 943
  def test_fields_for_object_with_bracketed_name
    fields_for("author[post]", @post) do |f|
944 945
      concat f.label(:title)
      concat f.text_field(:title)
946 947
    end

948 949
    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' />",
950
      output_buffer
951 952
  end

953 954
  def test_fields_for_object_with_bracketed_name_and_index
    fields_for("author[post]", @post, :index => 1) do |f|
955 956
      concat f.label(:title)
      concat f.text_field(:title)
957 958 959 960
    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' />",
961
      output_buffer
962 963
  end

964 965 966
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
967

968
  def test_form_for_and_fields_for
969
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
970 971
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
972

973
      fields_for(:parent_post, @post) do |parent_fields|
974
        concat parent_fields.check_box(:secret)
975 976 977
      end
    end

978
    expected =
979
      "<form action='http://www.example.com' id='create-post' method='post'>" +
980 981 982
      "<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' />" +
983
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
984 985
      "</form>"

986
    assert_dom_equal expected, output_buffer
987
  end
988

989 990
  def test_form_for_and_fields_for_with_object
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
991 992
      concat post_form.text_field(:title)
      concat post_form.text_area(:body)
993 994

      post_form.fields_for(@comment) do |comment_fields|
995
        concat comment_fields.text_field(:name)
996 997 998
      end
    end

999
    expected =
1000 1001 1002 1003 1004 1005
      "<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>"

1006
    assert_dom_equal expected, output_buffer
1007 1008
  end

1009
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
1010 1011 1012 1013 1014 1015 1016 1017 1018
    (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
1019

1020
  def test_form_for_with_labelled_builder
1021
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1022 1023 1024
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1025 1026
    end

1027
    expected =
1028 1029 1030
      "<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/>" +
1031
      "<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/>" +
1032 1033
      "</form>"

1034
    assert_dom_equal expected, output_buffer
1035
  end
1036 1037

  def test_default_form_builder
1038 1039
    old_default_form_builder, ActionView.default_form_builder =
      ActionView.default_form_builder, LabelledFormBuilder
1040 1041

    form_for(:post, @post) do |f|
1042 1043 1044
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1045 1046
    end

1047
    expected =
1048 1049 1050
      "<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/>" +
1051
      "<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/>" +
1052 1053
      "</form>"

1054
    assert_dom_equal expected, output_buffer
1055
  ensure
1056
    ActionView.default_form_builder = old_default_form_builder
1057
  end
1058

1059 1060
  def test_default_form_builder_with_active_record_helpers
    form_for(:post, @post) do |f|
1061 1062
       concat f.error_message_on('author_name')
       concat f.error_messages
1063 1064 1065 1066
    end

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

1070
    assert_dom_equal expected, output_buffer
1071 1072

  end
1073

1074 1075 1076
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
1077

1078
    form_for(:post, post) do |f|
1079 1080
       concat f.error_message_on('author_name')
       concat f.error_messages
1081 1082 1083 1084
    end

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

1088
    assert_dom_equal expected, output_buffer
1089

1090
  end
1091

1092 1093 1094 1095
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper

1096
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1097 1098 1099
       concat f.text_field(:title)
       concat f.text_area(:body)
       concat f.check_box(:secret)
1100 1101
     end

1102
     expected =
1103
       %(<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">) +
1104 1105
       "<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/>" +
1106
       "<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/>" +
1107 1108
       "</form>"

1109
     assert_dom_equal expected, output_buffer
1110
  end
1111

1112
  def test_fields_for_with_labelled_builder
1113
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
1114 1115 1116
      concat f.text_field(:title)
      concat f.text_area(:body)
      concat f.check_box(:secret)
1117
    end
1118 1119

    expected =
1120 1121
      "<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/>" +
1122
      "<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/>"
1123

1124
    assert_dom_equal expected, output_buffer
1125
  end
1126

1127 1128 1129 1130 1131 1132 1133 1134 1135 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
  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

1168 1169 1170
  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>"
1171

1172
    assert_dom_equal expected, output_buffer
1173
  end
1174

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

1178
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', output_buffer
1179 1180 1181 1182 1183 1184 1185 1186
  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
1187

1188 1189 1190 1191
  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>"
1192
    assert_equal expected, output_buffer
1193 1194 1195 1196 1197
  end

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

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

1213 1214 1215
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
1216

1217 1218
    form_for([@post, @comment]) {}

1219
    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>)
1220
    assert_dom_equal expected, output_buffer
1221 1222 1223 1224
  end

  def test_form_for_with_new_object_in_list
    @post.new_record = false
1225

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

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

1232 1233 1234
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
1235

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

1238
    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>)
1239
    assert_dom_equal expected, output_buffer
1240
  end
1241

1242 1243
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
1244

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

1247
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
1248
    assert_dom_equal expected, output_buffer
1249 1250
  end

1251 1252 1253
  def test_form_for_with_existing_object_and_custom_url
    form_for(@post, :url => "/super_posts") do |f| end

1254
    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>"
1255
    assert_equal expected, output_buffer
1256
  end
1257

1258 1259
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
1260

1261 1262
    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>"
1263

1264
    assert_dom_equal expected, output_buffer
1265
  end
1266 1267

  protected
1268 1269 1270
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
1271
    alias_method :post_comments_path, :comments_path
1272 1273 1274 1275

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

1278 1279 1280 1281
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
1282

1283 1284 1285 1286
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
1287

1288 1289
    def posts_path
      "/posts"
1290 1291
    end

1292 1293
    def post_path(post)
      "/posts/#{post.id}"
1294
    end
1295 1296 1297

    def protect_against_forgery?
      false
1298
    end
1299
end