speedo-formstrap 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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