formtastic-bootstrap 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +12 -0
  4. data/Gemfile.lock +123 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +159 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/formtastic-bootstrap.gemspec +128 -0
  10. data/lib/action_view/helpers/text_field_date_helper.rb +166 -0
  11. data/lib/formtastic-bootstrap.rb +5 -0
  12. data/lib/formtastic-bootstrap/form_builder.rb +38 -0
  13. data/lib/formtastic-bootstrap/helpers.rb +19 -0
  14. data/lib/formtastic-bootstrap/helpers/buttons_helper.rb +47 -0
  15. data/lib/formtastic-bootstrap/helpers/fieldset_wrapper.rb +37 -0
  16. data/lib/formtastic-bootstrap/helpers/input_helper.rb +12 -0
  17. data/lib/formtastic-bootstrap/helpers/inputs_helper.rb +36 -0
  18. data/lib/formtastic-bootstrap/inputs.rb +28 -0
  19. data/lib/formtastic-bootstrap/inputs/base.rb +22 -0
  20. data/lib/formtastic-bootstrap/inputs/base/choices.rb +49 -0
  21. data/lib/formtastic-bootstrap/inputs/base/errors.rb +48 -0
  22. data/lib/formtastic-bootstrap/inputs/base/hints.rb +27 -0
  23. data/lib/formtastic-bootstrap/inputs/base/html.rb +21 -0
  24. data/lib/formtastic-bootstrap/inputs/base/labelling.rb +18 -0
  25. data/lib/formtastic-bootstrap/inputs/base/stringish.rb +18 -0
  26. data/lib/formtastic-bootstrap/inputs/base/timeish.rb +35 -0
  27. data/lib/formtastic-bootstrap/inputs/base/wrapping.rb +56 -0
  28. data/lib/formtastic-bootstrap/inputs/boolean_input.rb +33 -0
  29. data/lib/formtastic-bootstrap/inputs/check_boxes_input.rb +35 -0
  30. data/lib/formtastic-bootstrap/inputs/date_input.rb +16 -0
  31. data/lib/formtastic-bootstrap/inputs/datetime_input.rb +19 -0
  32. data/lib/formtastic-bootstrap/inputs/email_input.rb +15 -0
  33. data/lib/formtastic-bootstrap/inputs/file_input.rb +14 -0
  34. data/lib/formtastic-bootstrap/inputs/hidden_input.rb +12 -0
  35. data/lib/formtastic-bootstrap/inputs/number_input.rb +15 -0
  36. data/lib/formtastic-bootstrap/inputs/password_input.rb +15 -0
  37. data/lib/formtastic-bootstrap/inputs/phone_input.rb +15 -0
  38. data/lib/formtastic-bootstrap/inputs/radio_input.rb +32 -0
  39. data/lib/formtastic-bootstrap/inputs/range_input.rb +15 -0
  40. data/lib/formtastic-bootstrap/inputs/search_input.rb +15 -0
  41. data/lib/formtastic-bootstrap/inputs/select_input.rb +14 -0
  42. data/lib/formtastic-bootstrap/inputs/string_input.rb +15 -0
  43. data/lib/formtastic-bootstrap/inputs/text_input.rb +14 -0
  44. data/lib/formtastic-bootstrap/inputs/time_input.rb +16 -0
  45. data/lib/formtastic-bootstrap/inputs/url_input.rb +14 -0
  46. data/spec/builder/errors_spec.rb +214 -0
  47. data/spec/builder/semantic_fields_for_spec.rb +130 -0
  48. data/spec/helpers/input_helper_spec.rb +956 -0
  49. data/spec/helpers/inputs_helper_spec.rb +577 -0
  50. data/spec/inputs/boolean_input_spec.rb +193 -0
  51. data/spec/inputs/check_boxes_input_spec.rb +439 -0
  52. data/spec/inputs/date_input_spec.rb +147 -0
  53. data/spec/inputs/datetime_input_spec.rb +101 -0
  54. data/spec/inputs/email_input_spec.rb +59 -0
  55. data/spec/inputs/file_input_spec.rb +63 -0
  56. data/spec/inputs/hidden_input_spec.rb +122 -0
  57. data/spec/inputs/number_input_spec.rb +787 -0
  58. data/spec/inputs/password_input_spec.rb +73 -0
  59. data/spec/inputs/phone_input_spec.rb +59 -0
  60. data/spec/inputs/radio_input_spec.rb +240 -0
  61. data/spec/inputs/range_input_spec.rb +479 -0
  62. data/spec/inputs/search_input_spec.rb +59 -0
  63. data/spec/inputs/select_input_spec.rb +567 -0
  64. data/spec/inputs/string_input_spec.rb +182 -0
  65. data/spec/inputs/text_input_spec.rb +163 -0
  66. data/spec/inputs/time_input_spec.rb +206 -0
  67. data/spec/inputs/url_input_spec.rb +59 -0
  68. data/spec/spec_helper.rb +24 -0
  69. data/spec/support/custom_macros.rb +704 -0
  70. data/spec/support/depracation.rb +6 -0
  71. data/spec/support/formtastic_spec_helper.rb +382 -0
  72. metadata +204 -0
@@ -0,0 +1,577 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'Formtastic::FormBuilder#inputs' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ Formtastic::Helpers::FormHelper.builder = FormtasticBootstrap::FormBuilder
12
+ end
13
+
14
+ describe 'with a block (block forms syntax)' do
15
+
16
+ describe 'when no options are provided' do
17
+ before do
18
+ output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
19
+ concat(semantic_form_for(@new_post) do |builder|
20
+ @inputs_output = builder.inputs do
21
+ concat('hello')
22
+ end
23
+ end)
24
+ end
25
+
26
+ it 'should output just the content wrapped in inputs, not the whole template' do
27
+ output_buffer.should =~ /before_builder/
28
+ @inputs_output.should_not =~ /before_builder/
29
+ end
30
+
31
+ it 'should render a fieldset inside the form, with a class of "inputs"' do
32
+ output_buffer.should have_tag("form fieldset.inputs")
33
+ end
34
+
35
+ it 'should not render an ol inside the fieldset' do
36
+ # output_buffer.should have_tag("form fieldset.inputs ol")
37
+ output_buffer.should_not have_tag("form fieldset.inputs ol")
38
+ end
39
+
40
+ it 'should render the contents of the block inside the fieldset' do
41
+ # output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
42
+ output_buffer.should have_tag("form fieldset.inputs", /hello/)
43
+ end
44
+
45
+ it 'should not render a legend inside the fieldset' do
46
+ output_buffer.should_not have_tag("form fieldset.inputs legend")
47
+ end
48
+
49
+ it 'should render a fieldset even if no object is given' do
50
+ concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
51
+ @inputs_output = builder.inputs do
52
+ concat('bye')
53
+ end
54
+ end)
55
+ output_buffer.should have_tag("form fieldset.inputs", /bye/)
56
+ end
57
+ end
58
+
59
+ describe 'when a :for option is provided' do
60
+
61
+ before do
62
+ @new_post.stub!(:respond_to?).and_return(true, true)
63
+ @new_post.stub!(:author).and_return(@bob)
64
+ end
65
+
66
+ it 'should render nested inputs' do
67
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
68
+
69
+ concat(semantic_form_for(@new_post) do |builder|
70
+ inputs = builder.inputs :for => [:author, @bob] do |bob_builder|
71
+ concat(bob_builder.input(:login))
72
+ end
73
+ concat(inputs)
74
+ end)
75
+ output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
76
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
77
+ end
78
+
79
+ it 'should concat rendered nested inputs to the template' do
80
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
81
+
82
+ concat(semantic_form_for(@new_post) do |builder|
83
+ builder.inputs :for => [:author, @bob] do |bob_builder|
84
+ concat(bob_builder.input(:login))
85
+ end
86
+ end)
87
+
88
+ output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
89
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
90
+
91
+ end
92
+
93
+ describe "as a symbol representing the association name" do
94
+
95
+ it 'should nest the inputs with an _attributes suffix on the association name' do
96
+ concat(semantic_form_for(@new_post) do |post|
97
+ inputs = post.inputs :for => :author do |author|
98
+ concat(author.input(:login))
99
+ end
100
+ concat(inputs)
101
+ end)
102
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
103
+ end
104
+
105
+ end
106
+
107
+ describe "as a symbol representing a has_many association name" do
108
+ before do
109
+ @new_post.stub!(:authors).and_return([@bob, @fred])
110
+ @new_post.stub!(:authors_attributes=)
111
+ end
112
+
113
+ it 'should nest the inputs with a fieldset, legend and :name input for each item' do
114
+ concat(semantic_form_for(@new_post) do |post|
115
+ post.inputs :for => :authors, :name => '%i' do |author|
116
+ concat(author.input(:login))
117
+ end
118
+ end)
119
+
120
+ output_buffer.should have_tag("form fieldset.inputs", :count => 2)
121
+ output_buffer.should have_tag("form fieldset.inputs legend", :count => 2)
122
+ output_buffer.should have_tag("form fieldset.inputs legend", "1", :count => 1)
123
+ output_buffer.should have_tag("form fieldset.inputs legend", "2")
124
+ output_buffer.should have_tag("form input[@name='post[authors_attributes][0][login]']")
125
+ output_buffer.should have_tag("form input[@name='post[authors_attributes][1][login]']")
126
+ output_buffer.should_not have_tag('form fieldset[@name]')
127
+ end
128
+ end
129
+
130
+ describe 'as an array containing the a symbole for the association name and the associated object' do
131
+
132
+ it 'should nest the inputs with an _attributes suffix on the association name' do
133
+ concat(semantic_form_for(@new_post) do |post|
134
+ inputs = post.inputs :for => [:author, @new_post.author] do |author|
135
+ concat(author.input(:login))
136
+ end
137
+ concat(inputs)
138
+ end)
139
+ output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
140
+ end
141
+
142
+ end
143
+
144
+ describe 'as an associated object' do
145
+
146
+ it 'should not nest the inputs with an _attributes suffix' do
147
+ concat(semantic_form_for(@new_post) do |post|
148
+ inputs = post.inputs :for => @new_post.author do |author|
149
+ concat(author.input(:login))
150
+ end
151
+ concat(inputs)
152
+ end)
153
+ output_buffer.should have_tag("form input[@name='post[author][login]']")
154
+ end
155
+
156
+ end
157
+
158
+ it 'should raise an error if :for and block with no argument is given' do
159
+ semantic_form_for(@new_post) do |builder|
160
+ proc {
161
+ builder.inputs(:for => [:author, @bob]) do
162
+ #
163
+ end
164
+ }.should raise_error(ArgumentError, 'You gave :for option with a block to inputs method, ' <<
165
+ 'but the block does not accept any argument.')
166
+ end
167
+ end
168
+
169
+ it 'should pass options down to semantic_fields_for' do
170
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
171
+
172
+ concat(semantic_form_for(@new_post) do |builder|
173
+ inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
174
+ concat(bob_builder.input(:login))
175
+ end
176
+ concat(inputs)
177
+ end)
178
+
179
+ output_buffer.should have_tag('form fieldset div.clearfix div.input #post_author_attributes_10_login')
180
+ end
181
+
182
+ it 'should not add builder as a fieldset attribute tag' do
183
+ concat(semantic_form_for(@new_post) do |builder|
184
+ inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
185
+ concat('input')
186
+ end
187
+ concat(inputs)
188
+ end)
189
+
190
+ output_buffer.should_not have_tag('fieldset[@builder="Formtastic::Helpers::FormHelper"]')
191
+ end
192
+
193
+ it 'should send parent_builder as an option to allow child index interpolation' do
194
+ concat(semantic_form_for(@new_post) do |builder|
195
+ builder.instance_variable_set('@nested_child_index', 0)
196
+ inputs = builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
197
+ concat('input')
198
+ end
199
+ concat(inputs)
200
+ end)
201
+
202
+ output_buffer.should have_tag('fieldset legend', 'Author #1')
203
+ end
204
+
205
+ it 'should also provide child index interpolation when nested child index is a hash' do
206
+ concat(semantic_form_for(@new_post) do |builder|
207
+ builder.instance_variable_set('@nested_child_index', :author => 10)
208
+ inputs = builder.inputs :for => [:author, @bob], :name => 'Author #%i' do |bob_builder|
209
+ concat('input')
210
+ end
211
+ concat(inputs)
212
+ end)
213
+
214
+ output_buffer.should have_tag('fieldset legend', 'Author #11')
215
+ end
216
+ end
217
+
218
+ describe 'when a :name or :title option is provided' do
219
+ describe 'and is a string' do
220
+ before do
221
+ @legend_text = "Advanced options"
222
+ @legend_text_using_name = "Advanced options 2"
223
+ @legend_text_using_title = "Advanced options 3"
224
+ @nested_forms_legend_text = "This is a nested form title"
225
+ concat(semantic_form_for(@new_post) do |builder|
226
+ inputs = builder.inputs @legend_text do
227
+ end
228
+ concat(inputs)
229
+ inputs = builder.inputs :name => @legend_text_using_name do
230
+ end
231
+ concat(inputs)
232
+ inputs = builder.inputs :title => @legend_text_using_title do
233
+ end
234
+ concat(inputs)
235
+ inputs = builder.inputs @nested_forms_legend_text, :for => :authors do |nf|
236
+ end
237
+ concat(inputs)
238
+ end)
239
+ end
240
+
241
+ it 'should render a fieldset with a legend inside the form' do
242
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
243
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
244
+ output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_title}$/)
245
+ output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
246
+ end
247
+ end
248
+
249
+ describe 'and is a symbol' do
250
+ before do
251
+ @localized_legend_text = "Localized advanced options"
252
+ @localized_legend_text_using_name = "Localized advanced options 2"
253
+ @localized_legend_text_using_title = "Localized advanced options 3"
254
+ @localized_nested_forms_legend_text = "This is a localized nested form title"
255
+ ::I18n.backend.store_translations :en, :formtastic => {
256
+ :titles => {
257
+ :post => {
258
+ :advanced_options => @localized_legend_text,
259
+ :advanced_options_using_name => @localized_legend_text_using_name,
260
+ :advanced_options_using_title => @localized_legend_text_using_title,
261
+ :nested_forms_title => @localized_nested_forms_legend_text
262
+ }
263
+ }
264
+ }
265
+ concat(semantic_form_for(@new_post) do |builder|
266
+ inputs = builder.inputs :advanced_options do
267
+ end
268
+ concat(inputs)
269
+ inputs =builder.inputs :name => :advanced_options_using_name do
270
+ end
271
+ concat(inputs)
272
+ inputs = builder.inputs :title => :advanced_options_using_title do
273
+ end
274
+ concat(inputs)
275
+ inputs = builder.inputs :nested_forms_title, :for => :authors do |nf|
276
+ end
277
+ concat(inputs)
278
+ end)
279
+ end
280
+
281
+ it 'should render a fieldset with a localized legend inside the form' do
282
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
283
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
284
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_title}$/)
285
+ output_buffer.should have_tag("form fieldset legend", /^#{@localized_nested_forms_legend_text}$/)
286
+ end
287
+ end
288
+ end
289
+
290
+ describe 'when other options are provided' do
291
+ before do
292
+ @id_option = 'advanced'
293
+ @class_option = 'wide'
294
+
295
+ concat(semantic_form_for(@new_post) do |builder|
296
+ builder.inputs :id => @id_option, :class => @class_option do
297
+ end
298
+ end)
299
+ end
300
+
301
+ it 'should pass the options into the fieldset tag as attributes' do
302
+ output_buffer.should have_tag("form fieldset##{@id_option}")
303
+ output_buffer.should have_tag("form fieldset.#{@class_option}")
304
+ end
305
+ end
306
+
307
+ end
308
+
309
+ describe 'without a block' do
310
+
311
+ before do
312
+ ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
313
+ :comments => mock('reflection', :options => {}, :macro => :has_many) })
314
+ ::Author.stub!(:find).and_return([@fred, @bob])
315
+
316
+ @new_post.stub!(:title)
317
+ @new_post.stub!(:body)
318
+ @new_post.stub!(:author_id)
319
+
320
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
321
+ @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
322
+ @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
323
+ @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
324
+ end
325
+
326
+ describe 'with no args (quick forms syntax)' do
327
+ before do
328
+ concat(semantic_form_for(@new_post) do |builder|
329
+ concat(builder.inputs)
330
+ end)
331
+ end
332
+
333
+ it 'should render a form' do
334
+ output_buffer.should have_tag('form')
335
+ end
336
+
337
+ it 'should render a fieldset inside the form' do
338
+ output_buffer.should have_tag('form > fieldset.inputs')
339
+ end
340
+
341
+ it 'should not render a legend in the fieldset' do
342
+ output_buffer.should_not have_tag('form > fieldset.inputs > legend')
343
+ end
344
+
345
+ it 'should not render an ol in the fieldset' do
346
+ output_buffer.should_not have_tag('form > fieldset.inputs > ol')
347
+ end
348
+
349
+ it 'should render a div item in the ol for each column and reflection' do
350
+ # Remove the :has_many macro and :created_at column
351
+ count = ::Post.content_columns.size + ::Post.reflections.size - 2
352
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix', :count => count)
353
+ end
354
+
355
+ it 'should render a string list item for title' do
356
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.string')
357
+ end
358
+
359
+ it 'should render a text list item for body' do
360
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.text')
361
+ end
362
+
363
+ it 'should render a select list item for author_id' do
364
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.select', :count => 1)
365
+ end
366
+
367
+ it 'should not render timestamps inputs by default' do
368
+ output_buffer.should_not have_tag('form > fieldset.inputs > div.clearfix.datetime')
369
+ end
370
+
371
+ context "with a polymorphic association" do
372
+
373
+ before do
374
+ @new_post.stub!(:commentable)
375
+ @new_post.class.stub!(:reflections).and_return({
376
+ :commentable => mock('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
377
+ })
378
+ @new_post.stub!(:column_for_attribute).with(:commentable).and_return(
379
+ mock('column', :type => :integer)
380
+ )
381
+ end
382
+
383
+ it 'should not render an input for the polymorphic association (the collection class cannot be guessed)' do
384
+ concat(semantic_form_for(@new_post) do |builder|
385
+ concat(builder.inputs)
386
+ end)
387
+ output_buffer.should_not have_tag('li#post_commentable_input')
388
+ end
389
+
390
+ end
391
+ end
392
+
393
+ describe 'with column names as args (short hand forms syntax)' do
394
+ describe 'and an object is given' do
395
+ it 'should render a form with a fieldset containing two list items' do
396
+ concat(semantic_form_for(@new_post) do |builder|
397
+ concat(builder.inputs(:title, :body))
398
+ end)
399
+
400
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix', :count => 2)
401
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.string')
402
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.text')
403
+ end
404
+ end
405
+
406
+ describe 'and no object is given' do
407
+ it 'should render a form with a fieldset containing two list items' do
408
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
409
+ concat(builder.inputs(:title, :body))
410
+ end)
411
+
412
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix.string', :count => 2)
413
+ end
414
+ end
415
+
416
+ context "with a polymorphic association" do
417
+
418
+ it 'should raise an error for polymorphic associations (the collection class cannot be guessed)' do
419
+ @new_post.stub!(:commentable)
420
+ @new_post.class.stub!(:reflections).and_return({
421
+ :commentable => mock('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
422
+ })
423
+ @new_post.stub!(:column_for_attribute).with(:commentable).and_return(
424
+ mock('column', :type => :integer)
425
+ )
426
+ @new_post.class.stub!(:reflect_on_association).with(:commentable).and_return(
427
+ mock('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
428
+ )
429
+
430
+ expect {
431
+ concat(semantic_form_for(@new_post) do |builder|
432
+ concat(builder.inputs :commentable)
433
+ end)
434
+ }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
435
+ end
436
+
437
+ end
438
+
439
+ end
440
+
441
+ describe 'when a :for option is provided' do
442
+ describe 'and an object is given' do
443
+ it 'should render nested inputs' do
444
+ @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
445
+ concat(semantic_form_for(@new_post) do |builder|
446
+ concat(builder.inputs(:login, :for => @bob))
447
+ end)
448
+
449
+ output_buffer.should have_tag("form fieldset.inputs #post_author_login")
450
+ output_buffer.should_not have_tag("form fieldset.inputs #author_login")
451
+ end
452
+ end
453
+
454
+ describe 'and no object is given' do
455
+ it 'should render nested inputs' do
456
+ concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
457
+ concat(builder.inputs(:login, :for => @bob))
458
+ end)
459
+ output_buffer.should have_tag("form fieldset.inputs #project_author_login")
460
+ output_buffer.should_not have_tag("form fieldset.inputs #project_login")
461
+ end
462
+ end
463
+ end
464
+
465
+ describe 'with column names and an options hash as args' do
466
+ before do
467
+ concat(semantic_form_for(@new_post) do |builder|
468
+ @legend_text_using_option = "Legendary Legend Text"
469
+ @legend_text_using_arg = "Legendary Legend Text 2"
470
+ concat(builder.inputs(:title, :body, :name => @legend_text_using_option, :id => "my-id"))
471
+ concat(builder.inputs(@legend_text_using_arg, :title, :body, :id => "my-id-2"))
472
+ end)
473
+ end
474
+
475
+ it 'should render a form with a fieldset containing two list items' do
476
+ output_buffer.should have_tag('form > fieldset.inputs > div.clearfix', :count => 4)
477
+ end
478
+
479
+ it 'should pass the options down to the fieldset' do
480
+ output_buffer.should have_tag('form > fieldset#my-id.inputs')
481
+ end
482
+
483
+ it 'should use the special :name option as a text for the legend tag' do
484
+ output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
485
+ output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
486
+ end
487
+ end
488
+
489
+ end
490
+
491
+ describe 'nesting' do
492
+
493
+ context "when not nested" do
494
+ it "should not wrap the inputs in an li block" do
495
+ concat(semantic_form_for(@new_post) do |builder|
496
+ concat(builder.inputs do
497
+ end)
498
+ end)
499
+ output_buffer.should_not have_tag('form > li')
500
+ end
501
+ end
502
+
503
+ context "when nested (with block)" do
504
+ it "should wrap the nested inputs in an li block to maintain HTML validity" do
505
+ concat(semantic_form_for(@new_post) do |builder|
506
+ concat(builder.inputs do
507
+ concat(builder.inputs do
508
+ end)
509
+ end)
510
+ end)
511
+ output_buffer.should have_tag('form > fieldset.inputs > fieldset.inputs')
512
+ end
513
+ end
514
+
515
+ context "when nested (with block and :for)" do
516
+ it "should wrap the nested inputs in an li block to maintain HTML validity" do
517
+ concat(semantic_form_for(@new_post) do |builder|
518
+ concat(builder.inputs do
519
+ concat(builder.inputs(:for => :author) do |author_builder|
520
+ end)
521
+ end)
522
+ end)
523
+ output_buffer.should have_tag('form > fieldset.inputs > fieldset.inputs')
524
+ end
525
+ end
526
+
527
+ context "when nested (without block)" do
528
+ it "should wrap the nested inputs in an li block to maintain HTML validity" do
529
+ concat(semantic_form_for(@new_post) do |builder|
530
+ concat(builder.inputs do
531
+ concat(builder.inputs(:title))
532
+ end)
533
+ end)
534
+ output_buffer.should have_tag('form > fieldset.inputs > fieldset.inputs')
535
+ end
536
+ end
537
+
538
+ context "when nested (without block, with :for)" do
539
+ it "should wrap the nested inputs in an li block to maintain HTML validity" do
540
+ concat(semantic_form_for(@new_post) do |builder|
541
+ concat(builder.inputs do
542
+ concat(builder.inputs(:name, :for => :author))
543
+ end)
544
+ end)
545
+ output_buffer.should have_tag('form > fieldset.inputs > fieldset.inputs')
546
+ end
547
+ end
548
+
549
+ context "when double nested" do
550
+ it "should wrap the nested inputs in an li block to maintain HTML validity" do
551
+ concat(semantic_form_for(@new_post) do |builder|
552
+ concat(builder.inputs do
553
+ concat(builder.inputs do
554
+ concat(builder.inputs do
555
+ end)
556
+ end)
557
+ end)
558
+ end)
559
+ output_buffer.should have_tag('form > fieldset.inputs > fieldset.inputs > fieldset.inputs')
560
+ end
561
+ end
562
+
563
+ end
564
+
565
+ describe 'when using MongoMapper associations ' do
566
+ def generate_form
567
+ semantic_form_for(@new_mm_post) do |builder|
568
+ builder.inputs :title, :sub_posts
569
+ end
570
+ end
571
+ it "should throw PolymorphicInputWithoutCollectionError on sub_posts" do
572
+ ::MongoPost.should_receive(:associations).at_least(3).times
573
+ expect { generate_form }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
574
+ end
575
+ end
576
+
577
+ end