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,787 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'number input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ Formtastic::Helpers::FormHelper.builder = FormtasticBootstrap::FormBuilder
12
+
13
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
14
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than=>2})
15
+ ])
16
+ end
17
+
18
+ describe "all cases" do
19
+
20
+ before do
21
+ concat(
22
+ semantic_form_for(@new_post) do |builder|
23
+ concat(builder.input(:title, :as => :number))
24
+ end
25
+ )
26
+ end
27
+
28
+ it_should_have_input_wrapper_with_class(:number)
29
+ it_should_have_input_wrapper_with_class(:clearfix)
30
+ it_should_have_input_wrapper_with_class(:stringish)
31
+ it_should_have_input_class_in_the_right_place
32
+ it_should_have_input_wrapper_with_id("post_title_input")
33
+ it_should_have_label_with_text(/Title/)
34
+ it_should_have_label_for("post_title")
35
+ it_should_have_input_with_id("post_title")
36
+ it_should_have_input_with_type(:number)
37
+ it_should_have_input_with_name("post[title]")
38
+ it_should_use_default_text_field_size_when_not_nil(:string)
39
+ it_should_not_use_default_text_field_size_when_nil(:string)
40
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
41
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
42
+ it_should_apply_error_logic_for_input_type(:number)
43
+
44
+ end
45
+
46
+ describe "when no object is provided" do
47
+ before do
48
+ concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
49
+ concat(builder.input(:title, :as => :number, :input_html => { :min => 1, :max => 2 }))
50
+ end)
51
+ end
52
+
53
+ it_should_have_label_with_text(/Title/)
54
+ it_should_have_label_for("project_title")
55
+ it_should_have_input_with_id("project_title")
56
+ it_should_have_input_with_type(:number)
57
+ it_should_have_input_with_name("project[title]")
58
+ end
59
+
60
+ describe "when namespace provided" do
61
+ before do
62
+ concat(semantic_form_for(@new_post, :namespace => :context2) do |builder|
63
+ concat(builder.input(:title, :as => :number))
64
+ end)
65
+ end
66
+
67
+ it_should_have_input_wrapper_with_id("context2_post_title_input")
68
+ it_should_have_label_and_input_with_id("context2_post_title")
69
+ end
70
+
71
+ describe "when required" do
72
+ it "should add the required attribute to the input's html options" do
73
+ with_config :use_required_attribute, true do
74
+ concat(semantic_form_for(@new_post) do |builder|
75
+ concat(builder.input(:title, :as => :number, :required => true))
76
+ end)
77
+ output_buffer.should have_tag("input[@required]")
78
+ end
79
+ end
80
+ end
81
+
82
+ describe "when validations require a minimum value (:greater_than)" do
83
+ before do
84
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
85
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than=>2})
86
+ ])
87
+ end
88
+
89
+ it "should allow :input_html to override :min" do
90
+ concat(semantic_form_for(@new_post) do |builder|
91
+ builder.input(:title, :as => :number, :input_html => { :min => 5 })
92
+ end)
93
+ output_buffer.should have_tag('input[@min="5"]')
94
+ end
95
+
96
+ it "should allow :input_html to override :min through :in" do
97
+ concat(semantic_form_for(@new_post) do |builder|
98
+ builder.input(:title, :as => :number, :input_html => { :in => 5..102 })
99
+ end)
100
+ output_buffer.should have_tag('input[@min="5"]')
101
+ end
102
+
103
+ it "should allow options to override :min" do
104
+ concat(semantic_form_for(@new_post) do |builder|
105
+ builder.input(:title, :as => :number, :min => 5)
106
+ end)
107
+ output_buffer.should have_tag('input[@min="5"]')
108
+ end
109
+
110
+ it "should allow options to override :min through :in" do
111
+ concat(semantic_form_for(@new_post) do |builder|
112
+ builder.input(:title, :as => :number, :in => 5..102)
113
+ end)
114
+ output_buffer.should have_tag('input[@min="5"]')
115
+ end
116
+
117
+ describe "and the column is an integer" do
118
+ before do
119
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :integer))
120
+ end
121
+
122
+ it "should add a min attribute to the input one greater than the validation" do
123
+ concat(semantic_form_for(@new_post) do |builder|
124
+ builder.input(:title, :as => :number)
125
+ end)
126
+ output_buffer.should have_tag('input[@min="3"]')
127
+ end
128
+ end
129
+
130
+ describe "and the column is a float" do
131
+ before do
132
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :float))
133
+ end
134
+
135
+ it "should raise an error" do
136
+ lambda {
137
+ concat(semantic_form_for(@new_post) do |builder|
138
+ builder.input(:title, :as => :number)
139
+ end)
140
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMinimumAttributeError)
141
+ end
142
+ end
143
+
144
+ describe "and the column is a big decimal" do
145
+ before do
146
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
147
+ end
148
+
149
+ it "should raise an error" do
150
+ lambda {
151
+ concat(semantic_form_for(@new_post) do |builder|
152
+ builder.input(:title, :as => :number)
153
+ end)
154
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMinimumAttributeError)
155
+ end
156
+ end
157
+
158
+ end
159
+
160
+ describe "when validations require a minimum value (:greater_than) that takes a proc" do
161
+ before do
162
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
163
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than=> Proc.new {|post| 2}})
164
+ ])
165
+ end
166
+
167
+ it "should allow :input_html to override :min" do
168
+ concat(semantic_form_for(@new_post) do |builder|
169
+ builder.input(:title, :as => :number, :input_html => { :min => 5 })
170
+ end)
171
+ output_buffer.should have_tag('input[@min="5"]')
172
+ end
173
+
174
+ it "should allow :input_html to override :min through :in" do
175
+ concat(semantic_form_for(@new_post) do |builder|
176
+ builder.input(:title, :as => :number, :input_html => { :in => 5..102 })
177
+ end)
178
+ output_buffer.should have_tag('input[@min="5"]')
179
+ end
180
+
181
+ it "should allow options to override :min" do
182
+ concat(semantic_form_for(@new_post) do |builder|
183
+ builder.input(:title, :as => :number, :min => 5)
184
+ end)
185
+ output_buffer.should have_tag('input[@min="5"]')
186
+ end
187
+
188
+ it "should allow options to override :min through :in" do
189
+ concat(semantic_form_for(@new_post) do |builder|
190
+ builder.input(:title, :as => :number, :in => 5..102)
191
+ end)
192
+ output_buffer.should have_tag('input[@min="5"]')
193
+ end
194
+
195
+ describe "and the column is an integer" do
196
+ before do
197
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :integer))
198
+ end
199
+
200
+ it "should add a min attribute to the input one greater than the validation" do
201
+ concat(semantic_form_for(@new_post) do |builder|
202
+ builder.input(:title, :as => :number)
203
+ end)
204
+ output_buffer.should have_tag('input[@min="3"]')
205
+ end
206
+ end
207
+
208
+ describe "and the column is a float" do
209
+ before do
210
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :float))
211
+ end
212
+
213
+ it "should raise an error" do
214
+ lambda {
215
+ concat(semantic_form_for(@new_post) do |builder|
216
+ builder.input(:title, :as => :number)
217
+ end)
218
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMinimumAttributeError)
219
+ end
220
+ end
221
+
222
+ describe "and the column is a big decimal" do
223
+ before do
224
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
225
+ end
226
+
227
+ it "should raise an error" do
228
+ lambda {
229
+ concat(semantic_form_for(@new_post) do |builder|
230
+ builder.input(:title, :as => :number)
231
+ end)
232
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMinimumAttributeError)
233
+ end
234
+ end
235
+
236
+ end
237
+
238
+ describe "when validations require a minimum value (:greater_than_or_equal_to)" do
239
+ before do
240
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
241
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than_or_equal_to=>2})
242
+ ])
243
+ end
244
+
245
+ it "should allow :input_html to override :min" do
246
+ concat(semantic_form_for(@new_post) do |builder|
247
+ builder.input(:title, :as => :number, :input_html => { :min => 5 })
248
+ end)
249
+ output_buffer.should have_tag('input[@min="5"]')
250
+ end
251
+
252
+ it "should allow options to override :min" do
253
+ concat(semantic_form_for(@new_post) do |builder|
254
+ builder.input(:title, :as => :number, :min => 5)
255
+ end)
256
+ output_buffer.should have_tag('input[@min="5"]')
257
+ end
258
+
259
+ it "should allow :input_html to override :min with :in" do
260
+ concat(semantic_form_for(@new_post) do |builder|
261
+ builder.input(:title, :as => :number, :input_html => { :in => 5..102 })
262
+ end)
263
+ output_buffer.should have_tag('input[@min="5"]')
264
+ end
265
+
266
+ it "should allow options to override :min with :in" do
267
+ concat(semantic_form_for(@new_post) do |builder|
268
+ builder.input(:title, :as => :number, :in => 5..102)
269
+ end)
270
+ output_buffer.should have_tag('input[@min="5"]')
271
+ end
272
+
273
+
274
+ [:integer, :decimal, :float].each do |column_type|
275
+ describe "and the column is a #{column_type}" do
276
+ before do
277
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => column_type))
278
+ end
279
+
280
+ it "should add a max attribute to the input equal to the validation" do
281
+ concat(semantic_form_for(@new_post) do |builder|
282
+ builder.input(:title, :as => :number)
283
+ end)
284
+ output_buffer.should have_tag('input[@min="2"]')
285
+ end
286
+ end
287
+ end
288
+
289
+ describe "and there is no column" do
290
+ before do
291
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(nil)
292
+ end
293
+
294
+ it "should add a max attribute to the input equal to the validation" do
295
+ concat(semantic_form_for(@new_post) do |builder|
296
+ builder.input(:title, :as => :number)
297
+ end)
298
+ output_buffer.should have_tag('input[@min="2"]')
299
+ end
300
+ end
301
+ end
302
+
303
+ describe "when validations require a minimum value (:greater_than_or_equal_to) that takes a Proc" do
304
+ before do
305
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
306
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than_or_equal_to=> Proc.new { |post| 2}})
307
+ ])
308
+ end
309
+
310
+ it "should allow :input_html to override :min" do
311
+ concat(semantic_form_for(@new_post) do |builder|
312
+ builder.input(:title, :as => :number, :input_html => { :min => 5 })
313
+ end)
314
+ output_buffer.should have_tag('input[@min="5"]')
315
+ end
316
+
317
+ it "should allow options to override :min" do
318
+ concat(semantic_form_for(@new_post) do |builder|
319
+ builder.input(:title, :as => :number, :min => 5)
320
+ end)
321
+ output_buffer.should have_tag('input[@min="5"]')
322
+ end
323
+
324
+ it "should allow :input_html to override :min with :in" do
325
+ concat(semantic_form_for(@new_post) do |builder|
326
+ builder.input(:title, :as => :number, :input_html => { :in => 5..102 })
327
+ end)
328
+ output_buffer.should have_tag('input[@min="5"]')
329
+ end
330
+
331
+ it "should allow options to override :min with :in" do
332
+ concat(semantic_form_for(@new_post) do |builder|
333
+ builder.input(:title, :as => :number, :in => 5..102)
334
+ end)
335
+ output_buffer.should have_tag('input[@min="5"]')
336
+ end
337
+
338
+
339
+ [:integer, :decimal, :float].each do |column_type|
340
+ describe "and the column is a #{column_type}" do
341
+ before do
342
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => column_type))
343
+ end
344
+
345
+ it "should add a max attribute to the input equal to the validation" do
346
+ concat(semantic_form_for(@new_post) do |builder|
347
+ builder.input(:title, :as => :number)
348
+ end)
349
+ output_buffer.should have_tag('input[@min="2"]')
350
+ end
351
+ end
352
+ end
353
+
354
+ describe "and there is no column" do
355
+ before do
356
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(nil)
357
+ end
358
+
359
+ it "should add a max attribute to the input equal to the validation" do
360
+ concat(semantic_form_for(@new_post) do |builder|
361
+ builder.input(:title, :as => :number)
362
+ end)
363
+ output_buffer.should have_tag('input[@min="2"]')
364
+ end
365
+ end
366
+ end
367
+
368
+ describe "when validations require a maximum value (:less_than)" do
369
+
370
+ before do
371
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
372
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :less_than=>20})
373
+ ])
374
+ end
375
+
376
+ it "should allow :input_html to override :max" do
377
+ concat(semantic_form_for(@new_post) do |builder|
378
+ builder.input(:title, :as => :number, :input_html => { :max => 102 })
379
+ end)
380
+ output_buffer.should have_tag('input[@max="102"]')
381
+ end
382
+
383
+ it "should allow option to override :max" do
384
+ concat(semantic_form_for(@new_post) do |builder|
385
+ builder.input(:title, :as => :number, :max => 102)
386
+ end)
387
+ output_buffer.should have_tag('input[@max="102"]')
388
+ end
389
+
390
+ it "should allow :input_html to override :max with :in" do
391
+ concat(semantic_form_for(@new_post) do |builder|
392
+ builder.input(:title, :as => :number, :input_html => { :in => 1..102 })
393
+ end)
394
+ output_buffer.should have_tag('input[@max="102"]')
395
+ end
396
+
397
+ it "should allow option to override :max with :in" do
398
+ concat(semantic_form_for(@new_post) do |builder|
399
+ builder.input(:title, :as => :number, :in => 1..102)
400
+ end)
401
+ output_buffer.should have_tag('input[@max="102"]')
402
+ end
403
+
404
+ describe "and the column is an integer" do
405
+ before do
406
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :integer))
407
+ end
408
+
409
+ it "should add a max attribute to the input one greater than the validation" do
410
+ concat(semantic_form_for(@new_post) do |builder|
411
+ builder.input(:title, :as => :number)
412
+ end)
413
+ output_buffer.should have_tag('input[@max="19"]')
414
+ end
415
+ end
416
+
417
+ describe "and the column is a float" do
418
+ before do
419
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :float))
420
+ end
421
+
422
+ it "should raise an error" do
423
+ lambda {
424
+ concat(semantic_form_for(@new_post) do |builder|
425
+ builder.input(:title, :as => :number)
426
+ end)
427
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMaximumAttributeError)
428
+ end
429
+ end
430
+
431
+ describe "and the column is a big decimal" do
432
+ before do
433
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
434
+ end
435
+
436
+ it "should raise an error" do
437
+ lambda {
438
+ concat(semantic_form_for(@new_post) do |builder|
439
+ builder.input(:title, :as => :number)
440
+ end)
441
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMaximumAttributeError)
442
+ end
443
+ end
444
+ describe "and the validator takes a proc" do
445
+ before do
446
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
447
+ end
448
+ end
449
+ end
450
+
451
+ describe "when validations require a maximum value (:less_than) that takes a Proc" do
452
+
453
+ before do
454
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
455
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :less_than=> Proc.new {|post| 20 }})
456
+ ])
457
+ end
458
+
459
+ it "should allow :input_html to override :max" do
460
+ concat(semantic_form_for(@new_post) do |builder|
461
+ builder.input(:title, :as => :number, :input_html => { :max => 102 })
462
+ end)
463
+ output_buffer.should have_tag('input[@max="102"]')
464
+ end
465
+
466
+ it "should allow option to override :max" do
467
+ concat(semantic_form_for(@new_post) do |builder|
468
+ builder.input(:title, :as => :number, :max => 102)
469
+ end)
470
+ output_buffer.should have_tag('input[@max="102"]')
471
+ end
472
+
473
+ it "should allow :input_html to override :max with :in" do
474
+ concat(semantic_form_for(@new_post) do |builder|
475
+ builder.input(:title, :as => :number, :input_html => { :in => 1..102 })
476
+ end)
477
+ output_buffer.should have_tag('input[@max="102"]')
478
+ end
479
+
480
+ it "should allow option to override :max with :in" do
481
+ concat(semantic_form_for(@new_post) do |builder|
482
+ builder.input(:title, :as => :number, :in => 1..102)
483
+ end)
484
+ output_buffer.should have_tag('input[@max="102"]')
485
+ end
486
+
487
+ describe "and the column is an integer" do
488
+ before do
489
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :integer))
490
+ end
491
+
492
+ it "should add a max attribute to the input one greater than the validation" do
493
+ concat(semantic_form_for(@new_post) do |builder|
494
+ builder.input(:title, :as => :number)
495
+ end)
496
+ output_buffer.should have_tag('input[@max="19"]')
497
+ end
498
+ end
499
+
500
+ describe "and the column is a float" do
501
+ before do
502
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :float))
503
+ end
504
+
505
+ it "should raise an error" do
506
+ lambda {
507
+ concat(semantic_form_for(@new_post) do |builder|
508
+ builder.input(:title, :as => :number)
509
+ end)
510
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMaximumAttributeError)
511
+ end
512
+ end
513
+
514
+ describe "and the column is a big decimal" do
515
+ before do
516
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
517
+ end
518
+
519
+ it "should raise an error" do
520
+ lambda {
521
+ concat(semantic_form_for(@new_post) do |builder|
522
+ builder.input(:title, :as => :number)
523
+ end)
524
+ }.should raise_error(Formtastic::Inputs::Base::Validations::IndeterminableMaximumAttributeError)
525
+ end
526
+ end
527
+ describe "and the validator takes a proc" do
528
+ before do
529
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => :decimal))
530
+ end
531
+ end
532
+ end
533
+
534
+
535
+ describe "when validations require a maximum value (:less_than_or_equal_to)" do
536
+ before do
537
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
538
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :less_than_or_equal_to=>20})
539
+ ])
540
+ end
541
+
542
+ it "should allow :input_html to override :max" do
543
+ concat(semantic_form_for(@new_post) do |builder|
544
+ builder.input(:title, :as => :number, :input_html => { :max => 102 })
545
+ end)
546
+ output_buffer.should have_tag('input[@max="102"]')
547
+ end
548
+
549
+ it "should allow options to override :max" do
550
+ concat(semantic_form_for(@new_post) do |builder|
551
+ builder.input(:title, :as => :number, :max => 102)
552
+ end)
553
+ output_buffer.should have_tag('input[@max="102"]')
554
+ end
555
+
556
+ it "should allow :input_html to override :max with :in" do
557
+ concat(semantic_form_for(@new_post) do |builder|
558
+ builder.input(:title, :as => :number, :input_html => { :in => 1..102 })
559
+ end)
560
+ output_buffer.should have_tag('input[@max="102"]')
561
+ end
562
+
563
+ it "should allow options to override :max with :in" do
564
+ concat(semantic_form_for(@new_post) do |builder|
565
+ builder.input(:title, :as => :number, :in => 1..102)
566
+ end)
567
+ output_buffer.should have_tag('input[@max="102"]')
568
+ end
569
+
570
+ [:integer, :decimal, :float].each do |column_type|
571
+ describe "and the column is a #{column_type}" do
572
+ before do
573
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => column_type))
574
+ end
575
+
576
+ it "should add a max attribute to the input equal to the validation" do
577
+ concat(semantic_form_for(@new_post) do |builder|
578
+ builder.input(:title, :as => :number)
579
+ end)
580
+ output_buffer.should have_tag('input[@max="20"]')
581
+ end
582
+ end
583
+ end
584
+
585
+ describe "and there is no column" do
586
+ before do
587
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(nil)
588
+ end
589
+
590
+ it "should add a max attribute to the input equal to the validation" do
591
+ concat(semantic_form_for(@new_post) do |builder|
592
+ builder.input(:title, :as => :number)
593
+ end)
594
+ output_buffer.should have_tag('input[@max="20"]')
595
+ end
596
+ end
597
+ end
598
+
599
+ describe "when validations require a maximum value (:less_than_or_equal_to) that takes a proc" do
600
+ before do
601
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
602
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :less_than_or_equal_to=> Proc.new { |post| 20 }})
603
+ ])
604
+ end
605
+
606
+ it "should allow :input_html to override :max" do
607
+ concat(semantic_form_for(@new_post) do |builder|
608
+ builder.input(:title, :as => :number, :input_html => { :max => 102 })
609
+ end)
610
+ output_buffer.should have_tag('input[@max="102"]')
611
+ end
612
+
613
+ it "should allow options to override :max" do
614
+ concat(semantic_form_for(@new_post) do |builder|
615
+ builder.input(:title, :as => :number, :max => 102)
616
+ end)
617
+ output_buffer.should have_tag('input[@max="102"]')
618
+ end
619
+
620
+ it "should allow :input_html to override :max with :in" do
621
+ concat(semantic_form_for(@new_post) do |builder|
622
+ builder.input(:title, :as => :number, :input_html => { :in => 1..102 })
623
+ end)
624
+ output_buffer.should have_tag('input[@max="102"]')
625
+ end
626
+
627
+ it "should allow options to override :max with :in" do
628
+ concat(semantic_form_for(@new_post) do |builder|
629
+ builder.input(:title, :as => :number, :in => 1..102)
630
+ end)
631
+ output_buffer.should have_tag('input[@max="102"]')
632
+ end
633
+
634
+ [:integer, :decimal, :float].each do |column_type|
635
+ describe "and the column is a #{column_type}" do
636
+ before do
637
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(mock('column', :type => column_type))
638
+ end
639
+
640
+ it "should add a max attribute to the input equal to the validation" do
641
+ concat(semantic_form_for(@new_post) do |builder|
642
+ builder.input(:title, :as => :number)
643
+ end)
644
+ output_buffer.should have_tag('input[@max="20"]')
645
+ end
646
+ end
647
+ end
648
+
649
+ describe "and there is no column" do
650
+ before do
651
+ @new_post.stub!(:column_for_attribute).with(:title).and_return(nil)
652
+ end
653
+
654
+ it "should add a max attribute to the input equal to the validation" do
655
+ concat(semantic_form_for(@new_post) do |builder|
656
+ builder.input(:title, :as => :number)
657
+ end)
658
+ output_buffer.should have_tag('input[@max="20"]')
659
+ end
660
+ end
661
+ end
662
+
663
+ describe "when validations require conflicting minimum values (:greater_than, :greater_than_or_equal_to)" do
664
+ before do
665
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
666
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :greater_than => 20, :greater_than_or_equal_to=>2})
667
+ ])
668
+ end
669
+
670
+ it "should add a max attribute to the input equal to the :greater_than_or_equal_to validation" do
671
+ concat(semantic_form_for(@new_post) do |builder|
672
+ builder.input(:title, :as => :number)
673
+ end)
674
+ output_buffer.should have_tag('input[@min="2"]')
675
+ end
676
+ end
677
+
678
+ describe "when validations require conflicting maximum values (:less_than, :less_than_or_equal_to)" do
679
+ before do
680
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
681
+ active_model_numericality_validator([:title], {:only_integer=>false, :allow_nil=>false, :less_than => 20, :less_than_or_equal_to=>2})
682
+ ])
683
+ end
684
+
685
+ it "should add a max attribute to the input equal to the :greater_than_or_equal_to validation" do
686
+ concat(semantic_form_for(@new_post) do |builder|
687
+ builder.input(:title, :as => :number)
688
+ end)
689
+ output_buffer.should have_tag('input[@max="2"]')
690
+ end
691
+ end
692
+
693
+ describe "when validations require only an integer (:only_integer)" do
694
+
695
+ before do
696
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
697
+ active_model_numericality_validator([:title], {:allow_nil=>false, :only_integer=>true})
698
+ ])
699
+ end
700
+
701
+ it "should add a step=1 attribute to the input to signify that only whole numbers are allowed" do
702
+ concat(semantic_form_for(@new_post) do |builder|
703
+ builder.input(:title, :as => :number)
704
+ end)
705
+ output_buffer.should have_tag('input[@step="1"]')
706
+ end
707
+
708
+ it "should let input_html override :step" do
709
+ concat(semantic_form_for(@new_post) do |builder|
710
+ builder.input(:title, :as => :number, :input_html => { :step => 3 })
711
+ end)
712
+ output_buffer.should have_tag('input[@step="3"]')
713
+ end
714
+
715
+ it "should let options override :step" do
716
+ concat(semantic_form_for(@new_post) do |builder|
717
+ builder.input(:title, :as => :number, :step => 3)
718
+ end)
719
+ output_buffer.should have_tag('input[@step="3"]')
720
+ end
721
+
722
+ end
723
+
724
+ describe "when validations require a :step (non standard)" do
725
+
726
+ before do
727
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
728
+ active_model_numericality_validator([:title], {:allow_nil=>false, :only_integer=>true, :step=>2})
729
+ ])
730
+ end
731
+
732
+ it "should add a step=1 attribute to the input to signify that only whole numbers are allowed" do
733
+ concat(semantic_form_for(@new_post) do |builder|
734
+ builder.input(:title, :as => :number)
735
+ end)
736
+ output_buffer.should have_tag('input[@step="2"]')
737
+ end
738
+
739
+ it "should let input_html override :step" do
740
+ concat(semantic_form_for(@new_post) do |builder|
741
+ builder.input(:title, :as => :number, :input_html => { :step => 3 })
742
+ end)
743
+ output_buffer.should have_tag('input[@step="3"]')
744
+ end
745
+
746
+ it "should let options override :step" do
747
+ concat(semantic_form_for(@new_post) do |builder|
748
+ builder.input(:title, :as => :number, :step => 3)
749
+ end)
750
+ output_buffer.should have_tag('input[@step="3"]')
751
+ end
752
+
753
+ end
754
+
755
+ describe "when validations do not specify :step (non standard) or :only_integer" do
756
+
757
+ before do
758
+ @new_post.class.stub!(:validators_on).with(:title).and_return([
759
+ active_model_numericality_validator([:title], {:allow_nil=>false})
760
+ ])
761
+ end
762
+
763
+ it "should default step to 'any'" do
764
+ concat(semantic_form_for(@new_post) do |builder|
765
+ builder.input(:title, :as => :number)
766
+ end)
767
+ output_buffer.should have_tag('input[@step="any"]')
768
+ end
769
+
770
+ it "should let input_html set :step" do
771
+ concat(semantic_form_for(@new_post) do |builder|
772
+ builder.input(:title, :as => :number, :input_html => { :step => 3 })
773
+ end)
774
+ output_buffer.should have_tag('input[@step="3"]')
775
+ end
776
+
777
+ it "should let options set :step" do
778
+ concat(semantic_form_for(@new_post) do |builder|
779
+ builder.input(:title, :as => :number, :step => 3)
780
+ end)
781
+ output_buffer.should have_tag('input[@step="3"]')
782
+ end
783
+
784
+ end
785
+
786
+ end
787
+