formtastic 2.0.2 → 2.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/.gitignore +4 -1
  2. data/Appraisals +11 -0
  3. data/CHANGELOG +2 -2
  4. data/Gemfile +0 -2
  5. data/README.textile +183 -151
  6. data/Rakefile +9 -5
  7. data/app/assets/stylesheets/formtastic.css +16 -3
  8. data/formtastic.gemspec +6 -2
  9. data/gemfiles/rails-3.0.gemfile +7 -0
  10. data/gemfiles/rails-3.1.gemfile +7 -0
  11. data/gemfiles/rails-3.2.gemfile +7 -0
  12. data/lib/formtastic.rb +10 -2
  13. data/lib/formtastic/actions.rb +11 -0
  14. data/lib/formtastic/actions/base.rb +156 -0
  15. data/lib/formtastic/actions/button_action.rb +72 -0
  16. data/lib/formtastic/actions/buttonish.rb +17 -0
  17. data/lib/formtastic/actions/input_action.rb +68 -0
  18. data/lib/formtastic/actions/link_action.rb +87 -0
  19. data/lib/formtastic/engine.rb +5 -1
  20. data/lib/formtastic/form_builder.rb +3 -0
  21. data/lib/formtastic/helpers.rb +2 -1
  22. data/lib/formtastic/helpers/action_helper.rb +109 -0
  23. data/lib/formtastic/helpers/actions_helper.rb +168 -0
  24. data/lib/formtastic/helpers/buttons_helper.rb +22 -9
  25. data/lib/formtastic/helpers/errors_helper.rb +0 -54
  26. data/lib/formtastic/helpers/fieldset_wrapper.rb +10 -5
  27. data/lib/formtastic/helpers/form_helper.rb +2 -2
  28. data/lib/formtastic/helpers/input_helper.rb +1 -10
  29. data/lib/formtastic/helpers/inputs_helper.rb +6 -3
  30. data/lib/formtastic/i18n.rb +3 -2
  31. data/lib/formtastic/inputs/base.rb +11 -3
  32. data/lib/formtastic/inputs/base/choices.rb +6 -1
  33. data/lib/formtastic/inputs/base/collections.rb +36 -13
  34. data/lib/formtastic/inputs/base/grouped_collections.rb +1 -1
  35. data/lib/formtastic/inputs/base/numeric.rb +50 -0
  36. data/lib/formtastic/inputs/base/options.rb +1 -1
  37. data/lib/formtastic/inputs/base/placeholder.rb +17 -0
  38. data/lib/formtastic/inputs/base/stringish.rb +2 -7
  39. data/lib/formtastic/inputs/base/timeish.rb +21 -5
  40. data/lib/formtastic/inputs/base/validations.rb +1 -1
  41. data/lib/formtastic/inputs/base/wrapping.rb +10 -3
  42. data/lib/formtastic/inputs/boolean_input.rb +10 -2
  43. data/lib/formtastic/inputs/check_boxes_input.rb +18 -9
  44. data/lib/formtastic/inputs/country_input.rb +2 -2
  45. data/lib/formtastic/inputs/date_input.rb +19 -1
  46. data/lib/formtastic/inputs/datetime_input.rb +1 -1
  47. data/lib/formtastic/inputs/email_input.rb +2 -1
  48. data/lib/formtastic/inputs/file_input.rb +1 -1
  49. data/lib/formtastic/inputs/hidden_input.rb +1 -1
  50. data/lib/formtastic/inputs/number_input.rb +6 -36
  51. data/lib/formtastic/inputs/password_input.rb +2 -1
  52. data/lib/formtastic/inputs/phone_input.rb +3 -2
  53. data/lib/formtastic/inputs/radio_input.rb +1 -1
  54. data/lib/formtastic/inputs/range_input.rb +8 -32
  55. data/lib/formtastic/inputs/search_input.rb +2 -1
  56. data/lib/formtastic/inputs/select_input.rb +56 -28
  57. data/lib/formtastic/inputs/string_input.rb +3 -1
  58. data/lib/formtastic/inputs/text_input.rb +5 -4
  59. data/lib/formtastic/inputs/time_input.rb +4 -8
  60. data/lib/formtastic/inputs/time_zone_input.rb +1 -1
  61. data/lib/formtastic/inputs/url_input.rb +2 -1
  62. data/lib/formtastic/localized_string.rb +6 -94
  63. data/lib/formtastic/localizer.rb +110 -0
  64. data/lib/formtastic/version.rb +1 -1
  65. data/lib/generators/formtastic/form/form_generator.rb +105 -0
  66. data/lib/generators/templates/_form.html.erb +2 -2
  67. data/lib/generators/templates/_form.html.haml +4 -4
  68. data/lib/generators/templates/_form.html.slim +2 -2
  69. data/lib/generators/templates/formtastic.rb +4 -0
  70. data/lib/locale/en.yml +2 -0
  71. data/sample/basic_inputs.html +22 -0
  72. data/spec/actions/button_action_spec.rb +63 -0
  73. data/spec/actions/generic_action_spec.rb +484 -0
  74. data/spec/actions/input_action_spec.rb +59 -0
  75. data/spec/actions/link_action_spec.rb +92 -0
  76. data/spec/builder/semantic_fields_for_spec.rb +14 -0
  77. data/spec/generators/formtastic/form/form_generator_spec.rb +118 -0
  78. data/spec/generators/formtastic/install/install_generator_spec.rb +47 -0
  79. data/spec/helpers/action_helper_spec.rb +365 -0
  80. data/spec/helpers/actions_helper_spec.rb +143 -0
  81. data/spec/helpers/buttons_helper_spec.rb +39 -23
  82. data/spec/helpers/commit_button_helper_spec.rb +153 -93
  83. data/spec/helpers/inputs_helper_spec.rb +14 -0
  84. data/spec/i18n_spec.rb +11 -0
  85. data/spec/inputs/boolean_input_spec.rb +31 -2
  86. data/spec/inputs/check_boxes_input_spec.rb +29 -1
  87. data/spec/inputs/date_input_spec.rb +95 -0
  88. data/spec/inputs/datetime_input_spec.rb +49 -0
  89. data/spec/inputs/email_input_spec.rb +28 -0
  90. data/spec/inputs/file_input_spec.rb +28 -0
  91. data/spec/inputs/hidden_input_spec.rb +28 -0
  92. data/spec/inputs/include_blank_spec.rb +53 -45
  93. data/spec/inputs/number_input_spec.rb +34 -4
  94. data/spec/inputs/password_input_spec.rb +28 -0
  95. data/spec/inputs/phone_input_spec.rb +28 -0
  96. data/spec/inputs/placeholder_spec.rb +10 -10
  97. data/spec/inputs/radio_input_spec.rb +51 -6
  98. data/spec/inputs/range_input_spec.rb +30 -2
  99. data/spec/inputs/search_input_spec.rb +27 -0
  100. data/spec/inputs/select_input_spec.rb +52 -6
  101. data/spec/inputs/string_input_spec.rb +28 -0
  102. data/spec/inputs/text_input_spec.rb +27 -0
  103. data/spec/inputs/time_input_spec.rb +67 -1
  104. data/spec/inputs/time_zone_input_spec.rb +28 -0
  105. data/spec/inputs/url_input_spec.rb +28 -0
  106. data/spec/inputs/with_options_spec.rb +43 -0
  107. data/spec/spec_helper.rb +22 -6
  108. data/spec/support/custom_macros.rb +6 -134
  109. data/spec/support/test_environment.rb +0 -1
  110. metadata +104 -17
  111. data/lib/formtastic/helpers/semantic_form_helper.rb +0 -11
  112. data/lib/formtastic/inputs/numeric_input.rb +0 -21
  113. data/lib/formtastic/railtie.rb +0 -12
  114. data/lib/formtastic/semantic_form_builder.rb +0 -11
  115. data/spec/builder/errors_spec.rb +0 -203
  116. data/spec/inputs/numeric_input_spec.rb +0 -41
@@ -1,8 +1,8 @@
1
1
  = semantic_form_for @<%= singular_name %> do |f|
2
2
  = f.inputs do
3
- <% attributes.each do |attribute| -%>
3
+ <%- attributes.each do |attribute| -%>
4
4
  = f.input :<%= attribute.name %>
5
- <% end -%>
5
+ <%- end -%>
6
6
 
7
- = f.buttons do
8
- = f.commit_button
7
+ = f.actions do
8
+ = f.action :submit, :as => :input
@@ -1,8 +1,8 @@
1
1
  = semantic_form_for @<%= singular_name %> do |f|
2
2
  = f.inputs do
3
- <% attributes.each do |attribute| -%>
3
+ <%- attributes.each do |attribute| -%>
4
4
  = f.input :<%= attribute.name %>
5
- <% end -%>
5
+ <%- end -%>
6
6
 
7
7
  = f.buttons do
8
8
  = f.commit_button
@@ -68,6 +68,10 @@
68
68
  # i.e. :label => true, or :hint => true (or opposite depending on initialized value)
69
69
  # Formtastic::FormBuilder.i18n_lookups_by_default = false
70
70
 
71
+ # Specifies the class to use for localization lookups. You can create your own
72
+ # class and use it instead by subclassing Formtastic::Localizer (which is the default).
73
+ # Formtastic::FormBuilder.i18n_localizer = MyOwnLocalizer
74
+
71
75
  # You can add custom inputs or override parts of Formtastic by subclassing Formtastic::FormBuilder and
72
76
  # specifying that class here. Defaults to Formtastic::FormBuilder.
73
77
  # Formtastic::Helpers::FormHelper.builder = MyCustomBuilder
data/lib/locale/en.yml CHANGED
@@ -5,4 +5,6 @@ en:
5
5
  :create: 'Create %{model}'
6
6
  :update: 'Update %{model}'
7
7
  :submit: 'Submit %{model}'
8
+ :cancel: 'Cancel %{model}'
9
+ :reset: 'Reset %{model}'
8
10
  :required: 'required'
@@ -177,6 +177,28 @@
177
177
  </li>
178
178
  </ol>
179
179
  </fieldset>
180
+
181
+ <fieldset class="actions">
182
+ <ol>
183
+ <li class="action input_action">
184
+ <input id="gem_submit" type="submit" value="Create Thing">
185
+ </li>
186
+ </ol>
187
+ </fieldset>
188
+
189
+ <fieldset class="actions">
190
+ <ol>
191
+ <li class="action button_action">
192
+ <button id="gem_submit" type="submit">Create Thing</button>
193
+ </li>
194
+ <li class="action button_action">
195
+ <button id="gem_submit" type="reset">Reset</button>
196
+ </li>
197
+ <li class="action link_action">
198
+ <a href="#">Cancel</button>
199
+ </li>
200
+ </ol>
201
+ </fieldset>
180
202
  </form>
181
203
  </body>
182
204
  </html>
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'ButtonAction', 'when submitting' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ concat(semantic_form_for(@new_post) do |builder|
13
+ concat(builder.action(:submit, :as => :button))
14
+ end)
15
+ end
16
+
17
+ it 'should render a submit type of button' do
18
+ output_buffer.should have_tag('li.action.button_action button[@type="submit"]')
19
+ end
20
+
21
+ end
22
+
23
+ describe 'ButtonAction', 'when resetting' do
24
+
25
+ include FormtasticSpecHelper
26
+
27
+ before do
28
+ @output_buffer = ''
29
+ mock_everything
30
+
31
+ concat(semantic_form_for(@new_post) do |builder|
32
+ concat(builder.action(:reset, :as => :button))
33
+ end)
34
+ end
35
+
36
+ it 'should render a reset type of button' do
37
+ output_buffer.should have_tag('li.action.button_action button[@type="reset"]', :text => "Reset Post")
38
+ end
39
+
40
+ it 'should not render a value attribute' do
41
+ output_buffer.should_not have_tag('li.action.button_action button[@value]')
42
+ end
43
+
44
+ end
45
+
46
+ describe 'InputAction', 'when cancelling' do
47
+
48
+ include FormtasticSpecHelper
49
+
50
+ before do
51
+ @output_buffer = ''
52
+ mock_everything
53
+ end
54
+
55
+ it 'should raise an error' do
56
+ lambda {
57
+ concat(semantic_form_for(@new_post) do |builder|
58
+ concat(builder.action(:cancel, :as => :button))
59
+ end)
60
+ }.should raise_error(Formtastic::UnsupportedMethodForAction)
61
+ end
62
+
63
+ end
@@ -0,0 +1,484 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'InputAction::Base' do
5
+
6
+ # Most basic Action class to test Base
7
+ class ::GenericAction
8
+ include ::Formtastic::Actions::Base
9
+
10
+ def supported_methods
11
+ [:submit, :reset, :cancel]
12
+ end
13
+
14
+ def to_html
15
+ wrapper do
16
+ builder.submit(text, button_html)
17
+ end
18
+ end
19
+ end
20
+
21
+ include FormtasticSpecHelper
22
+
23
+ before do
24
+ @output_buffer = ''
25
+ mock_everything
26
+ end
27
+
28
+ describe 'wrapping HTML' do
29
+
30
+ before do
31
+ concat(semantic_form_for(@new_post) do |builder|
32
+ concat(builder.action(:submit, :as => :generic,
33
+ :wrapper_html => { :foo => 'bah' }
34
+ ))
35
+ end)
36
+ end
37
+
38
+ it 'should add the #foo id to the li' do
39
+ output_buffer.should have_tag('li#post_submit_action')
40
+ end
41
+
42
+ it 'should add the .action and .generic_action classes to the li' do
43
+ output_buffer.should have_tag('li.action.generic_action')
44
+ end
45
+
46
+ it 'should pass :wrapper_html HTML attributes to the wrapper' do
47
+ output_buffer.should have_tag('li.action.generic_action[@foo="bah"]')
48
+ end
49
+
50
+ context "when a custom :id is provided" do
51
+
52
+ before do
53
+ concat(semantic_form_for(@new_post) do |builder|
54
+ concat(builder.action(:submit, :as => :generic,
55
+ :wrapper_html => { :id => 'foo_bah_bing' }
56
+ ))
57
+ end)
58
+ end
59
+
60
+ it "should use the custom id" do
61
+ output_buffer.should have_tag('li#foo_bah_bing')
62
+ end
63
+
64
+ end
65
+
66
+ context "when a custom class is provided as a string" do
67
+
68
+ before do
69
+ concat(semantic_form_for(@new_post) do |builder|
70
+ concat(builder.action(:submit, :as => :generic,
71
+ :wrapper_html => { :class => 'foo_bah_bing' }
72
+ ))
73
+ end)
74
+ end
75
+
76
+ it "should add the custom class strng to the existing classes" do
77
+ output_buffer.should have_tag('li.action.generic_action.foo_bah_bing')
78
+ end
79
+
80
+ end
81
+
82
+ context "when a custom class is provided as an array" do
83
+
84
+ before do
85
+ concat(semantic_form_for(@new_post) do |builder|
86
+ concat(builder.action(:submit, :as => :generic,
87
+ :wrapper_html => { :class => ['foo_bah_bing', 'zing_boo'] }
88
+ ))
89
+ end)
90
+ end
91
+
92
+ it "should add the custom class strng to the existing classes" do
93
+ output_buffer.should have_tag('li.action.generic_action.foo_bah_bing.zing_boo')
94
+ end
95
+
96
+ end
97
+
98
+ end
99
+
100
+ describe 'button HTML' do
101
+
102
+ before do
103
+ concat(semantic_form_for(@new_post) do |builder|
104
+ concat(builder.action(:submit, :as => :generic,
105
+ :button_html => { :foo => 'bah' }
106
+ ))
107
+ end)
108
+ end
109
+
110
+ it 'should pass :button_html HTML attributes to the button' do
111
+ output_buffer.should have_tag('li.action.generic_action input[@foo="bah"]')
112
+ end
113
+
114
+ it 'should respect a default_commit_button_accesskey configuration with nil' do
115
+ with_config :default_commit_button_accesskey, nil do
116
+ concat(semantic_form_for(@new_post) do |builder|
117
+ concat(builder.action(:submit, :as => :generic))
118
+ end)
119
+ output_buffer.should_not have_tag('li.action input[@accesskey]')
120
+ end
121
+ end
122
+
123
+ it 'should respect a default_commit_button_accesskey configuration with a String' do
124
+ with_config :default_commit_button_accesskey, 's' do
125
+ concat(semantic_form_for(@new_post) do |builder|
126
+ concat(builder.action(:submit, :as => :generic))
127
+ end)
128
+ output_buffer.should have_tag('li.action input[@accesskey="s"]')
129
+ end
130
+ end
131
+
132
+ it 'should respect an accesskey through options over configration' do
133
+ with_config :default_commit_button_accesskey, 's' do
134
+ concat(semantic_form_for(@new_post) do |builder|
135
+ concat(builder.action(:submit, :as => :generic, :accesskey => 'o'))
136
+ end)
137
+ output_buffer.should_not have_tag('li.action input[@accesskey="s"]')
138
+ output_buffer.should have_tag('li.action input[@accesskey="o"]')
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ describe 'labelling' do
145
+
146
+ describe 'when used without object' do
147
+
148
+ describe 'when explicit label is provided' do
149
+ it 'should render an input with the explicitly specified label' do
150
+ concat(semantic_form_for(:post, :url => 'http://example.com') do |builder|
151
+ concat(builder.action(:submit, :as => :generic, :label => "Click!"))
152
+ concat(builder.action(:reset, :as => :generic, :label => "Reset!"))
153
+ concat(builder.action(:cancel, :as => :generic, :label => "Cancel!"))
154
+ end)
155
+ output_buffer.should have_tag('li.generic_action input[@value="Click!"]')
156
+ output_buffer.should have_tag('li.generic_action input[@value="Reset!"]')
157
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel!"]')
158
+ end
159
+ end
160
+
161
+ describe 'when no explicit label is provided' do
162
+ describe 'when no I18n-localized label is provided' do
163
+ before do
164
+ ::I18n.backend.store_translations :en, :formtastic => {
165
+ :submit => 'Submit %{model}',
166
+ :reset => 'Reset %{model}',
167
+ :cancel => 'Cancel %{model}'
168
+ }
169
+ end
170
+
171
+ after do
172
+ ::I18n.backend.reload!
173
+ end
174
+
175
+ it 'should render an input with default I18n-localized label (fallback)' do
176
+ concat(semantic_form_for(:post, :url => 'http://example.com') do |builder|
177
+ concat(builder.action(:submit, :as => :generic))
178
+ concat(builder.action(:reset, :as => :generic))
179
+ concat(builder.action(:cancel, :as => :generic))
180
+ end)
181
+ output_buffer.should have_tag('li.generic_action input[@value="Submit Post"]')
182
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel Post"]')
183
+ output_buffer.should have_tag('li.generic_action input[@value="Reset Post"]')
184
+ end
185
+ end
186
+
187
+ describe 'when I18n-localized label is provided' do
188
+
189
+ before do
190
+ ::I18n.backend.store_translations :en,
191
+ :formtastic => {
192
+ :actions => {
193
+ :submit => 'Custom Submit',
194
+ :reset => 'Custom Reset',
195
+ :cancel => 'Custom Cancel'
196
+ }
197
+ }
198
+ end
199
+
200
+ after do
201
+ ::I18n.backend.reload!
202
+ end
203
+
204
+ it 'should render an input with localized label (I18n)' do
205
+ with_config :i18n_lookups_by_default, true do
206
+ ::I18n.backend.store_translations :en,
207
+ :formtastic => {
208
+ :actions => {
209
+ :post => {
210
+ :submit => 'Custom Submit %{model}',
211
+ :reset => 'Custom Reset %{model}',
212
+ :cancel => 'Custom Cancel %{model}'
213
+ }
214
+ }
215
+ }
216
+ concat(semantic_form_for(:post, :url => 'http://example.com') do |builder|
217
+ concat(builder.action(:submit, :as => :generic))
218
+ concat(builder.action(:reset, :as => :generic))
219
+ concat(builder.action(:cancel, :as => :generic))
220
+ end)
221
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Submit Post"]})
222
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset Post"]})
223
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel Post"]})
224
+ end
225
+ end
226
+
227
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
228
+ with_config :i18n_lookups_by_default, true do
229
+ concat(semantic_form_for(:post, :url => 'http://example.com') do |builder|
230
+ concat(builder.action(:submit, :as => :generic))
231
+ concat(builder.action(:reset, :as => :generic))
232
+ concat(builder.action(:cancel, :as => :generic))
233
+ end)
234
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Submit"]})
235
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset"]})
236
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel"]})
237
+ end
238
+ end
239
+
240
+ end
241
+ end
242
+ end
243
+
244
+ describe 'when used on a new record' do
245
+ before do
246
+ @new_post.stub!(:new_record?).and_return(true)
247
+ end
248
+
249
+ describe 'when explicit label is provided' do
250
+ it 'should render an input with the explicitly specified label' do
251
+ concat(semantic_form_for(@new_post) do |builder|
252
+ concat(builder.action(:submit, :as => :generic, :label => "Click!"))
253
+ concat(builder.action(:reset, :as => :generic, :label => "Reset!"))
254
+ concat(builder.action(:cancel, :as => :generic, :label => "Cancel!"))
255
+ end)
256
+ output_buffer.should have_tag('li.generic_action input[@value="Click!"]')
257
+ output_buffer.should have_tag('li.generic_action input[@value="Reset!"]')
258
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel!"]')
259
+ end
260
+ end
261
+
262
+ describe 'when no explicit label is provided' do
263
+ describe 'when no I18n-localized label is provided' do
264
+ before do
265
+ ::I18n.backend.store_translations :en, :formtastic => {
266
+ :create => 'Create %{model}',
267
+ :reset => 'Reset %{model}',
268
+ :cancel => 'Cancel %{model}'
269
+ }
270
+ end
271
+
272
+ after do
273
+ ::I18n.backend.reload!
274
+ end
275
+
276
+ it 'should render an input with default I18n-localized label (fallback)' do
277
+ concat(semantic_form_for(@new_post) do |builder|
278
+ concat(builder.action(:submit, :as => :generic))
279
+ concat(builder.action(:reset, :as => :generic))
280
+ concat(builder.action(:cancel, :as => :generic))
281
+ end)
282
+ output_buffer.should have_tag('li.generic_action input[@value="Create Post"]')
283
+ output_buffer.should have_tag('li.generic_action input[@value="Reset Post"]')
284
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel Post"]')
285
+ end
286
+ end
287
+
288
+ describe 'when I18n-localized label is provided' do
289
+ before do
290
+ ::I18n.backend.store_translations :en,
291
+ :formtastic => {
292
+ :actions => {
293
+ :create => 'Custom Create',
294
+ :reset => 'Custom Reset',
295
+ :cancel => 'Custom Cancel'
296
+ }
297
+ }
298
+ end
299
+
300
+ after do
301
+ ::I18n.backend.reload!
302
+ end
303
+
304
+ it 'should render an input with localized label (I18n)' do
305
+ with_config :i18n_lookups_by_default, true do
306
+ ::I18n.backend.store_translations :en,
307
+ :formtastic => {
308
+ :actions => {
309
+ :post => {
310
+ :create => 'Custom Create %{model}',
311
+ :reset => 'Custom Reset %{model}',
312
+ :cancel => 'Custom Cancel %{model}'
313
+ }
314
+ }
315
+ }
316
+ concat(semantic_form_for(@new_post) do |builder|
317
+ concat(builder.action(:submit, :as => :generic))
318
+ concat(builder.action(:reset, :as => :generic))
319
+ concat(builder.action(:cancel, :as => :generic))
320
+ end)
321
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Create Post"]})
322
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset Post"]})
323
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel Post"]})
324
+ end
325
+ end
326
+
327
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
328
+ with_config :i18n_lookups_by_default, true do
329
+ concat(semantic_form_for(@new_post) do |builder|
330
+ concat(builder.action(:submit, :as => :generic))
331
+ concat(builder.action(:reset, :as => :generic))
332
+ concat(builder.action(:cancel, :as => :generic))
333
+ end)
334
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Create"]})
335
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset"]})
336
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel"]})
337
+ end
338
+ end
339
+
340
+ end
341
+ end
342
+ end
343
+
344
+ describe 'when used on an existing record' do
345
+ before do
346
+ @new_post.stub!(:persisted?).and_return(true)
347
+ end
348
+
349
+ describe 'when explicit label is provided' do
350
+ it 'should render an input with the explicitly specified label' do
351
+ concat(semantic_form_for(@new_post) do |builder|
352
+ concat(builder.action(:submit, :as => :generic, :label => "Click!"))
353
+ concat(builder.action(:reset, :as => :generic, :label => "Reset!"))
354
+ concat(builder.action(:cancel, :as => :generic, :label => "Cancel!"))
355
+ end)
356
+ output_buffer.should have_tag('li.generic_action input[@value="Click!"]')
357
+ output_buffer.should have_tag('li.generic_action input[@value="Reset!"]')
358
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel!"]')
359
+ end
360
+ end
361
+
362
+ describe 'when no explicit label is provided' do
363
+ describe 'when no I18n-localized label is provided' do
364
+ before do
365
+ ::I18n.backend.store_translations :en, :formtastic => {
366
+ :update => 'Save %{model}',
367
+ :reset => 'Reset %{model}',
368
+ :cancel => 'Cancel %{model}'
369
+ }
370
+ end
371
+
372
+ after do
373
+ ::I18n.backend.reload!
374
+ end
375
+
376
+ it 'should render an input with default I18n-localized label (fallback)' do
377
+ concat(semantic_form_for(@new_post) do |builder|
378
+ concat(builder.action(:submit, :as => :generic))
379
+ concat(builder.action(:reset, :as => :generic))
380
+ concat(builder.action(:cancel, :as => :generic))
381
+ end)
382
+ output_buffer.should have_tag('li.generic_action input[@value="Save Post"]')
383
+ output_buffer.should have_tag('li.generic_action input[@value="Reset Post"]')
384
+ output_buffer.should have_tag('li.generic_action input[@value="Cancel Post"]')
385
+ end
386
+ end
387
+
388
+ describe 'when I18n-localized label is provided' do
389
+ before do
390
+ ::I18n.backend.reload!
391
+ ::I18n.backend.store_translations :en,
392
+ :formtastic => {
393
+ :actions => {
394
+ :update => 'Custom Save',
395
+ :reset => 'Custom Reset',
396
+ :cancel => 'Custom Cancel'
397
+ }
398
+ }
399
+ end
400
+
401
+ after do
402
+ ::I18n.backend.reload!
403
+ end
404
+
405
+ it 'should render an input with localized label (I18n)' do
406
+ with_config :i18n_lookups_by_default, true do
407
+ ::I18n.backend.store_translations :en,
408
+ :formtastic => {
409
+ :actions => {
410
+ :post => {
411
+ :update => 'Custom Save %{model}',
412
+ :reset => 'Custom Reset %{model}',
413
+ :cancel => 'Custom Cancel %{model}'
414
+ }
415
+ }
416
+ }
417
+ concat(semantic_form_for(@new_post) do |builder|
418
+ concat(builder.action(:submit, :as => :generic))
419
+ concat(builder.action(:reset, :as => :generic))
420
+ concat(builder.action(:cancel, :as => :generic))
421
+ end)
422
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Save Post"]})
423
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset Post"]})
424
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel Post"]})
425
+ end
426
+ end
427
+
428
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
429
+ with_config :i18n_lookups_by_default, true do
430
+ concat(semantic_form_for(@new_post) do |builder|
431
+ concat(builder.action(:submit, :as => :generic))
432
+ concat(builder.action(:reset, :as => :generic))
433
+ concat(builder.action(:cancel, :as => :generic))
434
+ end)
435
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Save"]})
436
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Reset"]})
437
+ output_buffer.should have_tag(%Q{li.generic_action input[@value="Custom Cancel"]})
438
+ ::I18n.backend.store_translations :en, :formtastic => {}
439
+ end
440
+ end
441
+
442
+ end
443
+ end
444
+ end
445
+ end
446
+
447
+ describe 'when the model is two words' do
448
+
449
+ before do
450
+ output_buffer = ''
451
+ class ::UserPost
452
+ extend ActiveModel::Naming if defined?(ActiveModel::Naming)
453
+ include ActiveModel::Conversion if defined?(ActiveModel::Conversion)
454
+
455
+ def id
456
+ end
457
+
458
+ def persisted?
459
+ end
460
+
461
+ # Rails does crappy human_name
462
+ def self.human_name
463
+ "User post"
464
+ end
465
+ end
466
+ @new_user_post = ::UserPost.new
467
+
468
+ @new_user_post.stub!(:new_record?).and_return(true)
469
+ concat(semantic_form_for(@new_user_post, :url => '') do |builder|
470
+ concat(builder.action(:submit, :as => :generic))
471
+ concat(builder.action(:reset, :as => :generic))
472
+ concat(builder.action(:cancel, :as => :generic))
473
+ end)
474
+ end
475
+
476
+ it "should render the string as the value of the button" do
477
+ output_buffer.should have_tag('li input[@value="Create User post"]')
478
+ output_buffer.should have_tag('li input[@value="Reset User post"]')
479
+ output_buffer.should have_tag('li input[@value="Cancel User post"]')
480
+ end
481
+
482
+ end
483
+
484
+ end