speedo-formstrap 1.2.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 (89) hide show
  1. data/.document +5 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +13 -0
  4. data/Gemfile.lock +117 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.md +192 -0
  7. data/Rakefile +49 -0
  8. data/VERSION +1 -0
  9. data/formtastic-bootstrap.gemspec +56 -0
  10. data/lib/action_view/helpers/text_field_date_helper.rb +166 -0
  11. data/lib/formtastic-bootstrap.rb +7 -0
  12. data/lib/formtastic-bootstrap/actions.rb +4 -0
  13. data/lib/formtastic-bootstrap/actions/base.rb +18 -0
  14. data/lib/formtastic-bootstrap/actions/button_action.rb +7 -0
  15. data/lib/formtastic-bootstrap/actions/input_action.rb +7 -0
  16. data/lib/formtastic-bootstrap/actions/link_action.rb +7 -0
  17. data/lib/formtastic-bootstrap/engine.rb +4 -0
  18. data/lib/formtastic-bootstrap/form_builder.rb +40 -0
  19. data/lib/formtastic-bootstrap/helpers.rb +21 -0
  20. data/lib/formtastic-bootstrap/helpers/action_helper.rb +12 -0
  21. data/lib/formtastic-bootstrap/helpers/actions_helper.rb +23 -0
  22. data/lib/formtastic-bootstrap/helpers/buttons_helper.rb +56 -0
  23. data/lib/formtastic-bootstrap/helpers/fieldset_wrapper.rb +42 -0
  24. data/lib/formtastic-bootstrap/helpers/input_helper.rb +12 -0
  25. data/lib/formtastic-bootstrap/helpers/inputs_helper.rb +36 -0
  26. data/lib/formtastic-bootstrap/inputs.rb +29 -0
  27. data/lib/formtastic-bootstrap/inputs/base.rb +23 -0
  28. data/lib/formtastic-bootstrap/inputs/base/choices.rb +38 -0
  29. data/lib/formtastic-bootstrap/inputs/base/errors.rb +48 -0
  30. data/lib/formtastic-bootstrap/inputs/base/hints.rb +27 -0
  31. data/lib/formtastic-bootstrap/inputs/base/html.rb +21 -0
  32. data/lib/formtastic-bootstrap/inputs/base/labelling.rb +28 -0
  33. data/lib/formtastic-bootstrap/inputs/base/numeric.rb +18 -0
  34. data/lib/formtastic-bootstrap/inputs/base/stringish.rb +18 -0
  35. data/lib/formtastic-bootstrap/inputs/base/timeish.rb +28 -0
  36. data/lib/formtastic-bootstrap/inputs/base/wrapping.rb +74 -0
  37. data/lib/formtastic-bootstrap/inputs/boolean_input.rb +29 -0
  38. data/lib/formtastic-bootstrap/inputs/check_boxes_input.rb +36 -0
  39. data/lib/formtastic-bootstrap/inputs/date_input.rb +16 -0
  40. data/lib/formtastic-bootstrap/inputs/datetime_input.rb +19 -0
  41. data/lib/formtastic-bootstrap/inputs/email_input.rb +15 -0
  42. data/lib/formtastic-bootstrap/inputs/file_input.rb +14 -0
  43. data/lib/formtastic-bootstrap/inputs/hidden_input.rb +14 -0
  44. data/lib/formtastic-bootstrap/inputs/number_input.rb +15 -0
  45. data/lib/formtastic-bootstrap/inputs/password_input.rb +15 -0
  46. data/lib/formtastic-bootstrap/inputs/phone_input.rb +15 -0
  47. data/lib/formtastic-bootstrap/inputs/radio_input.rb +33 -0
  48. data/lib/formtastic-bootstrap/inputs/range_input.rb +15 -0
  49. data/lib/formtastic-bootstrap/inputs/search_input.rb +15 -0
  50. data/lib/formtastic-bootstrap/inputs/select_input.rb +14 -0
  51. data/lib/formtastic-bootstrap/inputs/string_input.rb +15 -0
  52. data/lib/formtastic-bootstrap/inputs/text_input.rb +14 -0
  53. data/lib/formtastic-bootstrap/inputs/time_input.rb +16 -0
  54. data/lib/formtastic-bootstrap/inputs/time_zone_input.rb +14 -0
  55. data/lib/formtastic-bootstrap/inputs/url_input.rb +14 -0
  56. data/spec/actions/button_action_spec.rb +68 -0
  57. data/spec/actions/generic_action_spec.rb +486 -0
  58. data/spec/actions/input_action_spec.rb +64 -0
  59. data/spec/actions/link_action_spec.rb +93 -0
  60. data/spec/builder/semantic_fields_for_spec.rb +130 -0
  61. data/spec/helpers/action_helper_spec.rb +365 -0
  62. data/spec/helpers/actions_helper_spec.rb +143 -0
  63. data/spec/helpers/buttons_helper_spec.rb +159 -0
  64. data/spec/helpers/input_helper_spec.rb +956 -0
  65. data/spec/helpers/inputs_helper_spec.rb +591 -0
  66. data/spec/inputs/boolean_input_spec.rb +221 -0
  67. data/spec/inputs/check_boxes_input_spec.rb +467 -0
  68. data/spec/inputs/date_input_spec.rb +213 -0
  69. data/spec/inputs/datetime_input_spec.rb +101 -0
  70. data/spec/inputs/email_input_spec.rb +87 -0
  71. data/spec/inputs/file_input_spec.rb +91 -0
  72. data/spec/inputs/hidden_input_spec.rb +150 -0
  73. data/spec/inputs/number_input_spec.rb +817 -0
  74. data/spec/inputs/password_input_spec.rb +101 -0
  75. data/spec/inputs/phone_input_spec.rb +87 -0
  76. data/spec/inputs/radio_input_spec.rb +268 -0
  77. data/spec/inputs/range_input_spec.rb +507 -0
  78. data/spec/inputs/search_input_spec.rb +86 -0
  79. data/spec/inputs/select_input_spec.rb +613 -0
  80. data/spec/inputs/string_input_spec.rb +227 -0
  81. data/spec/inputs/text_input_spec.rb +190 -0
  82. data/spec/inputs/time_input_spec.rb +206 -0
  83. data/spec/inputs/time_zone_input_spec.rb +120 -0
  84. data/spec/inputs/url_input_spec.rb +87 -0
  85. data/spec/spec_helper.rb +24 -0
  86. data/spec/support/custom_macros.rb +575 -0
  87. data/spec/support/depracation.rb +6 -0
  88. data/spec/support/formtastic_spec_helper.rb +398 -0
  89. metadata +216 -0
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'password 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
+ concat(semantic_form_for(@new_post) do |builder|
14
+ concat(builder.input(:title, :as => :password))
15
+ end)
16
+ end
17
+
18
+ it_should_have_input_wrapper_with_class('password-wrapper')
19
+ it_should_have_input_wrapper_with_class("control-group")
20
+ it_should_have_input_wrapper_with_class(:stringish)
21
+ it_should_have_input_class_in_the_right_place
22
+ it_should_have_input_wrapper_with_id("post_title_input")
23
+ it_should_have_label_with_text(/Title/)
24
+ it_should_have_label_for("post_title")
25
+ it_should_have_input_with_id("post_title")
26
+ it_should_have_input_with_type(:password)
27
+ it_should_have_input_with_name("post[title]")
28
+ it_should_have_maxlength_matching_column_limit
29
+ it_should_use_default_text_field_size_when_not_nil(:string)
30
+ it_should_not_use_default_text_field_size_when_nil(:string)
31
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
32
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
33
+ it_should_apply_error_logic_for_input_type(:password)
34
+
35
+ describe "when no object is provided" do
36
+ before do
37
+ concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
38
+ concat(builder.input(:title, :as => :password))
39
+ end)
40
+ end
41
+
42
+ it_should_have_label_with_text(/Title/)
43
+ it_should_have_label_for("project_title")
44
+ it_should_have_input_with_id("project_title")
45
+ it_should_have_input_with_type(:password)
46
+ it_should_have_input_with_name("project[title]")
47
+ end
48
+
49
+ describe "when namespace is provided" do
50
+
51
+ before do
52
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
53
+ concat(builder.input(:title, :as => :password))
54
+ end)
55
+ end
56
+
57
+ it_should_have_input_wrapper_with_id("context2_post_title_input")
58
+ it_should_have_label_and_input_with_id("context2_post_title")
59
+
60
+ end
61
+
62
+ describe "when index is provided" do
63
+
64
+ before do
65
+ @output_buffer = ''
66
+ mock_everything
67
+
68
+ concat(semantic_form_for(@new_post) do |builder|
69
+ concat(builder.fields_for(:author, :index => 3) do |author|
70
+ concat(author.input(:name, :as => :password))
71
+ end)
72
+ end)
73
+ end
74
+
75
+ it 'should index the id of the wrapper' do
76
+ output_buffer.should have_tag("div#post_author_attributes_3_name_input")
77
+ end
78
+
79
+ it 'should index the id of the select tag' do
80
+ output_buffer.should have_tag("input#post_author_attributes_3_name")
81
+ end
82
+
83
+ it 'should index the name of the select tag' do
84
+ output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']")
85
+ end
86
+
87
+ end
88
+
89
+
90
+ describe "when required" do
91
+ it "should add the required attribute to the input's html options" do
92
+ with_config :use_required_attribute, true do
93
+ concat(semantic_form_for(@new_post) do |builder|
94
+ concat(builder.input(:title, :as => :password, :required => true))
95
+ end)
96
+ output_buffer.should have_tag("input[@required]")
97
+ end
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,87 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'phone input' 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 "when object is provided" do
15
+ before do
16
+ concat(semantic_form_for(@new_post) do |builder|
17
+ concat(builder.input(:phone))
18
+ end)
19
+ end
20
+
21
+ it_should_have_input_wrapper_with_class('phone-wrapper')
22
+ it_should_have_input_wrapper_with_class("control-group")
23
+ it_should_have_input_wrapper_with_class(:stringish)
24
+ it_should_have_input_class_in_the_right_place
25
+ it_should_have_input_wrapper_with_id("post_phone_input")
26
+ it_should_have_label_with_text(/Phone/)
27
+ it_should_have_label_for("post_phone")
28
+ it_should_have_input_with_id("post_phone")
29
+ it_should_have_input_with_type(:tel)
30
+ it_should_have_input_with_name("post[phone]")
31
+
32
+ end
33
+
34
+ describe "when namespace is provided" do
35
+
36
+ before do
37
+ concat(semantic_form_for(@new_post, :namespace => "context2") do |builder|
38
+ concat(builder.input(:phone))
39
+ end)
40
+ end
41
+
42
+ it_should_have_input_wrapper_with_id("context2_post_phone_input")
43
+ it_should_have_label_and_input_with_id("context2_post_phone")
44
+
45
+ end
46
+
47
+ describe "when index is provided" do
48
+
49
+ before do
50
+ @output_buffer = ''
51
+ mock_everything
52
+
53
+ concat(semantic_form_for(@new_post) do |builder|
54
+ concat(builder.fields_for(:author, :index => 3) do |author|
55
+ concat(author.input(:name, :as => :phone))
56
+ end)
57
+ end)
58
+ end
59
+
60
+ it 'should index the id of the wrapper' do
61
+ output_buffer.should have_tag("div#post_author_attributes_3_name_input")
62
+ end
63
+
64
+ it 'should index the id of the select tag' do
65
+ output_buffer.should have_tag("input#post_author_attributes_3_name")
66
+ end
67
+
68
+ it 'should index the name of the select tag' do
69
+ output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']")
70
+ end
71
+
72
+ end
73
+
74
+
75
+ describe "when required" do
76
+ it "should add the required attribute to the input's html options" do
77
+ with_config :use_required_attribute, true do
78
+ concat(semantic_form_for(@new_post) do |builder|
79
+ concat(builder.input(:title, :as => :phone, :required => true))
80
+ end)
81
+ output_buffer.should have_tag("input[@required]")
82
+ end
83
+ end
84
+ end
85
+
86
+ end
87
+
@@ -0,0 +1,268 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'radio input' 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 'for belongs_to association' do
15
+ before do
16
+ concat(semantic_form_for(@new_post) do |builder|
17
+ concat(builder.input(:author, :as => :radio, :value_as_class => true, :required => true))
18
+ end)
19
+ end
20
+
21
+ it_should_have_input_wrapper_with_class("radio-wrapper")
22
+ it_should_have_input_wrapper_with_class("control-group")
23
+ it_should_have_input_class_in_the_right_place
24
+ it_should_have_input_wrapper_with_id("post_author_input")
25
+ it_should_have_a_nested_div
26
+ it_should_have_a_nested_div_with_class('choices.controls')
27
+ #it_should_have_a_nested_unordered_list_with_class('choices-group.inputs-list')
28
+ it_should_apply_error_logic_for_input_type(:radio, :block)
29
+ it_should_use_the_collection_when_provided(:radio, 'input[@type="radio"]')
30
+
31
+ it 'should generate a \'legend\' containing a label with text for the input' do
32
+ output_buffer.should have_tag('form div.control-group label.control-label')
33
+ output_buffer.should have_tag('form div.control-group label.control-label', /Author/)
34
+ end
35
+
36
+ it 'should not link the \'legend\' label to any input' do
37
+ output_buffer.should_not have_tag('form div.control-group > label.control-label[@for]')
38
+ end
39
+
40
+ # it 'should generate an unordered list with a list item for each choice' do
41
+ # output_buffer.should have_tag('form div.control-group div.controls ul')
42
+ # output_buffer.should have_tag('form div.control-group div.controls ul li.choice', :count => ::Author.all.size)
43
+ # end
44
+
45
+ it 'should have one option with a "checked" attribute' do
46
+ output_buffer.should have_tag('form .controls input[@checked]', :count => 1)
47
+ end
48
+
49
+ describe "each choice" do
50
+
51
+ it 'should not give the choice label the .control-label class' do
52
+ output_buffer.should_not have_tag('div.controls label.control-label')
53
+ end
54
+
55
+ it 'should not add the required attribute to each input' do
56
+ output_buffer.should_not have_tag('li.choice input[@required]')
57
+ end
58
+
59
+
60
+ it 'should contain a label for the radio input with a nested input and label text' do
61
+ ::Author.all.each do |author|
62
+ output_buffer.should have_tag('form div.control-group div.controls label.radio', /#{author.to_label}/)
63
+ output_buffer.should have_tag("form div.control-group div.controls label.radio[@for='post_author_id_#{author.id}']")
64
+ end
65
+ end
66
+
67
+ it 'should use values as li.class when value_as_class is true' do
68
+ ::Author.all.each do |author|
69
+ output_buffer.should have_tag("form div.control-group label.radio.author_#{author.id}")
70
+ end
71
+ end
72
+
73
+ it "should have a radio input" do
74
+ ::Author.all.each do |author|
75
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input#post_author_id_#{author.id}")
76
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input[@type='radio']")
77
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input[@value='#{author.id}']")
78
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input[@name='post[author_id]']")
79
+ end
80
+ end
81
+
82
+ it "should mark input as checked if it's the the existing choice" do
83
+ @new_post.author_id.should == @bob.id
84
+ @new_post.author.id.should == @bob.id
85
+ @new_post.author.should == @bob
86
+
87
+ concat(semantic_form_for(@new_post) do |builder|
88
+ concat(builder.input(:author, :as => :radio))
89
+ end)
90
+
91
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input[@checked='checked']")
92
+ end
93
+
94
+ it "should mark the input as disabled if options attached for disabling" do
95
+ concat(semantic_form_for(@new_post) do |builder|
96
+ concat(builder.input(:author, :as => :radio, :collection => [["Test", 'test'], ["Try", "try", {:disabled => true}]]))
97
+ end)
98
+
99
+ output_buffer.should_not have_tag("form div.control-group div.controls label.radio input[@value='test'][@disabled='disabled']")
100
+ output_buffer.should have_tag("form div.control-group div.controls label.radio input[@value='try'][@disabled='disabled']")
101
+ end
102
+
103
+ it "should not contain invalid HTML attributes" do
104
+
105
+ concat(semantic_form_for(@new_post) do |builder|
106
+ concat(builder.input(:author, :as => :radio))
107
+ end)
108
+
109
+ output_buffer.should_not have_tag("form div.control-group div.controls input[@find_options]")
110
+ end
111
+
112
+ end
113
+
114
+ describe 'and no object is given' do
115
+ before(:each) do
116
+ output_buffer.replace ''
117
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
118
+ concat(builder.input(:author_id, :as => :radio, :collection => ::Author.all))
119
+ end)
120
+ end
121
+
122
+ it 'should generate a div with a label' do
123
+ output_buffer.should have_tag('form div.control-group label.control-label', /Author/)
124
+ end
125
+
126
+ it 'should generate an li tag for each item in the collection' do
127
+ output_buffer.should have_tag('form div.control-group div label.radio', :count => ::Author.all.size)
128
+ end
129
+
130
+ it 'should generate labels for each item' do
131
+ ::Author.all.each do |author|
132
+ output_buffer.should have_tag('form div div label.radio', /#{author.to_label}/)
133
+ output_buffer.should have_tag("form div div label.radio[@for='project_author_id_#{author.id}']")
134
+ end
135
+ end
136
+
137
+ it 'should html escape the label string' do
138
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
139
+ concat(builder.input(:author_id, :as => :radio, :collection => [["<b>Item 1</b>", 1], ["<b>Item 2</b>", 2]]))
140
+ end)
141
+ output_buffer.should have_tag('form div div label.radio') do |label|
142
+ # label.body.should match /&lt;b&gt;Item [12]&lt;\/b&gt;$/
143
+ label.body.should match /&lt;b&gt;Item [12]&lt;\/b&gt;/
144
+ end
145
+ end
146
+
147
+ it 'should generate inputs for each item' do
148
+ ::Author.all.each do |author|
149
+ output_buffer.should have_tag("form div div label.radio input#project_author_id_#{author.id}")
150
+ output_buffer.should have_tag("form div div label.radio input[@type='radio']")
151
+ output_buffer.should have_tag("form div div label.radio input[@value='#{author.id}']")
152
+ output_buffer.should have_tag("form div div label.radio input[@name='project[author_id]']")
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ describe "with i18n of the legend label" do
159
+
160
+ before do
161
+ ::I18n.backend.store_translations :en, :formtastic => { :labels => { :post => { :authors => "Translated!" }}}
162
+
163
+ with_config :i18n_lookups_by_default, true do
164
+ @new_post.stub!(:author_ids).and_return(nil)
165
+ concat(semantic_form_for(@new_post) do |builder|
166
+ concat(builder.input(:authors, :as => :radio))
167
+ end)
168
+ end
169
+ end
170
+
171
+ after do
172
+ ::I18n.backend.reload!
173
+ end
174
+
175
+ it "should do foo" do
176
+ output_buffer.should have_tag("div.control-group > label.control-label", /Translated/)
177
+ end
178
+
179
+ end
180
+
181
+ describe "when :label option is set" do
182
+ before do
183
+ @new_post.stub!(:author_ids).and_return(nil)
184
+ concat(semantic_form_for(@new_post) do |builder|
185
+ concat(builder.input(:authors, :as => :radio, :label => 'The authors'))
186
+ end)
187
+ end
188
+
189
+ it "should output the correct label title" do
190
+ output_buffer.should have_tag("div.control-group > label.control-label", /The authors/)
191
+ end
192
+ end
193
+
194
+ describe "when :label option is false" do
195
+ before do
196
+ @output_buffer = ''
197
+ @new_post.stub!(:author_ids).and_return(nil)
198
+ concat(semantic_form_for(@new_post) do |builder|
199
+ concat(builder.input(:authors, :as => :radio, :label => false))
200
+ end)
201
+ end
202
+
203
+ it "should not output the legend" do
204
+ output_buffer.should_not have_tag("legend.control-label")
205
+ output_buffer.should_not include("&gt;")
206
+ end
207
+
208
+ it "should not cause escaped HTML" do
209
+ output_buffer.should_not include("&gt;")
210
+ end
211
+ end
212
+
213
+ describe "when :required option is true" do
214
+ before do
215
+ @new_post.stub!(:author_ids).and_return(nil)
216
+ concat(semantic_form_for(@new_post) do |builder|
217
+ concat(builder.input(:authors, :as => :radio, :required => true))
218
+ end)
219
+ end
220
+
221
+ it "should output the correct label title" do
222
+ output_buffer.should have_tag("div.control-group label.control-label abbr")
223
+ end
224
+ end
225
+
226
+ describe "when :namespace is given on form" do
227
+ before do
228
+ @output_buffer = ''
229
+ @new_post.stub!(:author_ids).and_return(nil)
230
+ concat(semantic_form_for(@new_post, :namespace => "custom_prefix") do |builder|
231
+ concat(builder.input(:authors, :as => :radio, :label => ''))
232
+ end)
233
+
234
+ output_buffer.should match(/for="custom_prefix_post_author_ids_(\d+)"/)
235
+ output_buffer.should match(/id="custom_prefix_post_author_ids_(\d+)"/)
236
+ end
237
+ it_should_have_input_wrapper_with_id("custom_prefix_post_authors_input")
238
+ end
239
+
240
+ describe "when index is provided" do
241
+
242
+ before do
243
+ @output_buffer = ''
244
+ mock_everything
245
+
246
+ concat(semantic_form_for(@new_post) do |builder|
247
+ concat(builder.fields_for(:author, :index => 3) do |author|
248
+ concat(author.input(:name, :as => :radio))
249
+ end)
250
+ end)
251
+ end
252
+
253
+ it 'should index the id of the wrapper' do
254
+ output_buffer.should have_tag("div#post_author_attributes_3_name_input")
255
+ end
256
+
257
+ it 'should index the id of the select tag' do
258
+ output_buffer.should have_tag("input#post_author_attributes_3_name_true")
259
+ output_buffer.should have_tag("input#post_author_attributes_3_name_false")
260
+ end
261
+
262
+ it 'should index the name of the select tag' do
263
+ output_buffer.should have_tag("input[@name='post[author_attributes][3][name]']")
264
+ end
265
+
266
+ end
267
+
268
+ end