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

3 4 5 6 7 8
silence_warnings do
  Post = Struct.new(:title, :author_name, :body, :secret, :written_on, :cost)
  Post.class_eval do
    alias_method :title_before_type_cast, :title unless respond_to?(:title_before_type_cast)
    alias_method :body_before_type_cast, :body unless respond_to?(:body_before_type_cast)
    alias_method :author_name_before_type_cast, :author_name unless respond_to?(:author_name_before_type_cast)
9
    
10 11 12 13 14 15 16 17
    def new_record=(boolean)
      @new_record = boolean
    end
    
    def new_record?
      @new_record
    end
  end
18 19 20 21 22 23 24 25 26 27

  class Comment
    attr_reader :id
    attr_reader :post_id
    def save; @id = 1; @post_id = 1 end
    def new_record?; @id.nil? end
    def name
      @id.nil? ? 'new comment' : "comment ##{@id}"
    end
  end
28 29
end

30 31 32
class Comment::Nested < Comment; end


D
Initial  
David Heinemeier Hansson 已提交
33 34
class FormHelperTest < Test::Unit::TestCase
  include ActionView::Helpers::FormHelper
35 36 37 38
  include ActionView::Helpers::FormTagHelper
  include ActionView::Helpers::UrlHelper
  include ActionView::Helpers::TagHelper
  include ActionView::Helpers::TextHelper
39
  include ActionView::Helpers::ActiveRecordHelper
40
  include ActionView::Helpers::RecordIdentificationHelper
41
  include ActionController::PolymorphicRoutes
D
Initial  
David Heinemeier Hansson 已提交
42 43

  def setup
44
    @post = Post.new
45
    @comment = Comment.new
46 47 48 49 50 51 52 53
    def @post.errors() 
      Class.new{ 
        def on(field); "can't be empty" if field == "author_name"; end 
        def empty?() false end 
        def count() 1 end
        def full_messages() [ "Author name can't be empty" ] end  
      }.new 
    end
54
    def @post.id; 123; end
55
    def @post.id_before_type_cast; 123; end
56
    def @post.to_param; '123'; end
57

D
Initial  
David Heinemeier Hansson 已提交
58 59 60 61 62
    @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)
63 64

    @controller = Class.new do
65
      attr_reader :url_for_options
66
      def url_for(options)
67
        @url_for_options = options
68 69 70 71
        "http://www.example.com"
      end
    end
    @controller = @controller.new
D
Initial  
David Heinemeier Hansson 已提交
72 73
  end

74 75 76 77 78 79 80 81 82 83 84 85 86
  def test_label
    assert_dom_equal('<label for="post_title">Title</label>', label("post", "title"))
    assert_dom_equal('<label for="post_title">The title goes here</label>', label("post", "title", "The title goes here"))
    assert_dom_equal(
      '<label class="title_label" for="post_title">Title</label>',
      label("post", "title", nil, :class => 'title_label')
    )
  end
  
  def test_label_with_symbols
    assert_dom_equal('<label for="post_title">Title</label>', label(:post, :title))
  end

D
Initial  
David Heinemeier Hansson 已提交
87
  def test_text_field
88
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
89 90
      '<input id="post_title" name="post[title]" size="30" type="text" value="Hello World" />', text_field("post", "title")
    )
91
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
92 93
      '<input id="post_title" name="post[title]" size="30" type="password" value="Hello World" />', password_field("post", "title")
    )
94
    assert_dom_equal(
95
      '<input id="person_name" name="person[name]" size="30" type="password" />', password_field("person", "name")
D
Initial  
David Heinemeier Hansson 已提交
96 97 98 99 100
    )
  end

  def test_text_field_with_escapes
    @post.title = "<b>Hello World</b>"
101
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
102 103 104 105 106
      '<input id="post_title" name="post[title]" size="30" type="text" value="&lt;b&gt;Hello World&lt;/b&gt;" />', text_field("post", "title")
    )
  end

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

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

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

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

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
  def test_hidden_field
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Hello World" />',
      hidden_field("post", "title")
  end

  def test_hidden_field_with_escapes
    @post.title = "<b>Hello World</b>"
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="&lt;b&gt;Hello World&lt;/b&gt;" />',
      hidden_field("post", "title")
  end

  def test_text_field_with_options
    assert_dom_equal '<input id="post_title" name="post[title]" type="hidden" value="Something Else" />',
      hidden_field("post", "title", :value => "Something Else")
  end

D
Initial  
David Heinemeier Hansson 已提交
147
  def test_check_box
148
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
149 150 151 152
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
    @post.secret = 0
153
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
154
      '<input id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
155
      check_box("post", "secret")
D
Initial  
David Heinemeier Hansson 已提交
156
    )
157
    assert_dom_equal(
158
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
159 160
      check_box("post", "secret" ,{"checked"=>"checked"})
    )
D
Initial  
David Heinemeier Hansson 已提交
161
    @post.secret = true
162
    assert_dom_equal(
D
Initial  
David Heinemeier Hansson 已提交
163 164 165 166
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="0" />',
      check_box("post", "secret")
    )
  end
167

168 169
  def test_check_box_with_explicit_checked_and_unchecked_values
    @post.secret = "on"
170
    assert_dom_equal(
171 172 173 174
      '<input checked="checked" id="post_secret" name="post[secret]" type="checkbox" value="on" /><input name="post[secret]" type="hidden" value="off" />',
      check_box("post", "secret", {}, "on", "off")
    )
  end
175

176 177 178 179 180 181 182
  def test_checkbox_disabled_still_submits_checked_value
    assert_dom_equal(
      '<input checked="checked" disabled="disabled" id="post_secret" name="post[secret]" type="checkbox" value="1" /><input name="post[secret]" type="hidden" value="1" />',
      check_box("post", "secret", { :disabled => :true })
    )
  end

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

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

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

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

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

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

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

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

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

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

  def test_form_for
    _erbout = ''

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

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

    assert_dom_equal expected, _erbout
  end

  def test_form_for_with_method
    _erbout = ''

    form_for(:post, @post, :html => { :id => 'create-post', :method => :put }) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

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

    assert_dom_equal expected, _erbout
  end

347 348 349
  def test_form_for_without_object
    _erbout = ''

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

    expected = 
357
      "<form action='http://www.example.com' id='create-post' method='post'>" +
358 359 360 361 362 363 364 365
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />" +
      "</form>"

    assert_dom_equal expected, _erbout
  end
366

367 368
  def test_form_for_with_index
    _erbout = ''
369

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

377 378
    expected = 
      "<form action='http://www.example.com' method='post'>" +
379
      "<label for=\"post_123_title\">Title</label>" +
380 381 382
      "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
      "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
383 384
      "<input name='post[123][secret]' type='hidden' value='0' />" +
      "</form>"
385 386 387 388

    assert_dom_equal expected, _erbout
  end

389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
  def test_form_for_with_nil_index_option_override
    _erbout = ''

    form_for("post[]", @post, :index => nil) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

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

    assert_dom_equal expected, _erbout
  end

409 410 411 412 413 414 415 416 417 418 419 420 421
  def test_nested_fields_for
    _erbout = ''
    form_for(:post, @post) do |f|
      f.fields_for(:comment, @post) do |c|
        _erbout.concat c.text_field(:title)
      end
    end

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

    assert_dom_equal expected, _erbout
422
  end
423

424 425 426
  def test_fields_for
    _erbout = ''

427
    fields_for(:post, @post) do |f|
428 429 430 431 432 433 434 435 436 437 438 439
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected = 
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493
  end

  def test_fields_for_with_index
    _erbout = ''

    fields_for("post[]", @post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected =
      "<input name='post[123][title]' size='30' type='text' id='post_123_title' value='Hello World' />" +
      "<textarea name='post[123][body]' id='post_123_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[123][secret]' checked='checked' type='checkbox' id='post_123_secret' value='1' />" +
      "<input name='post[123][secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_nil_index_option_override
    _erbout = ''

    fields_for("post[]", @post, :index => nil) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected =
      "<input name='post[][title]' size='30' type='text' id='post__title' value='Hello World' />" +
      "<textarea name='post[][body]' id='post__body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[][secret]' checked='checked' type='checkbox' id='post__secret' value='1' />" +
      "<input name='post[][secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_index_option_override
    _erbout = ''

    fields_for("post[]", @post, :index => "abc") do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected =
      "<input name='post[abc][title]' size='30' type='text' id='post_abc_title' value='Hello World' />" +
      "<textarea name='post[abc][body]' id='post_abc_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[abc][secret]' checked='checked' type='checkbox' id='post_abc_secret' value='1' />" +
      "<input name='post[abc][secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
494
  end
495 496 497 498 499 500 501 502 503 504 505 506 507

  def test_fields_for_without_object
    _erbout = ''
    fields_for(:post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected = 
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524
      "<input name='post[secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

  def test_fields_for_with_only_object
    _erbout = ''
    fields_for(@post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected = 
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
525 526 527 528 529
      "<input name='post[secret]' type='hidden' value='0' />"

    assert_dom_equal expected, _erbout
  end

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

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

542 543 544
  def test_form_builder_does_not_have_form_for_method
    assert ! ActionView::Helpers::FormBuilder.instance_methods.include?('form_for')
  end
545

546 547 548
  def test_form_for_and_fields_for
    _erbout = ''

549
    form_for(:post, @post, :html => { :id => 'create-post' }) do |post_form|
550 551 552
      _erbout.concat post_form.text_field(:title)
      _erbout.concat post_form.text_area(:body)

553
      fields_for(:parent_post, @post) do |parent_fields|
554 555 556 557 558
        _erbout.concat parent_fields.check_box(:secret)
      end
    end

    expected = 
559
      "<form action='http://www.example.com' id='create-post' method='post'>" +
560 561 562 563 564 565 566 567
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='parent_post[secret]' checked='checked' type='checkbox' id='parent_post_secret' value='1' />" +
      "<input name='parent_post[secret]' type='hidden' value='0' />" +
      "</form>"

    assert_dom_equal expected, _erbout
  end
568

569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590
  def test_form_for_and_fields_for_with_object
    _erbout = ''

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

      post_form.fields_for(@comment) do |comment_fields|
        _erbout.concat comment_fields.text_field(:name)
      end
    end

    expected = 
      "<form action='http://www.example.com' id='create-post' method='post'>" +
      "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
      "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
      "<input name='post[comment][name]' type='text' id='post_comment_name' value='new comment' size='30' />" +
      "</form>"

    assert_dom_equal expected, _erbout
  end

591
  class LabelledFormBuilder < ActionView::Helpers::FormBuilder
592 593 594 595 596 597 598 599 600
    (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
601

602 603 604
  def test_form_for_with_labelled_builder
    _erbout = ''

605
    form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
606 607 608 609 610 611 612 613 614 615 616 617 618 619 620
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected = 
      "<form action='http://www.example.com' method='post'>" +
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>" +
      "</form>"

    assert_dom_equal expected, _erbout
  end
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644

  def test_default_form_builder
    old_default_form_builder, ActionView::Base.default_form_builder =
      ActionView::Base.default_form_builder, LabelledFormBuilder

    _erbout = ''
    form_for(:post, @post) do |f|
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end

    expected = 
      "<form action='http://www.example.com' method='post'>" +
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>" +
      "</form>"

    assert_dom_equal expected, _erbout
  ensure
    ActionView::Base.default_form_builder = old_default_form_builder
  end
645

646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661
  def test_default_form_builder_with_active_record_helpers
     
    _erbout = '' 
    form_for(:post, @post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
    end    
    
    expected = %(<form action='http://www.example.com' method='post'>) + 
               %(<div class='formError'>can't be empty</div>) + 
               %(<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>)
    
    assert_dom_equal expected, _erbout

  end
662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680
  
  def test_default_form_builder_no_instance_variable
    post = @post
    @post = nil
    
    _erbout = '' 
    form_for(:post, post) do |f|
       _erbout.concat f.error_message_on('author_name')
       _erbout.concat f.error_messages
    end    
    
    expected = %(<form action='http://www.example.com' method='post'>) + 
               %(<div class='formError'>can't be empty</div>) + 
               %(<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>)
    
    assert_dom_equal expected, _erbout
    
  end
681

682 683 684 685 686
  # Perhaps this test should be moved to prototype helper tests.
  def test_remote_form_for_with_labelled_builder
    self.extend ActionView::Helpers::PrototypeHelper
     _erbout = ''

687
     remote_form_for(:post, @post, :builder => LabelledFormBuilder) do |f|
688 689 690 691 692 693
       _erbout.concat f.text_field(:title)
       _erbout.concat f.text_area(:body)
       _erbout.concat f.check_box(:secret)
     end

     expected = 
694
       %(<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">) +
695 696 697 698 699 700 701 702 703 704 705
       "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
       "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
       "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
       "<input name='post[secret]' type='hidden' value='0' /><br/>" +
       "</form>"

     assert_dom_equal expected, _erbout
  end
   
  def test_fields_for_with_labelled_builder
    _erbout = ''
706 707
    
    fields_for(:post, @post, :builder => LabelledFormBuilder) do |f|
708 709 710 711
      _erbout.concat f.text_field(:title)
      _erbout.concat f.text_area(:body)
      _erbout.concat f.check_box(:secret)
    end
712
    
713 714 715 716 717
    expected = 
      "<label for='title'>Title:</label> <input name='post[title]' size='30' type='text' id='post_title' value='Hello World' /><br/>" +
      "<label for='body'>Body:</label> <textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea><br/>" +
      "<label for='secret'>Secret:</label> <input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />" +
      "<input name='post[secret]' type='hidden' value='0' /><br/>"
718
    
719 720
    assert_dom_equal expected, _erbout
  end
721

722 723 724 725 726 727 728 729
  def test_form_for_with_html_options_adds_options_to_form_tag
    _erbout = ''
    
    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>"
    
    assert_dom_equal expected, _erbout
  end
730

731 732 733 734 735
  def test_form_for_with_string_url_option
    _erbout = ''

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

736
    assert_equal '<form action="http://www.otherdomain.com" method="post"></form>', _erbout
737 738 739 740 741 742 743 744 745 746
  end

  def test_form_for_with_hash_url_option
    _erbout = ''

    form_for(:post, @post, :url => {:controller => 'controller', :action => 'action'}) do |f| end

    assert_equal 'controller', @controller.url_for_options[:controller]
    assert_equal 'action', @controller.url_for_options[:action]
  end
747

748 749 750 751 752 753
  def test_form_for_with_record_url_option
    _erbout = ''

    form_for(:post, @post, :url => @post) do |f| end

    expected = "<form action=\"/posts/123\" method=\"post\"></form>"
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
    assert_equal expected, _erbout
  end

  def test_form_for_with_existing_object
    _erbout = ''

    form_for(@post) do |f| end

    expected = "<form action=\"/posts/123\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
    assert_equal expected, _erbout
  end

  def test_form_for_with_new_object
    _erbout = ''

    post = Post.new
    post.new_record = true
    def post.id() nil end

    form_for(post) do |f| end

    expected = "<form action=\"/posts\" class=\"new_post\" id=\"new_post\" method=\"post\"></form>"
    assert_equal expected, _erbout
  end

779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
  def test_form_for_with_existing_object_in_list
    @post.new_record = false
    @comment.save
    _erbout = ''
    form_for([@post, @comment]) {}

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

  def test_form_for_with_new_object_in_list
    @post.new_record = false
    _erbout = ''
    form_for([@post, @comment]) {}

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

798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
  def test_form_for_with_existing_object_and_namespace_in_list
    @post.new_record = false
    @comment.save
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
  
    expected = %(<form action="#{admin_comment_path(@post, @comment)}" class="edit_comment" id="edit_comment_1" method="post"><div style="margin:0;padding:0"><input name="_method" type="hidden" value="put" /></div></form>)
    assert_dom_equal expected, _erbout
  end
  
  def test_form_for_with_new_object_and_namespace_in_list
    @post.new_record = false
    _erbout = ''
    form_for([:admin, @post, @comment]) {}
  
    expected = %(<form action="#{admin_comments_path(@post)}" class="new_comment" id="new_comment" method="post"></form>)
    assert_dom_equal expected, _erbout
  end

817 818 819 820 821 822 823
  def test_form_for_with_existing_object_and_custom_url
    _erbout = ''

    form_for(@post, :url => "/super_posts") do |f| end

    expected = "<form action=\"/super_posts\" class=\"edit_post\" id=\"edit_post_123\" method=\"post\"><div style=\"margin:0;padding:0\"><input name=\"_method\" type=\"hidden\" value=\"put\" /></div></form>"
    assert_equal expected, _erbout
824
  end
825

826 827 828 829 830 831 832 833 834
  def test_remote_form_for_with_html_options_adds_options_to_form_tag
    self.extend ActionView::Helpers::PrototypeHelper
    _erbout = ''
    
    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>"
    
    assert_dom_equal expected, _erbout
  end
835 836 837


  protected
838 839 840
    def comments_path(post)
      "/posts/#{post.id}/comments"
    end
841
    alias_method :post_comments_path, :comments_path
842 843 844 845

    def comment_path(post, comment)
      "/posts/#{post.id}/comments/#{comment.id}"
    end
846 847
    alias_method :post_comment_path, :comment_path
    
848 849 850 851 852 853 854 855 856 857
    def admin_comments_path(post)
      "/admin/posts/#{post.id}/comments"
    end
    alias_method :admin_post_comments_path, :admin_comments_path
    
    def admin_comment_path(post, comment)
      "/admin/posts/#{post.id}/comments/#{comment.id}"
    end
    alias_method :admin_post_comment_path, :admin_comment_path
    
858 859 860 861 862 863
    def posts_path
      "/posts"
    end 
    
    def post_path(post)
      "/posts/#{post.id}"
864
    end
865 866 867

    def protect_against_forgery?
      false
868
    end
869
end