formtastic 2.0.0.rc3 → 2.0.0.rc4

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 (43) hide show
  1. data/.travis.yml +7 -0
  2. data/CHANGELOG +26 -0
  3. data/Gemfile +2 -0
  4. data/README.textile +0 -1
  5. data/RELEASE_PROCESS +0 -1
  6. data/Rakefile +1 -1
  7. data/app/assets/stylesheets/formtastic.css +3 -3
  8. data/app/assets/stylesheets/formtastic_ie6.css +7 -1
  9. data/app/assets/stylesheets/formtastic_ie7.css +7 -1
  10. data/formtastic.gemspec +0 -15
  11. data/lib/formtastic/form_builder.rb +2 -0
  12. data/lib/formtastic/helpers/errors_helper.rb +22 -0
  13. data/lib/formtastic/helpers/form_helper.rb +18 -16
  14. data/lib/formtastic/helpers/input_helper.rb +9 -7
  15. data/lib/formtastic/helpers/inputs_helper.rb +11 -3
  16. data/lib/formtastic/helpers/reflection.rb +5 -1
  17. data/lib/formtastic/inputs/base/collections.rb +7 -0
  18. data/lib/formtastic/inputs/base/html.rb +1 -1
  19. data/lib/formtastic/inputs/base/timeish.rb +7 -2
  20. data/lib/formtastic/inputs/base/validations.rb +39 -8
  21. data/lib/formtastic/inputs/check_boxes_input.rb +3 -3
  22. data/lib/formtastic/inputs/file_input.rb +4 -4
  23. data/lib/formtastic/inputs/number_input.rb +1 -1
  24. data/lib/formtastic/inputs/radio_input.rb +1 -1
  25. data/lib/formtastic/inputs/time_input.rb +25 -3
  26. data/lib/formtastic/version.rb +1 -1
  27. data/lib/generators/templates/formtastic.rb +10 -1
  28. data/spec/builder/errors_spec.rb +10 -0
  29. data/spec/builder/semantic_fields_for_spec.rb +77 -36
  30. data/spec/helpers/form_helper_spec.rb +32 -0
  31. data/spec/helpers/input_helper_spec.rb +196 -102
  32. data/spec/helpers/inputs_helper_spec.rb +85 -73
  33. data/spec/helpers/reflection_helper_spec.rb +32 -0
  34. data/spec/inputs/check_boxes_input_spec.rb +21 -6
  35. data/spec/inputs/date_input_spec.rb +20 -0
  36. data/spec/inputs/datetime_input_spec.rb +30 -11
  37. data/spec/inputs/label_spec.rb +8 -0
  38. data/spec/inputs/number_input_spec.rb +298 -2
  39. data/spec/inputs/radio_input_spec.rb +5 -6
  40. data/spec/inputs/string_input_spec.rb +22 -5
  41. data/spec/inputs/time_input_spec.rb +51 -7
  42. data/spec/spec_helper.rb +64 -12
  43. metadata +11 -9
@@ -11,7 +11,7 @@ describe 'Formtastic::FormBuilder#inputs' do
11
11
  end
12
12
 
13
13
  describe 'with a block (block forms syntax)' do
14
-
14
+
15
15
  describe 'when no options are provided' do
16
16
  before do
17
17
  output_buffer.replace 'before_builder' # clear the output buffer and sets before_builder
@@ -21,28 +21,28 @@ describe 'Formtastic::FormBuilder#inputs' do
21
21
  end
22
22
  end)
23
23
  end
24
-
24
+
25
25
  it 'should output just the content wrapped in inputs, not the whole template' do
26
26
  output_buffer.should =~ /before_builder/
27
27
  @inputs_output.should_not =~ /before_builder/
28
28
  end
29
-
29
+
30
30
  it 'should render a fieldset inside the form, with a class of "inputs"' do
31
31
  output_buffer.should have_tag("form fieldset.inputs")
32
32
  end
33
-
33
+
34
34
  it 'should render an ol inside the fieldset' do
35
35
  output_buffer.should have_tag("form fieldset.inputs ol")
36
36
  end
37
-
37
+
38
38
  it 'should render the contents of the block inside the ol' do
39
39
  output_buffer.should have_tag("form fieldset.inputs ol", /hello/)
40
40
  end
41
-
41
+
42
42
  it 'should not render a legend inside the fieldset' do
43
43
  output_buffer.should_not have_tag("form fieldset.inputs legend")
44
44
  end
45
-
45
+
46
46
  it 'should render a fieldset even if no object is given' do
47
47
  concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
48
48
  @inputs_output = builder.inputs do
@@ -52,17 +52,17 @@ describe 'Formtastic::FormBuilder#inputs' do
52
52
  output_buffer.should have_tag("form fieldset.inputs ol", /bye/)
53
53
  end
54
54
  end
55
-
55
+
56
56
  describe 'when a :for option is provided' do
57
-
57
+
58
58
  before do
59
59
  @new_post.stub!(:respond_to?).and_return(true, true)
60
60
  @new_post.stub!(:author).and_return(@bob)
61
61
  end
62
-
62
+
63
63
  it 'should render nested inputs' do
64
64
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
65
-
65
+
66
66
  concat(semantic_form_for(@new_post) do |builder|
67
67
  inputs = builder.inputs :for => [:author, @bob] do |bob_builder|
68
68
  concat(bob_builder.input(:login))
@@ -72,23 +72,23 @@ describe 'Formtastic::FormBuilder#inputs' do
72
72
  output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
73
73
  output_buffer.should_not have_tag("form fieldset.inputs #author_login")
74
74
  end
75
-
75
+
76
76
  it 'should concat rendered nested inputs to the template' do
77
77
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
78
-
78
+
79
79
  concat(semantic_form_for(@new_post) do |builder|
80
80
  builder.inputs :for => [:author, @bob] do |bob_builder|
81
81
  concat(bob_builder.input(:login))
82
82
  end
83
83
  end)
84
-
84
+
85
85
  output_buffer.should have_tag("form fieldset.inputs #post_author_attributes_login")
86
86
  output_buffer.should_not have_tag("form fieldset.inputs #author_login")
87
-
87
+
88
88
  end
89
-
89
+
90
90
  describe "as a symbol representing the association name" do
91
-
91
+
92
92
  it 'should nest the inputs with an _attributes suffix on the association name' do
93
93
  concat(semantic_form_for(@new_post) do |post|
94
94
  inputs = post.inputs :for => :author do |author|
@@ -98,15 +98,15 @@ describe 'Formtastic::FormBuilder#inputs' do
98
98
  end)
99
99
  output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
100
100
  end
101
-
101
+
102
102
  end
103
-
103
+
104
104
  describe "as a symbol representing a has_many association name" do
105
105
  before do
106
106
  @new_post.stub!(:authors).and_return([@bob, @fred])
107
107
  @new_post.stub!(:authors_attributes=)
108
108
  end
109
-
109
+
110
110
  it 'should nest the inputs with a fieldset, legend and :name input for each item' do
111
111
  concat(semantic_form_for(@new_post) do |post|
112
112
  post.inputs :for => :authors, :name => '%i' do |author|
@@ -123,9 +123,9 @@ describe 'Formtastic::FormBuilder#inputs' do
123
123
  output_buffer.should_not have_tag('form fieldset[@name]')
124
124
  end
125
125
  end
126
-
126
+
127
127
  describe 'as an array containing the a symbole for the association name and the associated object' do
128
-
128
+
129
129
  it 'should nest the inputs with an _attributes suffix on the association name' do
130
130
  concat(semantic_form_for(@new_post) do |post|
131
131
  inputs = post.inputs :for => [:author, @new_post.author] do |author|
@@ -135,11 +135,11 @@ describe 'Formtastic::FormBuilder#inputs' do
135
135
  end)
136
136
  output_buffer.should have_tag("form input[@name='post[author_attributes][login]']")
137
137
  end
138
-
138
+
139
139
  end
140
-
140
+
141
141
  describe 'as an associated object' do
142
-
142
+
143
143
  it 'should not nest the inputs with an _attributes suffix' do
144
144
  concat(semantic_form_for(@new_post) do |post|
145
145
  inputs = post.inputs :for => @new_post.author do |author|
@@ -149,9 +149,9 @@ describe 'Formtastic::FormBuilder#inputs' do
149
149
  end)
150
150
  output_buffer.should have_tag("form input[@name='post[author][login]']")
151
151
  end
152
-
152
+
153
153
  end
154
-
154
+
155
155
  it 'should raise an error if :for and block with no argument is given' do
156
156
  semantic_form_for(@new_post) do |builder|
157
157
  proc {
@@ -162,20 +162,20 @@ describe 'Formtastic::FormBuilder#inputs' do
162
162
  'but the block does not accept any argument.')
163
163
  end
164
164
  end
165
-
165
+
166
166
  it 'should pass options down to semantic_fields_for' do
167
167
  @bob.stub!(:column_for_attribute).and_return(mock('column', :type => :string, :limit => 255))
168
-
168
+
169
169
  concat(semantic_form_for(@new_post) do |builder|
170
170
  inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
171
171
  concat(bob_builder.input(:login))
172
172
  end
173
173
  concat(inputs)
174
174
  end)
175
-
175
+
176
176
  output_buffer.should have_tag('form fieldset ol li #post_author_attributes_10_login')
177
177
  end
178
-
178
+
179
179
  it 'should not add builder as a fieldset attribute tag' do
180
180
  concat(semantic_form_for(@new_post) do |builder|
181
181
  inputs = builder.inputs :for => [:author, @bob], :for_options => { :index => 10 } do |bob_builder|
@@ -183,10 +183,10 @@ describe 'Formtastic::FormBuilder#inputs' do
183
183
  end
184
184
  concat(inputs)
185
185
  end)
186
-
186
+
187
187
  output_buffer.should_not have_tag('fieldset[@builder="Formtastic::Helpers::FormHelper"]')
188
188
  end
189
-
189
+
190
190
  it 'should send parent_builder as an option to allow child index interpolation' do
191
191
  concat(semantic_form_for(@new_post) do |builder|
192
192
  builder.instance_variable_set('@nested_child_index', 0)
@@ -195,10 +195,10 @@ describe 'Formtastic::FormBuilder#inputs' do
195
195
  end
196
196
  concat(inputs)
197
197
  end)
198
-
198
+
199
199
  output_buffer.should have_tag('fieldset legend', 'Author #1')
200
200
  end
201
-
201
+
202
202
  it 'should also provide child index interpolation when nested child index is a hash' do
203
203
  concat(semantic_form_for(@new_post) do |builder|
204
204
  builder.instance_variable_set('@nested_child_index', :author => 10)
@@ -207,11 +207,11 @@ describe 'Formtastic::FormBuilder#inputs' do
207
207
  end
208
208
  concat(inputs)
209
209
  end)
210
-
210
+
211
211
  output_buffer.should have_tag('fieldset legend', 'Author #11')
212
212
  end
213
213
  end
214
-
214
+
215
215
  describe 'when a :name or :title option is provided' do
216
216
  describe 'and is a string' do
217
217
  before do
@@ -234,7 +234,7 @@ describe 'Formtastic::FormBuilder#inputs' do
234
234
  concat(inputs)
235
235
  end)
236
236
  end
237
-
237
+
238
238
  it 'should render a fieldset with a legend inside the form' do
239
239
  output_buffer.should have_tag("form fieldset legend", /^#{@legend_text}$/)
240
240
  output_buffer.should have_tag("form fieldset legend", /^#{@legend_text_using_name}$/)
@@ -242,7 +242,7 @@ describe 'Formtastic::FormBuilder#inputs' do
242
242
  output_buffer.should have_tag("form fieldset legend", /^#{@nested_forms_legend_text}$/)
243
243
  end
244
244
  end
245
-
245
+
246
246
  describe 'and is a symbol' do
247
247
  before do
248
248
  @localized_legend_text = "Localized advanced options"
@@ -274,7 +274,7 @@ describe 'Formtastic::FormBuilder#inputs' do
274
274
  concat(inputs)
275
275
  end)
276
276
  end
277
-
277
+
278
278
  it 'should render a fieldset with a localized legend inside the form' do
279
279
  output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text}$/)
280
280
  output_buffer.should have_tag("form fieldset legend", /^#{@localized_legend_text_using_name}$/)
@@ -283,84 +283,84 @@ describe 'Formtastic::FormBuilder#inputs' do
283
283
  end
284
284
  end
285
285
  end
286
-
286
+
287
287
  describe 'when other options are provided' do
288
288
  before do
289
289
  @id_option = 'advanced'
290
290
  @class_option = 'wide'
291
-
291
+
292
292
  concat(semantic_form_for(@new_post) do |builder|
293
293
  builder.inputs :id => @id_option, :class => @class_option do
294
294
  end
295
295
  end)
296
296
  end
297
-
297
+
298
298
  it 'should pass the options into the fieldset tag as attributes' do
299
299
  output_buffer.should have_tag("form fieldset##{@id_option}")
300
300
  output_buffer.should have_tag("form fieldset.#{@class_option}")
301
301
  end
302
302
  end
303
-
303
+
304
304
  end
305
-
305
+
306
306
  describe 'without a block' do
307
-
307
+
308
308
  before do
309
309
  ::Post.stub!(:reflections).and_return({:author => mock('reflection', :options => {}, :macro => :belongs_to),
310
310
  :comments => mock('reflection', :options => {}, :macro => :has_many) })
311
311
  ::Author.stub!(:find).and_return([@fred, @bob])
312
-
312
+
313
313
  @new_post.stub!(:title)
314
314
  @new_post.stub!(:body)
315
315
  @new_post.stub!(:author_id)
316
-
316
+
317
317
  @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :string, :limit => 255))
318
318
  @new_post.stub!(:column_for_attribute).with(:body).and_return(mock('column', :type => :text))
319
319
  @new_post.stub!(:column_for_attribute).with(:created_at).and_return(mock('column', :type => :datetime))
320
320
  @new_post.stub!(:column_for_attribute).with(:author).and_return(nil)
321
321
  end
322
-
322
+
323
323
  describe 'with no args (quick forms syntax)' do
324
324
  before do
325
325
  concat(semantic_form_for(@new_post) do |builder|
326
326
  concat(builder.inputs)
327
327
  end)
328
328
  end
329
-
329
+
330
330
  it 'should render a form' do
331
331
  output_buffer.should have_tag('form')
332
332
  end
333
-
333
+
334
334
  it 'should render a fieldset inside the form' do
335
335
  output_buffer.should have_tag('form > fieldset.inputs')
336
336
  end
337
-
337
+
338
338
  it 'should not render a legend in the fieldset' do
339
339
  output_buffer.should_not have_tag('form > fieldset.inputs > legend')
340
340
  end
341
-
341
+
342
342
  it 'should render an ol in the fieldset' do
343
343
  output_buffer.should have_tag('form > fieldset.inputs > ol')
344
344
  end
345
-
345
+
346
346
  it 'should render a list item in the ol for each column and reflection' do
347
347
  # Remove the :has_many macro and :created_at column
348
348
  count = ::Post.content_columns.size + ::Post.reflections.size - 2
349
349
  output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => count)
350
350
  end
351
-
351
+
352
352
  it 'should render a string list item for title' do
353
353
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
354
354
  end
355
-
355
+
356
356
  it 'should render a text list item for body' do
357
357
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
358
358
  end
359
-
359
+
360
360
  it 'should render a select list item for author_id' do
361
361
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.select', :count => 1)
362
362
  end
363
-
363
+
364
364
  it 'should not render timestamps inputs by default' do
365
365
  output_buffer.should_not have_tag('form > fieldset.inputs > ol > li.datetime')
366
366
  end
@@ -386,26 +386,26 @@ describe 'Formtastic::FormBuilder#inputs' do
386
386
 
387
387
  end
388
388
  end
389
-
389
+
390
390
  describe 'with column names as args (short hand forms syntax)' do
391
391
  describe 'and an object is given' do
392
392
  it 'should render a form with a fieldset containing two list items' do
393
393
  concat(semantic_form_for(@new_post) do |builder|
394
394
  concat(builder.inputs(:title, :body))
395
395
  end)
396
-
396
+
397
397
  output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 2)
398
398
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.string')
399
399
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.text')
400
400
  end
401
401
  end
402
-
402
+
403
403
  describe 'and no object is given' do
404
404
  it 'should render a form with a fieldset containing two list items' do
405
405
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
406
406
  concat(builder.inputs(:title, :body))
407
407
  end)
408
-
408
+
409
409
  output_buffer.should have_tag('form > fieldset.inputs > ol > li.string', :count => 2)
410
410
  end
411
411
  end
@@ -434,7 +434,7 @@ describe 'Formtastic::FormBuilder#inputs' do
434
434
  end
435
435
 
436
436
  end
437
-
437
+
438
438
  describe 'when a :for option is provided' do
439
439
  describe 'and an object is given' do
440
440
  it 'should render nested inputs' do
@@ -442,12 +442,12 @@ describe 'Formtastic::FormBuilder#inputs' do
442
442
  concat(semantic_form_for(@new_post) do |builder|
443
443
  concat(builder.inputs(:login, :for => @bob))
444
444
  end)
445
-
445
+
446
446
  output_buffer.should have_tag("form fieldset.inputs #post_author_login")
447
447
  output_buffer.should_not have_tag("form fieldset.inputs #author_login")
448
448
  end
449
449
  end
450
-
450
+
451
451
  describe 'and no object is given' do
452
452
  it 'should render nested inputs' do
453
453
  concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
@@ -458,7 +458,7 @@ describe 'Formtastic::FormBuilder#inputs' do
458
458
  end
459
459
  end
460
460
  end
461
-
461
+
462
462
  describe 'with column names and an options hash as args' do
463
463
  before do
464
464
  concat(semantic_form_for(@new_post) do |builder|
@@ -468,23 +468,23 @@ describe 'Formtastic::FormBuilder#inputs' do
468
468
  concat(builder.inputs(@legend_text_using_arg, :title, :body, :id => "my-id-2"))
469
469
  end)
470
470
  end
471
-
471
+
472
472
  it 'should render a form with a fieldset containing two list items' do
473
473
  output_buffer.should have_tag('form > fieldset.inputs > ol > li', :count => 4)
474
474
  end
475
-
475
+
476
476
  it 'should pass the options down to the fieldset' do
477
477
  output_buffer.should have_tag('form > fieldset#my-id.inputs')
478
478
  end
479
-
479
+
480
480
  it 'should use the special :name option as a text for the legend tag' do
481
481
  output_buffer.should have_tag('form > fieldset#my-id.inputs > legend', /^#{@legend_text_using_option}$/)
482
482
  output_buffer.should have_tag('form > fieldset#my-id-2.inputs > legend', /^#{@legend_text_using_arg}$/)
483
483
  end
484
484
  end
485
-
485
+
486
486
  end
487
-
487
+
488
488
  describe 'nesting' do
489
489
 
490
490
  context "when not nested" do
@@ -531,7 +531,7 @@ describe 'Formtastic::FormBuilder#inputs' do
531
531
  output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
532
532
  end
533
533
  end
534
-
534
+
535
535
  context "when nested (without block, with :for)" do
536
536
  it "should wrap the nested inputs in an li block to maintain HTML validity" do
537
537
  concat(semantic_form_for(@new_post) do |builder|
@@ -542,7 +542,7 @@ describe 'Formtastic::FormBuilder#inputs' do
542
542
  output_buffer.should have_tag('form > fieldset.inputs > ol > li > fieldset.inputs > ol')
543
543
  end
544
544
  end
545
-
545
+
546
546
  context "when double nested" do
547
547
  it "should wrap the nested inputs in an li block to maintain HTML validity" do
548
548
  concat(semantic_form_for(@new_post) do |builder|
@@ -559,4 +559,16 @@ describe 'Formtastic::FormBuilder#inputs' do
559
559
 
560
560
  end
561
561
 
562
+ describe 'when using MongoMapper associations ' do
563
+ def generate_form
564
+ semantic_form_for(@new_mm_post) do |builder|
565
+ builder.inputs :title, :sub_posts
566
+ end
567
+ end
568
+ it "should throw PolymorphicInputWithoutCollectionError on sub_posts" do
569
+ ::MongoPost.should_receive(:associations).at_least(3).times
570
+ expect { generate_form }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
571
+ end
572
+ end
573
+
562
574
  end