ShadowBelmolve-formtastic 0.2.1 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/README.textile +191 -176
  2. data/Rakefile +65 -22
  3. data/generators/form/USAGE +16 -0
  4. data/generators/form/form_generator.rb +120 -0
  5. data/generators/form/templates/view__form.html.erb +5 -0
  6. data/generators/form/templates/view__form.html.haml +4 -0
  7. data/generators/formtastic/formtastic_generator.rb +24 -0
  8. data/generators/{formtastic_stylesheets → formtastic}/templates/formtastic.css +2 -0
  9. data/generators/formtastic/templates/formtastic.rb +51 -0
  10. data/generators/{formtastic_stylesheets → formtastic}/templates/formtastic_changes.css +0 -0
  11. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +5 -10
  12. data/lib/formtastic.rb +1234 -895
  13. data/lib/formtastic/i18n.rb +32 -0
  14. data/lib/locale/en.yml +2 -2
  15. data/rails/init.rb +1 -1
  16. data/spec/buttons_spec.rb +149 -0
  17. data/spec/commit_button_spec.rb +344 -0
  18. data/spec/custom_builder_spec.rb +62 -0
  19. data/spec/custom_macros.rb +561 -0
  20. data/spec/defaults_spec.rb +20 -0
  21. data/spec/error_proc_spec.rb +27 -0
  22. data/spec/errors_spec.rb +85 -0
  23. data/spec/form_helper_spec.rb +120 -0
  24. data/spec/i18n_spec.rb +131 -0
  25. data/spec/include_blank_spec.rb +70 -0
  26. data/spec/input_spec.rb +608 -0
  27. data/spec/inputs/boolean_input_spec.rb +93 -0
  28. data/spec/inputs/check_boxes_input_spec.rb +162 -0
  29. data/spec/inputs/country_input_spec.rb +80 -0
  30. data/spec/inputs/date_input_spec.rb +45 -0
  31. data/spec/inputs/datetime_input_spec.rb +155 -0
  32. data/spec/inputs/file_input_spec.rb +33 -0
  33. data/spec/inputs/hidden_input_spec.rb +52 -0
  34. data/spec/inputs/numeric_input_spec.rb +44 -0
  35. data/spec/inputs/password_input_spec.rb +46 -0
  36. data/spec/inputs/radio_input_spec.rb +149 -0
  37. data/spec/inputs/select_input_spec.rb +459 -0
  38. data/spec/inputs/string_input_spec.rb +47 -0
  39. data/spec/inputs/text_input_spec.rb +33 -0
  40. data/spec/inputs/time_input_spec.rb +44 -0
  41. data/spec/inputs/time_zone_input_spec.rb +102 -0
  42. data/spec/inputs_spec.rb +395 -0
  43. data/spec/label_spec.rb +48 -0
  44. data/spec/nested_forms_spec.rb +50 -0
  45. data/spec/semantic_fields_for_spec.rb +44 -0
  46. data/spec/spec.opts +2 -0
  47. data/spec/spec_helper.rb +212 -0
  48. metadata +121 -16
  49. data/lib/justin_french/formtastic.rb +0 -10
  50. data/spec/formtastic_spec.rb +0 -3072
  51. data/spec/test_helper.rb +0 -14
@@ -0,0 +1,32 @@
1
+ module Formtastic
2
+ module I18n
3
+
4
+ DEFAULT_SCOPE = [:formtastic].freeze
5
+ DEFAULT_VALUES = {
6
+ :required => 'required',
7
+ :yes => 'Yes',
8
+ :no => 'No',
9
+ :create => 'Create {{model}}',
10
+ :update => 'Update {{model}}'
11
+ }.freeze
12
+ SCOPES = [
13
+ '{{model}}.{{action}}.{{attribute}}',
14
+ '{{model}}.{{attribute}}',
15
+ '{{attribute}}'
16
+ ]
17
+
18
+ class << self
19
+
20
+ def translate(*args)
21
+ key = args.shift.to_sym
22
+ options = args.extract_options!
23
+ options.reverse_merge!(:default => DEFAULT_VALUES[key])
24
+ options[:scope] = [DEFAULT_SCOPE, options[:scope]].flatten.compact
25
+ ::I18n.translate(key, *(args << options))
26
+ end
27
+ alias :t :translate
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -1,7 +1,7 @@
1
1
  en:
2
2
  formtastic:
3
- yes: 'Yes'
4
- no: 'No'
3
+ :yes: 'Yes'
4
+ :no: 'No'
5
5
  create: 'Create'
6
6
  save: 'Save'
7
7
  submit: 'Submit'
@@ -1,3 +1,3 @@
1
+ # coding: utf-8
1
2
  require File.join(File.dirname(__FILE__), *%w[.. lib formtastic])
2
- require File.join(File.dirname(__FILE__), *%w[.. lib justin_french formtastic])
3
3
  ActionView::Base.send :include, Formtastic::SemanticFormHelper
@@ -0,0 +1,149 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe 'SemanticFormBuilder#buttons' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'with a block' do
14
+ describe 'when no options are provided' do
15
+ before do
16
+ semantic_form_for(@new_post) do |builder|
17
+ builder.buttons do
18
+ concat('hello')
19
+ end
20
+ end
21
+ end
22
+
23
+ it 'should render a fieldset inside the form, with a class of "inputs"' do
24
+ output_buffer.should have_tag("form fieldset.buttons")
25
+ end
26
+
27
+ it 'should render an ol inside the fieldset' do
28
+ output_buffer.should have_tag("form fieldset.buttons ol")
29
+ end
30
+
31
+ it 'should render the contents of the block inside the ol' do
32
+ output_buffer.should have_tag("form fieldset.buttons ol", /hello/)
33
+ end
34
+
35
+ it 'should not render a legend inside the fieldset' do
36
+ output_buffer.should_not have_tag("form fieldset.buttons legend")
37
+ end
38
+ end
39
+
40
+ describe 'when a :name option is provided' do
41
+ before do
42
+ @legend_text = "Advanced options"
43
+
44
+ semantic_form_for(@new_post) do |builder|
45
+ builder.buttons :name => @legend_text do
46
+ end
47
+ end
48
+ end
49
+ it 'should render a fieldset inside the form' do
50
+ output_buffer.should have_tag("form fieldset legend", /#{@legend_text}/)
51
+ end
52
+ end
53
+
54
+ describe 'when other options are provided' do
55
+ before do
56
+ @id_option = 'advanced'
57
+ @class_option = 'wide'
58
+
59
+ semantic_form_for(@new_post) do |builder|
60
+ builder.buttons :id => @id_option, :class => @class_option do
61
+ end
62
+ end
63
+ end
64
+ it 'should pass the options into the fieldset tag as attributes' do
65
+ output_buffer.should have_tag("form fieldset##{@id_option}")
66
+ output_buffer.should have_tag("form fieldset.#{@class_option}")
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ describe 'without a block' do
73
+
74
+ describe 'with no args (default buttons)' do
75
+
76
+ before do
77
+ semantic_form_for(@new_post) do |builder|
78
+ concat(builder.buttons)
79
+ end
80
+ end
81
+
82
+ it 'should render a form' do
83
+ output_buffer.should have_tag('form')
84
+ end
85
+
86
+ it 'should render a buttons fieldset inside the form' do
87
+ output_buffer.should have_tag('form fieldset.buttons')
88
+ end
89
+
90
+ it 'should not render a legend in the fieldset' do
91
+ output_buffer.should_not have_tag('form fieldset.buttons legend')
92
+ end
93
+
94
+ it 'should render an ol in the fieldset' do
95
+ output_buffer.should have_tag('form fieldset.buttons ol')
96
+ end
97
+
98
+ it 'should render a list item in the ol for each default button' do
99
+ output_buffer.should have_tag('form fieldset.buttons ol li', :count => 1)
100
+ end
101
+
102
+ it 'should render a commit list item for the commit button' do
103
+ output_buffer.should have_tag('form fieldset.buttons ol li.commit')
104
+ end
105
+
106
+ end
107
+
108
+ describe 'with button names as args' do
109
+
110
+ before do
111
+ semantic_form_for(@new_post) do |builder|
112
+ concat(builder.buttons(:commit))
113
+ end
114
+ end
115
+
116
+ it 'should render a form with a fieldset containing a list item for each button arg' do
117
+ output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
118
+ output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit')
119
+ end
120
+
121
+ end
122
+
123
+ describe 'with button names as args and an options hash' do
124
+
125
+ before do
126
+ semantic_form_for(@new_post) do |builder|
127
+ concat(builder.buttons(:commit, :name => "Now click a button", :id => "my-id"))
128
+ end
129
+ end
130
+
131
+ it 'should render a form with a fieldset containing a list item for each button arg' do
132
+ output_buffer.should have_tag('form > fieldset.buttons > ol > li', :count => 1)
133
+ output_buffer.should have_tag('form > fieldset.buttons > ol > li.commit', :count => 1)
134
+ end
135
+
136
+ it 'should pass the options down to the fieldset' do
137
+ output_buffer.should have_tag('form > fieldset#my-id.buttons')
138
+ end
139
+
140
+ it 'should use the special :name option as a text for the legend tag' do
141
+ output_buffer.should have_tag('form > fieldset#my-id.buttons > legend', /Now click a button/)
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
148
+ end
149
+
@@ -0,0 +1,344 @@
1
+ # coding: utf-8
2
+ require File.dirname(__FILE__) + '/spec_helper'
3
+
4
+ describe 'SemanticFormBuilder#commit_button' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe 'when used on any record' do
14
+
15
+ before do
16
+ @new_post.stub!(:new_record?).and_return(false)
17
+ semantic_form_for(@new_post) do |builder|
18
+ concat(builder.commit_button)
19
+ end
20
+ end
21
+
22
+ it 'should render a commit li' do
23
+ output_buffer.should have_tag('li.commit')
24
+ end
25
+
26
+ it 'should render an input with a type attribute of "submit"' do
27
+ output_buffer.should have_tag('li.commit input[@type="submit"]')
28
+ end
29
+
30
+ it 'should render an input with a name attribute of "commit"' do
31
+ output_buffer.should have_tag('li.commit input[@name="commit"]')
32
+ end
33
+
34
+ it 'should pass options given in :button_html to the button' do
35
+ @new_post.stub!(:new_record?).and_return(false)
36
+ semantic_form_for(@new_post) do |builder|
37
+ concat(builder.commit_button('text', :button_html => {:class => 'my_class', :id => 'my_id'}))
38
+ end
39
+
40
+ output_buffer.should have_tag('li.commit input#my_id')
41
+ output_buffer.should have_tag('li.commit input.my_class')
42
+ end
43
+
44
+ end
45
+
46
+ describe "its accesskey" do
47
+
48
+ it 'should allow nil default' do
49
+ with_config :default_commit_button_accesskey, nil do
50
+ output_buffer.should_not have_tag('li.commit input[@accesskey]')
51
+ end
52
+ end
53
+
54
+ it 'should use the default if set' do
55
+ with_config :default_commit_button_accesskey, 's' do
56
+ @new_post.stub!(:new_record?).and_return(false)
57
+ semantic_form_for(@new_post) do |builder|
58
+ concat(builder.commit_button('text', :button_html => {}))
59
+ end
60
+ output_buffer.should have_tag('li.commit input[@accesskey="s"]')
61
+ end
62
+ end
63
+
64
+ it 'should use the value set in options over the default' do
65
+ with_config :default_commit_button_accesskey, 's' do
66
+ @new_post.stub!(:new_record?).and_return(false)
67
+ semantic_form_for(@new_post) do |builder|
68
+ concat(builder.commit_button('text', :accesskey => 'o'))
69
+ end
70
+ output_buffer.should_not have_tag('li.commit input[@accesskey="s"]')
71
+ output_buffer.should have_tag('li.commit input[@accesskey="o"]')
72
+ end
73
+ end
74
+
75
+ it 'should use the value set in button_html over options' do
76
+ with_config :default_commit_button_accesskey, 's' do
77
+ @new_post.stub!(:new_record?).and_return(false)
78
+ semantic_form_for(@new_post) do |builder|
79
+ concat(builder.commit_button('text', :accesskey => 'o', :button_html => {:accesskey => 't'}))
80
+ end
81
+ output_buffer.should_not have_tag('li.commit input[@accesskey="s"]')
82
+ output_buffer.should_not have_tag('li.commit input[@accesskey="o"]')
83
+ output_buffer.should have_tag('li.commit input[@accesskey="t"]')
84
+ end
85
+ end
86
+
87
+ end
88
+
89
+ describe 'when the first option is a string and the second is a hash' do
90
+
91
+ before do
92
+ @new_post.stub!(:new_record?).and_return(false)
93
+ semantic_form_for(@new_post) do |builder|
94
+ concat(builder.commit_button("a string", :button_html => { :class => "pretty"}))
95
+ end
96
+ end
97
+
98
+ it "should render the string as the value of the button" do
99
+ output_buffer.should have_tag('li input[@value="a string"]')
100
+ end
101
+
102
+ it "should deal with the options hash" do
103
+ output_buffer.should have_tag('li input.pretty')
104
+ end
105
+
106
+ end
107
+
108
+ describe 'when the first option is a hash' do
109
+
110
+ before do
111
+ @new_post.stub!(:new_record?).and_return(false)
112
+ semantic_form_for(@new_post) do |builder|
113
+ concat(builder.commit_button(:button_html => { :class => "pretty"}))
114
+ end
115
+ end
116
+
117
+ it "should deal with the options hash" do
118
+ output_buffer.should have_tag('li input.pretty')
119
+ end
120
+
121
+ end
122
+
123
+ describe 'label' do
124
+ before do
125
+ ::Post.stub!(:human_name).and_return('Post')
126
+ end
127
+
128
+ # No object
129
+ describe 'when used without object' do
130
+ describe 'when explicit label is provided' do
131
+ it 'should render an input with the explicitly specified label' do
132
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
133
+ concat(builder.commit_button("Click!"))
134
+ end
135
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="submit"]')
136
+ end
137
+ end
138
+
139
+ describe 'when no explicit label is provided' do
140
+ describe 'when no I18n-localized label is provided' do
141
+ before do
142
+ ::I18n.backend.store_translations :en, :formtastic => {:submit => 'Submit {{model}}'}
143
+ end
144
+
145
+ after do
146
+ ::I18n.backend.store_translations :en, :formtastic => {:submit => nil}
147
+ end
148
+
149
+ it 'should render an input with default I18n-localized label (fallback)' do
150
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
151
+ concat(builder.commit_button)
152
+ end
153
+ output_buffer.should have_tag('li.commit input[@value="Submit Post"][@class~="submit"]')
154
+ end
155
+ end
156
+
157
+ describe 'when I18n-localized label is provided' do
158
+ before do
159
+ ::I18n.backend.store_translations :en,
160
+ :formtastic => {
161
+ :actions => {
162
+ :submit => 'Custom Submit',
163
+ :post => {
164
+ :submit => 'Custom Submit {{model}}'
165
+ }
166
+ }
167
+ }
168
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
169
+ end
170
+
171
+ it 'should render an input with localized label (I18n)' do
172
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
173
+ concat(builder.commit_button)
174
+ end
175
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit Post"][@class~="submit"]})
176
+ end
177
+
178
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
179
+ ::I18n.backend.store_translations :en,
180
+ :formtastic => {
181
+ :actions => {
182
+ :post => {
183
+ :submit => nil
184
+ }
185
+ }
186
+ }
187
+ semantic_form_for(:post, :url => 'http://example.com') do |builder|
188
+ concat(builder.commit_button)
189
+ end
190
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Submit"][@class~="submit"]})
191
+ end
192
+
193
+ end
194
+ end
195
+ end
196
+
197
+ # New record
198
+ describe 'when used on a new record' do
199
+ before do
200
+ @new_post.stub!(:new_record?).and_return(true)
201
+ end
202
+
203
+ describe 'when explicit label is provided' do
204
+ it 'should render an input with the explicitly specified label' do
205
+ semantic_form_for(@new_post) do |builder|
206
+ concat(builder.commit_button("Click!"))
207
+ end
208
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="create"]')
209
+ end
210
+ end
211
+
212
+ describe 'when no explicit label is provided' do
213
+ describe 'when no I18n-localized label is provided' do
214
+ before do
215
+ ::I18n.backend.store_translations :en, :formtastic => {:create => 'Create {{model}}'}
216
+ end
217
+
218
+ after do
219
+ ::I18n.backend.store_translations :en, :formtastic => {:create => nil}
220
+ end
221
+
222
+ it 'should render an input with default I18n-localized label (fallback)' do
223
+ semantic_form_for(@new_post) do |builder|
224
+ concat(builder.commit_button)
225
+ end
226
+ output_buffer.should have_tag('li.commit input[@value="Create Post"][@class~="create"]')
227
+ end
228
+ end
229
+
230
+ describe 'when I18n-localized label is provided' do
231
+ before do
232
+ ::I18n.backend.store_translations :en,
233
+ :formtastic => {
234
+ :actions => {
235
+ :create => 'Custom Create',
236
+ :post => {
237
+ :create => 'Custom Create {{model}}'
238
+ }
239
+ }
240
+ }
241
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
242
+ end
243
+
244
+ it 'should render an input with localized label (I18n)' do
245
+ semantic_form_for(@new_post) do |builder|
246
+ concat(builder.commit_button)
247
+ end
248
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create Post"][@class~="create"]})
249
+ end
250
+
251
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
252
+ ::I18n.backend.store_translations :en,
253
+ :formtastic => {
254
+ :actions => {
255
+ :post => {
256
+ :create => nil
257
+ }
258
+ }
259
+ }
260
+ semantic_form_for(@new_post) do |builder|
261
+ concat(builder.commit_button)
262
+ end
263
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Create"][@class~="create"]})
264
+ end
265
+
266
+ end
267
+ end
268
+ end
269
+
270
+ # Existing record
271
+ describe 'when used on an existing record' do
272
+ before do
273
+ @new_post.stub!(:new_record?).and_return(false)
274
+ end
275
+
276
+ describe 'when explicit label is provided' do
277
+ it 'should render an input with the explicitly specified label' do
278
+ semantic_form_for(@new_post) do |builder|
279
+ concat(builder.commit_button("Click!"))
280
+ end
281
+ output_buffer.should have_tag('li.commit input[@value="Click!"][@class~="update"]')
282
+ end
283
+ end
284
+
285
+ describe 'when no explicit label is provided' do
286
+ describe 'when no I18n-localized label is provided' do
287
+ before do
288
+ ::I18n.backend.store_translations :en, :formtastic => {:update => 'Save {{model}}'}
289
+ end
290
+
291
+ after do
292
+ ::I18n.backend.store_translations :en, :formtastic => {:update => nil}
293
+ end
294
+
295
+ it 'should render an input with default I18n-localized label (fallback)' do
296
+ semantic_form_for(@new_post) do |builder|
297
+ concat(builder.commit_button)
298
+ end
299
+ output_buffer.should have_tag('li.commit input[@value="Save Post"][@class~="update"]')
300
+ end
301
+ end
302
+
303
+ describe 'when I18n-localized label is provided' do
304
+ before do
305
+ ::I18n.backend.store_translations :en,
306
+ :formtastic => {
307
+ :actions => {
308
+ :update => 'Custom Save',
309
+ :post => {
310
+ :update => 'Custom Save {{model}}'
311
+ }
312
+ }
313
+ }
314
+ ::Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
315
+ end
316
+
317
+ it 'should render an input with localized label (I18n)' do
318
+ semantic_form_for(@new_post) do |builder|
319
+ concat(builder.commit_button)
320
+ end
321
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save Post"][@class~="update"]})
322
+ end
323
+
324
+ it 'should render an input with anoptional localized label (I18n) - if first is not set' do
325
+ ::I18n.backend.store_translations :en,
326
+ :formtastic => {
327
+ :actions => {
328
+ :post => {
329
+ :update => nil
330
+ }
331
+ }
332
+ }
333
+ semantic_form_for(@new_post) do |builder|
334
+ concat(builder.commit_button)
335
+ end
336
+ output_buffer.should have_tag(%Q{li.commit input[@value="Custom Save"][@class~="update"]})
337
+ end
338
+
339
+ end
340
+ end
341
+ end
342
+ end
343
+
344
+ end