sensis-formtastic-rails3 1.d4e5326

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.textile +584 -0
  3. data/Rakefile +127 -0
  4. data/generators/form/USAGE +16 -0
  5. data/generators/form/form_generator.rb +120 -0
  6. data/generators/form/templates/view__form.html.erb +5 -0
  7. data/generators/form/templates/view__form.html.haml +4 -0
  8. data/generators/formtastic/formtastic_generator.rb +24 -0
  9. data/generators/formtastic/templates/formtastic.css +131 -0
  10. data/generators/formtastic/templates/formtastic.rb +54 -0
  11. data/generators/formtastic/templates/formtastic_changes.css +14 -0
  12. data/generators/formtastic_stylesheets/formtastic_stylesheets_generator.rb +16 -0
  13. data/init.rb +5 -0
  14. data/lib/formtastic.rb +1870 -0
  15. data/lib/formtastic/i18n.rb +35 -0
  16. data/lib/formtastic/layout_helper.rb +10 -0
  17. data/lib/formtastic/railtie.rb +12 -0
  18. data/lib/formtastic/util.rb +36 -0
  19. data/lib/generators/formtastic/form/form_generator.rb +86 -0
  20. data/lib/generators/formtastic/install/install_generator.rb +24 -0
  21. data/lib/locale/en.yml +8 -0
  22. data/rails/init.rb +2 -0
  23. data/spec/buttons_spec.rb +166 -0
  24. data/spec/commit_button_spec.rb +401 -0
  25. data/spec/custom_builder_spec.rb +98 -0
  26. data/spec/defaults_spec.rb +20 -0
  27. data/spec/error_proc_spec.rb +27 -0
  28. data/spec/errors_spec.rb +105 -0
  29. data/spec/form_helper_spec.rb +142 -0
  30. data/spec/helpers/layout_helper_spec.rb +21 -0
  31. data/spec/i18n_spec.rb +152 -0
  32. data/spec/include_blank_spec.rb +74 -0
  33. data/spec/input_spec.rb +786 -0
  34. data/spec/inputs/boolean_input_spec.rb +104 -0
  35. data/spec/inputs/check_boxes_input_spec.rb +426 -0
  36. data/spec/inputs/country_input_spec.rb +118 -0
  37. data/spec/inputs/date_input_spec.rb +168 -0
  38. data/spec/inputs/datetime_input_spec.rb +310 -0
  39. data/spec/inputs/file_input_spec.rb +34 -0
  40. data/spec/inputs/hidden_input_spec.rb +78 -0
  41. data/spec/inputs/numeric_input_spec.rb +44 -0
  42. data/spec/inputs/password_input_spec.rb +46 -0
  43. data/spec/inputs/radio_input_spec.rb +243 -0
  44. data/spec/inputs/select_input_spec.rb +546 -0
  45. data/spec/inputs/string_input_spec.rb +64 -0
  46. data/spec/inputs/text_input_spec.rb +34 -0
  47. data/spec/inputs/time_input_spec.rb +206 -0
  48. data/spec/inputs/time_zone_input_spec.rb +110 -0
  49. data/spec/inputs_spec.rb +476 -0
  50. data/spec/label_spec.rb +89 -0
  51. data/spec/semantic_errors_spec.rb +98 -0
  52. data/spec/semantic_fields_for_spec.rb +45 -0
  53. data/spec/spec.opts +2 -0
  54. data/spec/spec_helper.rb +289 -0
  55. data/spec/support/custom_macros.rb +494 -0
  56. data/spec/support/output_buffer.rb +4 -0
  57. data/spec/support/test_environment.rb +45 -0
  58. metadata +234 -0
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'file input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:body, :as => :file))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class("file")
18
+ it_should_have_input_wrapper_with_id("post_body_input")
19
+ it_should_have_label_with_text(/Body/)
20
+ it_should_have_label_for("post_body")
21
+ it_should_have_input_with_id("post_body")
22
+ it_should_have_input_with_name("post[body]")
23
+ it_should_apply_error_logic_for_input_type(:file)
24
+
25
+ it 'should use input_html to style inputs' do
26
+ form = semantic_form_for(@new_post) do |builder|
27
+ concat(builder.input(:title, :as => :file, :input_html => { :class => 'myclass' }))
28
+ end
29
+ output_buffer.concat(form) if Formtastic::Util.rails3?
30
+ output_buffer.should have_tag("form li input.myclass")
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,78 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'hidden input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:secret, :as => :hidden))
14
+ concat(builder.input(:author_id, :as => :hidden, :value => 99))
15
+ concat(builder.input(:published, :as => :hidden, :input_html => {:value => true}))
16
+ concat(builder.input(:reviewer, :as => :hidden, :input_html => {:class => 'new_post_reviewer', :id => 'new_post_reviewer'}))
17
+ concat(builder.input(:author, :as => :hidden, :value => 'direct_value', :input_html => {:value => "formtastic_value"}))
18
+ end
19
+ end
20
+
21
+ it_should_have_input_wrapper_with_class("hidden")
22
+ it_should_have_input_wrapper_with_id("post_secret_input")
23
+ it_should_not_have_a_label
24
+
25
+ it "should generate a input field" do
26
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
27
+ output_buffer.should have_tag("form li input#post_secret")
28
+ output_buffer.should have_tag("form li input#post_secret[@type=\"hidden\"]")
29
+ output_buffer.should have_tag("form li input#post_secret[@name=\"post[secret]\"]")
30
+ end
31
+
32
+ it "should pass any explicitly specified value - using :value" do
33
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
34
+ output_buffer.should have_tag("form li input#post_author_id[@type=\"hidden\"][@value=\"99\"]")
35
+ end
36
+
37
+ # Handle Formtastic :input_html options for consistency.
38
+ it "should pass any explicitly specified value - using :input_html options" do
39
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
40
+ output_buffer.should have_tag("form li input#post_published[@type=\"hidden\"][@value=\"true\"]")
41
+ end
42
+
43
+ it "should pass any option specified using :input_html" do
44
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
45
+ output_buffer.should have_tag("form li input#new_post_reviewer[@type=\"hidden\"][@class=\"new_post_reviewer\"]")
46
+ end
47
+
48
+ it "should prefer :input_html over directly supplied options" do
49
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
50
+ output_buffer.should have_tag("form li input#post_author[@type=\"hidden\"][@value=\"formtastic_value\"]")
51
+ end
52
+
53
+ it "should not render inline errors" do
54
+ @errors = mock('errors')
55
+ @errors.stub!(:[]).with(:secret).and_return(["foo", "bah"])
56
+ @new_post.stub!(:errors).and_return(@errors)
57
+
58
+ form = semantic_form_for(@new_post) do |builder|
59
+ concat(builder.input(:secret, :as => :hidden))
60
+ end
61
+
62
+ output_buffer.concat(form) if Formtastic::Util.rails3?
63
+ output_buffer.should_not have_tag("form li p.inline-errors")
64
+ output_buffer.should_not have_tag("form li ul.errors")
65
+ end
66
+
67
+ it "should not render inline hints" do
68
+ form = semantic_form_for(@new_post) do |builder|
69
+ concat(builder.input(:secret, :as => :hidden, :hint => "all your base are belong to use"))
70
+ end
71
+
72
+ output_buffer.concat(form) if Formtastic::Util.rails3?
73
+ output_buffer.should_not have_tag("form li p.inline-hints")
74
+ output_buffer.should_not have_tag("form li ul.hints")
75
+ end
76
+
77
+ end
78
+
@@ -0,0 +1,44 @@
1
+ # coding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'numeric input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:title, :as => :numeric))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class(:numeric)
18
+ it_should_have_input_wrapper_with_id("post_title_input")
19
+ it_should_have_label_with_text(/Title/)
20
+ it_should_have_label_for("post_title")
21
+ it_should_have_input_with_id("post_title")
22
+ it_should_have_input_with_type(:text)
23
+ it_should_have_input_with_name("post[title]")
24
+ it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
25
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
26
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
27
+ it_should_apply_error_logic_for_input_type(:numeric)
28
+
29
+ describe "when no object is provided" do
30
+ before do
31
+ @form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
32
+ concat(builder.input(:title, :as => :numeric))
33
+ end
34
+ end
35
+
36
+ it_should_have_label_with_text(/Title/)
37
+ it_should_have_label_for("project_title")
38
+ it_should_have_input_with_id("project_title")
39
+ it_should_have_input_with_type(:text)
40
+ it_should_have_input_with_name("project[title]")
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,46 @@
1
+ # coding: 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
+
12
+ @form = semantic_form_for(@new_post) do |builder|
13
+ concat(builder.input(:title, :as => :password))
14
+ end
15
+ end
16
+
17
+ it_should_have_input_wrapper_with_class(:password)
18
+ it_should_have_input_wrapper_with_id("post_title_input")
19
+ it_should_have_label_with_text(/Title/)
20
+ it_should_have_label_for("post_title")
21
+ it_should_have_input_with_id("post_title")
22
+ it_should_have_input_with_type(:password)
23
+ it_should_have_input_with_name("post[title]")
24
+ it_should_have_maxlength_matching_column_limit
25
+ it_should_use_default_text_field_size_for_columns_longer_than_default_text_field_size(:string)
26
+ it_should_use_column_size_for_columns_shorter_than_default_text_field_size(:string)
27
+ it_should_use_default_text_field_size_when_method_has_no_database_column(:string)
28
+ it_should_apply_custom_input_attributes_when_input_html_provided(:string)
29
+ it_should_apply_custom_for_to_label_when_input_html_id_provided(:string)
30
+ it_should_apply_error_logic_for_input_type(:password)
31
+
32
+ describe "when no object is provided" do
33
+ before do
34
+ @form = semantic_form_for(:project, :url => 'http://test.host/') do |builder|
35
+ concat(builder.input(:title, :as => :password))
36
+ end
37
+ end
38
+
39
+ it_should_have_label_with_text(/Title/)
40
+ it_should_have_label_for("project_title")
41
+ it_should_have_input_with_id("project_title")
42
+ it_should_have_input_with_type(:password)
43
+ it_should_have_input_with_name("project[title]")
44
+ end
45
+
46
+ end
@@ -0,0 +1,243 @@
1
+ # coding: 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
+ end
12
+
13
+ describe 'for belongs_to association' do
14
+ before do
15
+ @form = semantic_form_for(@new_post) do |builder|
16
+ concat(builder.input(:author, :as => :radio, :value_as_class => true))
17
+ end
18
+ end
19
+
20
+ it_should_have_input_wrapper_with_class("radio")
21
+ it_should_have_input_wrapper_with_id("post_author_input")
22
+ it_should_have_a_nested_fieldset
23
+ it_should_apply_error_logic_for_input_type(:radio)
24
+ it_should_use_the_collection_when_provided(:radio, 'input')
25
+
26
+ it 'should generate a legend containing a label with text for the input' do
27
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
28
+ output_buffer.should have_tag('form li fieldset legend.label label')
29
+ output_buffer.should have_tag('form li fieldset legend.label label', /Author/)
30
+ end
31
+
32
+ it 'should not link the label within the legend to any input' do
33
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
34
+ output_buffer.should_not have_tag('form li fieldset legend label[@for]')
35
+ end
36
+
37
+ it 'should generate an ordered list with a list item for each choice' do
38
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
39
+ output_buffer.should have_tag('form li fieldset ol')
40
+ output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
41
+ end
42
+
43
+ it 'should have one option with a "checked" attribute' do
44
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
45
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
46
+ end
47
+
48
+ describe "each choice" do
49
+
50
+ it 'should contain a label for the radio input with a nested input and label text' do
51
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
52
+ ::Author.find(:all).each do |author|
53
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
54
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_id_#{author.id}']")
55
+ end
56
+ end
57
+
58
+ it 'should use values as li.class when value_as_class is true' do
59
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
60
+ ::Author.find(:all).each do |author|
61
+ output_buffer.should have_tag("form li fieldset ol li.author_#{author.id} label")
62
+ end
63
+ end
64
+
65
+ it "should have a radio input" do
66
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
67
+ ::Author.find(:all).each do |author|
68
+ output_buffer.should have_tag("form li fieldset ol li label input#post_author_id_#{author.id}")
69
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
70
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
71
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='post[author_id]']")
72
+ end
73
+ end
74
+
75
+ it "should mark input as checked if it's the the existing choice" do
76
+ @new_post.author_id.should == @bob.id
77
+ @new_post.author.id.should == @bob.id
78
+ @new_post.author.should == @bob
79
+
80
+ form = semantic_form_for(@new_post) do |builder|
81
+ concat(builder.input(:author, :as => :radio))
82
+ end
83
+
84
+ output_buffer.concat(form) if Formtastic::Util.rails3?
85
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
86
+ end
87
+
88
+ it "should not contain invalid HTML attributes" do
89
+
90
+ form = semantic_form_for(@new_post) do |builder|
91
+ concat(builder.input(:author, :as => :radio))
92
+ end
93
+
94
+ output_buffer.concat(form) if Formtastic::Util.rails3?
95
+ output_buffer.should_not have_tag("form li fieldset ol li input[@find_options]")
96
+ end
97
+
98
+ end
99
+
100
+ describe 'and no object is given' do
101
+ before(:each) do
102
+ output_buffer.replace ''
103
+ @form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
104
+ concat(builder.input(:author_id, :as => :radio, :collection => ::Author.find(:all)))
105
+ end
106
+ end
107
+
108
+ it 'should generate a fieldset with legend' do
109
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
110
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
111
+ end
112
+
113
+ it 'should generate an li tag for each item in the collection' do
114
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
115
+ output_buffer.should have_tag('form li fieldset ol li', :count => ::Author.find(:all).size)
116
+ end
117
+
118
+ it 'should generate labels for each item' do
119
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
120
+ ::Author.find(:all).each do |author|
121
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
122
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
123
+ end
124
+ end
125
+
126
+ it 'should html escape the label string' do
127
+ output_buffer.replace ''
128
+ form = semantic_form_for(:project, :url => 'http://test.host') do |builder|
129
+ concat(builder.input(:author_id, :as => :radio, :collection => [["<b>Item 1</b>", 1], ["<b>Item 2</b>", 2]]))
130
+ end
131
+ output_buffer.concat(form) if Formtastic::Util.rails3?
132
+ output_buffer.should have_tag('form li fieldset ol li label') do |label|
133
+ label.body.should match /&lt;b&gt;Item [12]&lt;\/b&gt;$/
134
+ end
135
+ end
136
+
137
+ it 'should generate inputs for each item' do
138
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
139
+ ::Author.find(:all).each do |author|
140
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
141
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio']")
142
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
143
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id]']")
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ describe 'when :selected is set' do
150
+ before do
151
+ @output_buffer = ''
152
+ end
153
+
154
+ describe "no selected items" do
155
+ before do
156
+ @new_post.stub!(:author_ids).and_return(nil)
157
+
158
+ with_deprecation_silenced do
159
+ @form = semantic_form_for(@new_post) do |builder|
160
+ concat(builder.input(:authors, :as => :radio, :selected => nil))
161
+ end
162
+ end
163
+ end
164
+
165
+ it 'should not have any selected item(s)' do
166
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
167
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@checked='checked']")
168
+ end
169
+ end
170
+
171
+ describe "single selected item" do
172
+ before do
173
+ @new_post.stub!(:author_ids).and_return(nil)
174
+ with_deprecation_silenced do
175
+ @form = semantic_form_for(@new_post) do |builder|
176
+ concat(builder.input(:authors, :as => :radio, :selected => @fred.id))
177
+ end
178
+ end
179
+ end
180
+
181
+ it "should have one item selected; the specified one" do
182
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
183
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked']", :count => 1)
184
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
185
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='radio'][@checked='checked'][@value='#{@fred.id}']")
186
+ end
187
+ end
188
+
189
+ end
190
+
191
+ describe "with i18n of the legend label" do
192
+
193
+ before do
194
+ ::I18n.backend.store_translations :en, :formtastic => { :labels => { :post => { :authors => "Translated!" }}}
195
+
196
+ Formtastic::SemanticFormBuilder.i18n_lookups_by_default = true
197
+ @new_post.stub!(:author_ids).and_return(nil)
198
+ @form = semantic_form_for(@new_post) do |builder|
199
+ concat(builder.input(:authors, :as => :radio))
200
+ end
201
+ end
202
+
203
+ after do
204
+ ::I18n.backend.reload!
205
+ Formtastic::SemanticFormBuilder.i18n_lookups_by_default = false
206
+ end
207
+
208
+ it "should do foo" do
209
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
210
+ output_buffer.should have_tag("legend.label label", /Translated/)
211
+ end
212
+
213
+ end
214
+
215
+ describe "when :label option is set" do
216
+ before do
217
+ @new_post.stub!(:author_ids).and_return(nil)
218
+ @form = semantic_form_for(@new_post) do |builder|
219
+ concat(builder.input(:authors, :as => :radio, :label => 'The authors'))
220
+ end
221
+ end
222
+
223
+ it "should output the correct label title" do
224
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
225
+ output_buffer.should have_tag("legend.label label", /The authors/)
226
+ end
227
+ end
228
+
229
+ describe "when :label option is false" do
230
+ before do
231
+ @output_buffer = ''
232
+ @new_post.stub!(:author_ids).and_return(nil)
233
+ @form = semantic_form_for(@new_post) do |builder|
234
+ concat(builder.input(:authors, :as => :radio, :label => false))
235
+ end
236
+ end
237
+
238
+ it "should not output the legend" do
239
+ output_buffer.concat(@form) if Formtastic::Util.rails3?
240
+ output_buffer.should_not have_tag("legend.label")
241
+ end
242
+ end
243
+ end