formtastic 1.2.5 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. data/.gitignore +13 -0
  2. data/.rspec +2 -0
  3. data/.yardopts +1 -0
  4. data/CHANGELOG +279 -0
  5. data/Gemfile +3 -0
  6. data/README.textile +155 -172
  7. data/RELEASE_PROCESS +7 -0
  8. data/Rakefile +52 -0
  9. data/app/assets/stylesheets/formtastic.css +275 -0
  10. data/app/assets/stylesheets/formtastic_ie6.css +27 -0
  11. data/app/assets/stylesheets/formtastic_ie7.css +17 -0
  12. data/formtastic.gemspec +51 -0
  13. data/lib/formtastic.rb +21 -1960
  14. data/lib/formtastic/engine.rb +7 -0
  15. data/lib/formtastic/form_builder.rb +83 -0
  16. data/lib/formtastic/helpers.rb +16 -0
  17. data/lib/formtastic/helpers/buttons_helper.rb +277 -0
  18. data/lib/formtastic/helpers/errors_helper.rb +113 -0
  19. data/lib/formtastic/helpers/fieldset_wrapper.rb +75 -0
  20. data/lib/formtastic/helpers/file_column_detection.rb +16 -0
  21. data/lib/formtastic/helpers/form_helper.rb +198 -0
  22. data/lib/formtastic/helpers/input_helper.rb +366 -0
  23. data/lib/formtastic/helpers/inputs_helper.rb +392 -0
  24. data/lib/formtastic/helpers/reflection.rb +33 -0
  25. data/lib/formtastic/helpers/semantic_form_helper.rb +11 -0
  26. data/lib/formtastic/html_attributes.rb +21 -0
  27. data/lib/formtastic/i18n.rb +1 -0
  28. data/lib/formtastic/inputs.rb +31 -0
  29. data/lib/formtastic/inputs/base.rb +61 -0
  30. data/lib/formtastic/inputs/base/associations.rb +31 -0
  31. data/lib/formtastic/inputs/base/choices.rb +103 -0
  32. data/lib/formtastic/inputs/base/collections.rb +94 -0
  33. data/lib/formtastic/inputs/base/database.rb +17 -0
  34. data/lib/formtastic/inputs/base/errors.rb +58 -0
  35. data/lib/formtastic/inputs/base/fileish.rb +23 -0
  36. data/lib/formtastic/inputs/base/grouped_collections.rb +77 -0
  37. data/lib/formtastic/inputs/base/hints.rb +31 -0
  38. data/lib/formtastic/inputs/base/html.rb +52 -0
  39. data/lib/formtastic/inputs/base/labelling.rb +55 -0
  40. data/lib/formtastic/inputs/base/naming.rb +42 -0
  41. data/lib/formtastic/inputs/base/options.rb +18 -0
  42. data/lib/formtastic/inputs/base/stringish.rb +35 -0
  43. data/lib/formtastic/inputs/base/timeish.rb +128 -0
  44. data/lib/formtastic/inputs/base/validations.rb +166 -0
  45. data/lib/formtastic/inputs/base/wrapping.rb +40 -0
  46. data/lib/formtastic/inputs/boolean_input.rb +96 -0
  47. data/lib/formtastic/inputs/check_boxes_input.rb +179 -0
  48. data/lib/formtastic/inputs/country_input.rb +66 -0
  49. data/lib/formtastic/inputs/date_input.rb +14 -0
  50. data/lib/formtastic/inputs/datetime_input.rb +9 -0
  51. data/lib/formtastic/inputs/email_input.rb +40 -0
  52. data/lib/formtastic/inputs/file_input.rb +42 -0
  53. data/lib/formtastic/inputs/hidden_input.rb +66 -0
  54. data/lib/formtastic/inputs/number_input.rb +118 -0
  55. data/lib/formtastic/inputs/numeric_input.rb +21 -0
  56. data/lib/formtastic/inputs/password_input.rb +40 -0
  57. data/lib/formtastic/inputs/phone_input.rb +41 -0
  58. data/lib/formtastic/inputs/radio_input.rb +157 -0
  59. data/lib/formtastic/inputs/range_input.rb +119 -0
  60. data/lib/formtastic/inputs/search_input.rb +40 -0
  61. data/lib/formtastic/inputs/select_input.rb +210 -0
  62. data/lib/formtastic/inputs/string_input.rb +34 -0
  63. data/lib/formtastic/inputs/text_input.rb +47 -0
  64. data/lib/formtastic/inputs/time_input.rb +14 -0
  65. data/lib/formtastic/inputs/time_zone_input.rb +48 -0
  66. data/lib/formtastic/inputs/url_input.rb +40 -0
  67. data/lib/formtastic/localized_string.rb +105 -0
  68. data/lib/formtastic/railtie.rb +5 -7
  69. data/lib/formtastic/semantic_form_builder.rb +11 -0
  70. data/lib/formtastic/util.rb +6 -19
  71. data/lib/formtastic/version.rb +3 -0
  72. data/lib/generators/formtastic/install/install_generator.rb +28 -6
  73. data/lib/generators/templates/_form.html.erb +10 -4
  74. data/lib/generators/templates/_form.html.haml +8 -4
  75. data/lib/generators/templates/formtastic.rb +25 -32
  76. data/lib/locale/en.yml +1 -0
  77. data/lib/tasks/verify_rcov.rb +44 -0
  78. data/sample/basic_inputs.html +182 -0
  79. data/sample/config.ru +69 -0
  80. data/sample/index.html +14 -0
  81. data/spec/builder/custom_builder_spec.rb +109 -0
  82. data/spec/builder/error_proc_spec.rb +27 -0
  83. data/spec/builder/errors_spec.rb +193 -0
  84. data/spec/builder/semantic_fields_for_spec.rb +88 -0
  85. data/spec/helpers/buttons_helper_spec.rb +150 -0
  86. data/spec/helpers/commit_button_helper_spec.rb +470 -0
  87. data/spec/helpers/form_helper_spec.rb +135 -0
  88. data/spec/helpers/input_helper_spec.rb +837 -0
  89. data/spec/helpers/inputs_helper_spec.rb +562 -0
  90. data/spec/helpers/semantic_errors_helper_spec.rb +112 -0
  91. data/spec/i18n_spec.rb +199 -0
  92. data/spec/inputs/boolean_input_spec.rb +184 -0
  93. data/spec/inputs/check_boxes_input_spec.rb +375 -0
  94. data/spec/inputs/country_input_spec.rb +133 -0
  95. data/spec/inputs/custom_input_spec.rb +52 -0
  96. data/spec/inputs/date_input_spec.rb +110 -0
  97. data/spec/inputs/datetime_input_spec.rb +115 -0
  98. data/spec/inputs/email_input_spec.rb +55 -0
  99. data/spec/inputs/file_input_spec.rb +59 -0
  100. data/spec/inputs/hidden_input_spec.rb +120 -0
  101. data/spec/inputs/include_blank_spec.rb +70 -0
  102. data/spec/inputs/label_spec.rb +104 -0
  103. data/spec/inputs/number_input_spec.rb +487 -0
  104. data/spec/inputs/numeric_input_spec.rb +41 -0
  105. data/spec/inputs/password_input_spec.rb +69 -0
  106. data/spec/inputs/phone_input_spec.rb +55 -0
  107. data/spec/inputs/placeholder_spec.rb +71 -0
  108. data/spec/inputs/radio_input_spec.rb +234 -0
  109. data/spec/inputs/range_input_spec.rb +477 -0
  110. data/spec/inputs/search_input_spec.rb +55 -0
  111. data/spec/inputs/select_input_spec.rb +545 -0
  112. data/spec/inputs/string_input_spec.rb +163 -0
  113. data/spec/inputs/text_input_spec.rb +158 -0
  114. data/spec/inputs/time_input_spec.rb +155 -0
  115. data/spec/inputs/time_zone_input_spec.rb +87 -0
  116. data/spec/inputs/url_input_spec.rb +55 -0
  117. data/spec/spec.opts +2 -0
  118. data/spec/spec_helper.rb +361 -0
  119. data/spec/support/custom_macros.rb +656 -0
  120. data/spec/support/deferred_garbage_collection.rb +21 -0
  121. data/spec/support/deprecation.rb +6 -0
  122. data/spec/support/test_environment.rb +30 -0
  123. metadata +306 -88
  124. data/generators/form/USAGE +0 -16
  125. data/generators/form/form_generator.rb +0 -111
  126. data/generators/formtastic/formtastic_generator.rb +0 -26
  127. data/init.rb +0 -5
  128. data/lib/formtastic/layout_helper.rb +0 -12
  129. data/lib/generators/formtastic/form/form_generator.rb +0 -84
  130. data/lib/generators/templates/formtastic.css +0 -145
  131. data/lib/generators/templates/formtastic_changes.css +0 -14
  132. data/lib/generators/templates/rails2/_form.html.erb +0 -5
  133. data/lib/generators/templates/rails2/_form.html.haml +0 -4
  134. data/rails/init.rb +0 -2
@@ -0,0 +1,375 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'check_boxes input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ describe 'for a has_many association' do
9
+ before do
10
+ @output_buffer = ''
11
+ mock_everything
12
+
13
+ concat(semantic_form_for(@fred) do |builder|
14
+ concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true, :required => true))
15
+ end)
16
+ end
17
+
18
+ it_should_have_input_wrapper_with_class("check_boxes")
19
+ it_should_have_input_wrapper_with_class(:input)
20
+ it_should_have_input_wrapper_with_id("author_posts_input")
21
+ it_should_have_a_nested_fieldset
22
+ it_should_have_a_nested_fieldset_with_class('choices')
23
+ it_should_have_a_nested_ordered_list_with_class('choices-group')
24
+ it_should_apply_error_logic_for_input_type(:check_boxes)
25
+ it_should_call_find_on_association_class_when_no_collection_is_provided(:check_boxes)
26
+ it_should_use_the_collection_when_provided(:check_boxes, 'input[@type="checkbox"]')
27
+
28
+ it 'should generate a legend containing a label with text for the input' do
29
+ output_buffer.should have_tag('form li fieldset legend.label label')
30
+ output_buffer.should have_tag('form li fieldset legend.label label', /Posts/)
31
+ end
32
+
33
+ it 'should not link the label within the legend to any input' do
34
+ output_buffer.should_not have_tag('form li fieldset legend label[@for^="author_post_ids_"]')
35
+ end
36
+
37
+ it 'should generate an ordered list with an li.choice for each choice' do
38
+ output_buffer.should have_tag('form li fieldset ol')
39
+ output_buffer.should have_tag('form li fieldset ol li.choice input[@type=checkbox]', :count => ::Post.all.size)
40
+ end
41
+
42
+ it 'should have one option with a "checked" attribute' do
43
+ output_buffer.should have_tag('form li input[@checked]', :count => 1)
44
+ end
45
+
46
+ it 'should not generate hidden inputs with default value blank' do
47
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@type='hidden'][@value='']")
48
+ end
49
+
50
+ it 'should not render hidden inputs inside the ol' do
51
+ output_buffer.should_not have_tag("form li fieldset ol li input[@type='hidden']")
52
+ end
53
+
54
+ it 'should render one hidden input for each choice outside the ol' do
55
+ output_buffer.should have_tag("form li fieldset > input[@type='hidden']", :count => 1)
56
+ end
57
+
58
+ describe "each choice" do
59
+
60
+ it 'should contain a label for the radio input with a nested input and label text' do
61
+ ::Post.all.each do |post|
62
+ output_buffer.should have_tag('form li fieldset ol li label', /#{post.to_label}/)
63
+ output_buffer.should have_tag("form li fieldset ol li label[@for='author_post_ids_#{post.id}']")
64
+ end
65
+ end
66
+
67
+ it 'should use values as li.class when value_as_class is true' do
68
+ ::Post.all.each do |post|
69
+ output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} label")
70
+ end
71
+ end
72
+
73
+ it "should add the required attribute to the input's html options" do
74
+ ::Post.all.each do |post|
75
+ output_buffer.should have_tag("form li fieldset ol li.post_#{post.id} input[@required]")
76
+ end
77
+ end
78
+
79
+ it 'should have a checkbox input but no hidden field for each post' do
80
+ ::Post.all.each do |post|
81
+ output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
82
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 1)
83
+ end
84
+ end
85
+
86
+ it 'should have a hidden field with an empty array value for the collection to allow clearing of all checkboxes' do
87
+ output_buffer.should have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value='']", :count => 1)
88
+ end
89
+
90
+ it 'the hidden field with an empty array value should be followed by the ol' do
91
+ output_buffer.should have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids][]'][@value=''] + ol", :count => 1)
92
+ end
93
+
94
+ it 'should not have a hidden field with an empty string value for the collection' do
95
+ output_buffer.should_not have_tag("form li fieldset > input[@type=hidden][@name='author[post_ids]'][@value='']", :count => 1)
96
+ end
97
+
98
+ it 'should have a checkbox and a hidden field for each post with :hidden_field => true' do
99
+ output_buffer.replace ''
100
+
101
+ concat(semantic_form_for(@fred) do |builder|
102
+ concat(builder.input(:posts, :as => :check_boxes, :hidden_fields => true, :value_as_class => true))
103
+ end)
104
+
105
+ ::Post.all.each do |post|
106
+ output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
107
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => 2)
108
+ end
109
+
110
+ end
111
+
112
+ it "should mark input as checked if it's the the existing choice" do
113
+ ::Post.all.include?(@fred.posts.first).should be_true
114
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
115
+ end
116
+ end
117
+
118
+ describe 'and no object is given' do
119
+ before(:each) do
120
+ output_buffer.replace ''
121
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
122
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => ::Author.all))
123
+ end)
124
+ end
125
+
126
+ it 'should generate a fieldset with legend' do
127
+ output_buffer.should have_tag('form li fieldset legend', /Author/)
128
+ end
129
+
130
+ it 'shold generate an li tag for each item in the collection' do
131
+ output_buffer.should have_tag('form li fieldset ol li input[@type=checkbox]', :count => ::Author.all.size)
132
+ end
133
+
134
+ it 'should generate labels for each item' do
135
+ ::Author.all.each do |author|
136
+ output_buffer.should have_tag('form li fieldset ol li label', /#{author.to_label}/)
137
+ output_buffer.should have_tag("form li fieldset ol li label[@for='project_author_id_#{author.id}']")
138
+ end
139
+ end
140
+
141
+ it 'should generate inputs for each item' do
142
+ ::Author.all.each do |author|
143
+ output_buffer.should have_tag("form li fieldset ol li label input#project_author_id_#{author.id}")
144
+ output_buffer.should have_tag("form li fieldset ol li label input[@type='checkbox']")
145
+ output_buffer.should have_tag("form li fieldset ol li label input[@value='#{author.id}']")
146
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='project[author_id][]']")
147
+ end
148
+ end
149
+
150
+ it 'should html escape the label string' do
151
+ concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
152
+ concat(builder.input(:author_id, :as => :check_boxes, :collection => [["<b>Item 1</b>", 1], ["<b>Item 2</b>", 2]]))
153
+ end)
154
+
155
+ output_buffer.should have_tag('form li fieldset ol li label') do |label|
156
+ label.body.should match /&lt;b&gt;Item [12]&lt;\/b&gt;$/
157
+ end
158
+ end
159
+ end
160
+
161
+ describe 'when :hidden_fields is set to false' do
162
+ before do
163
+ @output_buffer = ''
164
+ mock_everything
165
+
166
+ concat(semantic_form_for(@fred) do |builder|
167
+ concat(builder.input(:posts, :as => :check_boxes, :value_as_class => true, :hidden_fields => false))
168
+ end)
169
+ end
170
+
171
+ it 'should have a checkbox input for each post' do
172
+ ::Post.all.each do |post|
173
+ output_buffer.should have_tag("form li fieldset ol li label input#author_post_ids_#{post.id}")
174
+ output_buffer.should have_tag("form li fieldset ol li label input[@name='author[post_ids][]']", :count => ::Post.all.length)
175
+ end
176
+ end
177
+
178
+ it "should mark input as checked if it's the the existing choice" do
179
+ ::Post.all.include?(@fred.posts.first).should be_true
180
+ output_buffer.should have_tag("form li fieldset ol li label input[@checked='checked']")
181
+ end
182
+
183
+ it 'should not generate empty hidden inputs' do
184
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@type='hidden'][@value='']", :count => ::Post.all.length)
185
+ end
186
+ end
187
+
188
+ describe 'when :disabled is set' do
189
+ before do
190
+ @output_buffer = ''
191
+ end
192
+
193
+ describe "no disabled items" do
194
+ before do
195
+ @new_post.stub!(:author_ids).and_return(nil)
196
+
197
+ concat(semantic_form_for(@new_post) do |builder|
198
+ concat(builder.input(:authors, :as => :check_boxes, :disabled => nil))
199
+ end)
200
+ end
201
+
202
+ it 'should not have any disabled item(s)' do
203
+ output_buffer.should_not have_tag("form li fieldset ol li label input[@disabled='disabled']")
204
+ end
205
+ end
206
+
207
+ describe "single disabled item" do
208
+ before do
209
+ @new_post.stub!(:author_ids).and_return(nil)
210
+
211
+ concat(semantic_form_for(@new_post) do |builder|
212
+ concat(builder.input(:authors, :as => :check_boxes, :disabled => @fred.id))
213
+ end)
214
+ end
215
+
216
+ it "should have one item disabled; the specified one" do
217
+ output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 1)
218
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
219
+ output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
220
+ end
221
+ end
222
+
223
+ describe "multiple disabled items" do
224
+ before do
225
+ @new_post.stub!(:author_ids).and_return(nil)
226
+
227
+ concat(semantic_form_for(@new_post) do |builder|
228
+ concat(builder.input(:authors, :as => :check_boxes, :disabled => [@bob.id, @fred.id]))
229
+ end)
230
+ end
231
+
232
+ it "should have multiple items disabled; the specified ones" do
233
+ output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled']", :count => 2)
234
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@bob.id}']", /bob/i)
235
+ output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@bob.id}']")
236
+ output_buffer.should have_tag("form li fieldset ol li label[@for='post_author_ids_#{@fred.id}']", /fred/i)
237
+ output_buffer.should have_tag("form li fieldset ol li label input[@disabled='disabled'][@value='#{@fred.id}']")
238
+ end
239
+ end
240
+
241
+ end
242
+
243
+ describe "with i18n of the legend label" do
244
+
245
+ before do
246
+ ::I18n.backend.store_translations :en, :formtastic => { :labels => { :post => { :authors => "Translated!" }}}
247
+ with_config :i18n_lookups_by_default, true do
248
+ @new_post.stub!(:author_ids).and_return(nil)
249
+ concat(semantic_form_for(@new_post) do |builder|
250
+ concat(builder.input(:authors, :as => :check_boxes))
251
+ end)
252
+ end
253
+ end
254
+
255
+ after do
256
+ ::I18n.backend.reload!
257
+ end
258
+
259
+ it "should do foo" do
260
+ output_buffer.should have_tag("legend.label label", /Translated/)
261
+ end
262
+
263
+ end
264
+
265
+ describe "when :label option is set" do
266
+ before do
267
+ @new_post.stub!(:author_ids).and_return(nil)
268
+ concat(semantic_form_for(@new_post) do |builder|
269
+ concat(builder.input(:authors, :as => :check_boxes, :label => 'The authors'))
270
+ end)
271
+ end
272
+
273
+ it "should output the correct label title" do
274
+ output_buffer.should have_tag("legend.label label", /The authors/)
275
+ end
276
+ end
277
+
278
+ describe "when :label option is false" do
279
+ before do
280
+ @output_buffer = ''
281
+ @new_post.stub!(:author_ids).and_return(nil)
282
+ concat(semantic_form_for(@new_post) do |builder|
283
+ concat(builder.input(:authors, :as => :check_boxes, :label => false))
284
+ end)
285
+ end
286
+
287
+ it "should not output the legend" do
288
+ output_buffer.should_not have_tag("legend.label")
289
+ end
290
+
291
+ it "should not cause escaped HTML" do
292
+ output_buffer.should_not include("&gt;")
293
+ end
294
+
295
+ end
296
+
297
+ describe "when :required option is true" do
298
+ before do
299
+ @new_post.stub!(:author_ids).and_return(nil)
300
+ concat(semantic_form_for(@new_post) do |builder|
301
+ concat(builder.input(:authors, :as => :check_boxes, :required => true))
302
+ end)
303
+ end
304
+
305
+ it "should output the correct label title" do
306
+ output_buffer.should have_tag("legend.label label abbr")
307
+ end
308
+ end
309
+
310
+ end
311
+
312
+ describe 'for a has_and_belongs_to_many association' do
313
+
314
+ before do
315
+ @output_buffer = ''
316
+ mock_everything
317
+
318
+ concat(semantic_form_for(@freds_post) do |builder|
319
+ concat(builder.input(:authors, :as => :check_boxes))
320
+ end)
321
+ end
322
+
323
+ it 'should render checkboxes' do
324
+ # I'm aware these two lines test the same thing
325
+ output_buffer.should have_tag('input[type="checkbox"]', :count => 2)
326
+ output_buffer.should have_tag('input[type="checkbox"]', :count => ::Author.all.size)
327
+ end
328
+
329
+ it 'should only select checkboxes that are present in the association' do
330
+ # I'm aware these two lines test the same thing
331
+ output_buffer.should have_tag('input[checked="checked"]', :count => 1)
332
+ output_buffer.should have_tag('input[checked="checked"]', :count => @freds_post.authors.size)
333
+ end
334
+
335
+ end
336
+
337
+ describe 'for an association when a :collection is provided' do
338
+ describe 'it should use the specified :member_value option' do
339
+ before do
340
+ @output_buffer = ''
341
+ mock_everything
342
+ end
343
+
344
+ it 'to set the right input value' do
345
+ item = mock('item')
346
+ item.should_not_receive(:id)
347
+ item.stub!(:custom_value).and_return('custom_value')
348
+ item.should_receive(:custom_value).exactly(3).times
349
+ @new_post.author.should_receive(:custom_value).exactly(3).times
350
+ concat(semantic_form_for(@new_post) do |builder|
351
+ concat(builder.input(:author, :as => :check_boxes, :member_value => :custom_value, :collection => [item, item, item]))
352
+ end)
353
+ output_buffer.should have_tag('input[@type=checkbox][@value="custom_value"]', :count => 3)
354
+ end
355
+ end
356
+ end
357
+
358
+ describe "when namespace is provided" do
359
+
360
+ before do
361
+ @output_buffer = ''
362
+ mock_everything
363
+
364
+ concat(semantic_form_for(@fred, :namespace => "context2") do |builder|
365
+ concat(builder.input(:posts, :as => :check_boxes))
366
+ end)
367
+ end
368
+
369
+ it_should_have_label_for('context2_author_post_ids_19')
370
+ it_should_have_input_with_id('context2_author_post_ids_19')
371
+ it_should_have_input_wrapper_with_id("context2_author_posts_input")
372
+ end
373
+
374
+ end
375
+
@@ -0,0 +1,133 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe 'country input' do
5
+
6
+ include FormtasticSpecHelper
7
+
8
+ before do
9
+ @output_buffer = ''
10
+ mock_everything
11
+ end
12
+
13
+ describe "when country_select is not available as a helper from a plugin" do
14
+
15
+ it "should raise an error, sugesting the author installs a plugin" do
16
+ lambda {
17
+ semantic_form_for(@new_post) do |builder|
18
+ concat(builder.input(:country, :as => :country))
19
+ end
20
+ }.should raise_error
21
+ end
22
+
23
+ end
24
+
25
+ describe "when country_select is available as a helper (from a plugin)" do
26
+
27
+ before do
28
+ concat(semantic_form_for(@new_post) do |builder|
29
+ builder.stub!(:country_select).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
30
+ concat(builder.input(:country, :as => :country))
31
+ end)
32
+ end
33
+
34
+ it_should_have_input_wrapper_with_class("country")
35
+ it_should_have_input_wrapper_with_class(:input)
36
+ it_should_have_input_wrapper_with_id("post_country_input")
37
+
38
+ # TODO -- needs stubbing inside the builder block, tricky!
39
+ #it_should_apply_error_logic_for_input_type(:country)
40
+
41
+ it 'should generate a label for the input' do
42
+ output_buffer.should have_tag('form li label')
43
+ output_buffer.should have_tag('form li label[@for="post_country"]')
44
+ output_buffer.should have_tag('form li label', /Country/)
45
+ end
46
+
47
+ it "should generate a select" do
48
+ output_buffer.should have_tag("form li select")
49
+ end
50
+
51
+ end
52
+
53
+ describe ":priority_countries option" do
54
+
55
+ it "should be passed down to the country_select helper when provided" do
56
+ priority_countries = ["Foo", "Bah"]
57
+ semantic_form_for(@new_post) do |builder|
58
+ builder.stub!(:country_select).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
59
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {:id => "post_country", :required => true, :autofocus => false}).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
60
+
61
+ concat(builder.input(:country, :as => :country, :priority_countries => priority_countries))
62
+ end
63
+ end
64
+
65
+ it "should default to the @@priority_countries config when absent" do
66
+ priority_countries = Formtastic::FormBuilder.priority_countries
67
+ priority_countries.should_not be_empty
68
+ priority_countries.should_not be_nil
69
+
70
+ semantic_form_for(@new_post) do |builder|
71
+ builder.stub!(:country_select).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
72
+ builder.should_receive(:country_select).with(:country, priority_countries, {}, {:id => "post_country", :required => true, :autofocus => false}).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
73
+
74
+ concat(builder.input(:country, :as => :country))
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ describe "when namespace is provided" do
81
+
82
+ before do
83
+ @output_buffer = ''
84
+ mock_everything
85
+
86
+ concat(semantic_form_for(@new_post, :namespace => 'context2') do |builder|
87
+ builder.stub!(:country_select).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
88
+ builder.should_receive(:country_select).with(:country, [], {}, {:id => "context2_post_country", :required => true, :autofocus => false}).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
89
+ concat(builder.input(:country, :priority_countries => []))
90
+ end)
91
+ end
92
+
93
+ it_should_have_input_wrapper_with_id("context2_post_country_input")
94
+ it_should_have_label_for("context2_post_country")
95
+
96
+ end
97
+
98
+ describe "matching" do
99
+
100
+ describe "when the attribute is 'country'" do
101
+
102
+ before do
103
+ concat(semantic_form_for(@new_post) do |builder|
104
+ builder.stub!(:country_select).and_return(Formtastic::Util.html_safe("<select><option>...</option></select>"))
105
+ concat(builder.input(:country))
106
+ end)
107
+ end
108
+
109
+ it "should render a country input" do
110
+ output_buffer.should have_tag "form li.country"
111
+ end
112
+ end
113
+
114
+ describe "whent the attribute is 'country_something'" do
115
+
116
+ before do
117
+ concat(semantic_form_for(@new_post) do |builder|
118
+ concat(builder.input(:country_subdivision))
119
+ concat(builder.input(:country_code))
120
+ end)
121
+ end
122
+
123
+ it "should render a country input" do
124
+ output_buffer.should_not have_tag "form li.country"
125
+ output_buffer.should have_tag "form li.string", :count => 2
126
+ end
127
+
128
+ end
129
+
130
+ end
131
+
132
+ end
133
+