formtastic-bootstrap 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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