formtastic 2.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +1 -0
  3. data/.github/workflows/test.yml +61 -0
  4. data/.gitignore +4 -2
  5. data/CHANGELOG.md +52 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +105 -0
  8. data/MIT-LICENSE +1 -1
  9. data/{README.textile → README.md} +204 -219
  10. data/RELEASE_PROCESS +3 -1
  11. data/Rakefile +27 -29
  12. data/app/assets/stylesheets/formtastic.css +3 -2
  13. data/bin/appraisal +8 -0
  14. data/formtastic.gemspec +11 -14
  15. data/gemfiles/rails_5.2/Gemfile +5 -0
  16. data/gemfiles/rails_6.0/Gemfile +5 -0
  17. data/gemfiles/rails_6.1/Gemfile +5 -0
  18. data/gemfiles/rails_edge/Gemfile +13 -0
  19. data/lib/formtastic/action_class_finder.rb +18 -0
  20. data/lib/formtastic/actions/button_action.rb +55 -60
  21. data/lib/formtastic/actions/input_action.rb +59 -57
  22. data/lib/formtastic/actions/link_action.rb +68 -67
  23. data/lib/formtastic/actions.rb +6 -3
  24. data/lib/formtastic/deprecation.rb +5 -0
  25. data/lib/formtastic/engine.rb +3 -1
  26. data/lib/formtastic/form_builder.rb +35 -16
  27. data/lib/formtastic/helpers/action_helper.rb +34 -28
  28. data/lib/formtastic/helpers/enum.rb +13 -0
  29. data/lib/formtastic/helpers/errors_helper.rb +2 -2
  30. data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
  31. data/lib/formtastic/helpers/form_helper.rb +19 -16
  32. data/lib/formtastic/helpers/input_helper.rb +69 -97
  33. data/lib/formtastic/helpers/inputs_helper.rb +35 -25
  34. data/lib/formtastic/helpers/reflection.rb +4 -4
  35. data/lib/formtastic/helpers.rb +1 -2
  36. data/lib/formtastic/html_attributes.rb +12 -1
  37. data/lib/formtastic/i18n.rb +1 -1
  38. data/lib/formtastic/input_class_finder.rb +18 -0
  39. data/lib/formtastic/inputs/base/choices.rb +2 -2
  40. data/lib/formtastic/inputs/base/collections.rb +46 -14
  41. data/lib/formtastic/inputs/base/database.rb +7 -2
  42. data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
  43. data/lib/formtastic/inputs/base/errors.rb +7 -7
  44. data/lib/formtastic/inputs/base/hints.rb +2 -2
  45. data/lib/formtastic/inputs/base/html.rb +10 -9
  46. data/lib/formtastic/inputs/base/labelling.rb +5 -8
  47. data/lib/formtastic/inputs/base/naming.rb +4 -4
  48. data/lib/formtastic/inputs/base/numeric.rb +1 -1
  49. data/lib/formtastic/inputs/base/options.rb +3 -4
  50. data/lib/formtastic/inputs/base/stringish.rb +10 -2
  51. data/lib/formtastic/inputs/base/timeish.rb +34 -22
  52. data/lib/formtastic/inputs/base/validations.rb +41 -13
  53. data/lib/formtastic/inputs/base/wrapping.rb +29 -26
  54. data/lib/formtastic/inputs/base.rb +22 -15
  55. data/lib/formtastic/inputs/boolean_input.rb +26 -12
  56. data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
  57. data/lib/formtastic/inputs/color_input.rb +41 -0
  58. data/lib/formtastic/inputs/country_input.rb +24 -5
  59. data/lib/formtastic/inputs/datalist_input.rb +41 -0
  60. data/lib/formtastic/inputs/date_picker_input.rb +93 -0
  61. data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
  62. data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
  63. data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
  64. data/lib/formtastic/inputs/file_input.rb +2 -2
  65. data/lib/formtastic/inputs/hidden_input.rb +2 -6
  66. data/lib/formtastic/inputs/radio_input.rb +28 -22
  67. data/lib/formtastic/inputs/select_input.rb +36 -39
  68. data/lib/formtastic/inputs/time_picker_input.rb +99 -0
  69. data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
  70. data/lib/formtastic/inputs/time_zone_input.rb +16 -6
  71. data/lib/formtastic/inputs.rb +32 -21
  72. data/lib/formtastic/localized_string.rb +1 -1
  73. data/lib/formtastic/localizer.rb +24 -24
  74. data/lib/formtastic/namespaced_class_finder.rb +99 -0
  75. data/lib/formtastic/version.rb +1 -1
  76. data/lib/formtastic.rb +20 -10
  77. data/lib/generators/formtastic/form/form_generator.rb +10 -4
  78. data/lib/generators/formtastic/input/input_generator.rb +46 -0
  79. data/lib/generators/formtastic/install/install_generator.rb +5 -19
  80. data/lib/generators/templates/_form.html.slim +2 -2
  81. data/lib/generators/templates/formtastic.rb +46 -25
  82. data/lib/generators/templates/input.rb +19 -0
  83. data/sample/basic_inputs.html +23 -3
  84. data/script/integration-template.rb +74 -0
  85. data/script/integration.sh +19 -0
  86. data/spec/action_class_finder_spec.rb +12 -0
  87. data/spec/actions/button_action_spec.rb +8 -8
  88. data/spec/actions/generic_action_spec.rb +92 -56
  89. data/spec/actions/input_action_spec.rb +7 -7
  90. data/spec/actions/link_action_spec.rb +10 -10
  91. data/spec/builder/custom_builder_spec.rb +36 -20
  92. data/spec/builder/error_proc_spec.rb +4 -4
  93. data/spec/builder/semantic_fields_for_spec.rb +28 -29
  94. data/spec/fast_spec_helper.rb +12 -0
  95. data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
  96. data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
  97. data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
  98. data/spec/helpers/action_helper_spec.rb +75 -103
  99. data/spec/helpers/actions_helper_spec.rb +17 -17
  100. data/spec/helpers/form_helper_spec.rb +84 -33
  101. data/spec/helpers/input_helper_spec.rb +333 -285
  102. data/spec/helpers/inputs_helper_spec.rb +167 -121
  103. data/spec/helpers/reflection_helper_spec.rb +3 -3
  104. data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
  105. data/spec/i18n_spec.rb +26 -26
  106. data/spec/input_class_finder_spec.rb +10 -0
  107. data/spec/inputs/base/collections_spec.rb +76 -0
  108. data/spec/inputs/base/validations_spec.rb +480 -0
  109. data/spec/inputs/boolean_input_spec.rb +100 -65
  110. data/spec/inputs/check_boxes_input_spec.rb +200 -101
  111. data/spec/inputs/color_input_spec.rb +85 -0
  112. data/spec/inputs/country_input_spec.rb +20 -20
  113. data/spec/inputs/custom_input_spec.rb +3 -4
  114. data/spec/inputs/datalist_input_spec.rb +61 -0
  115. data/spec/inputs/date_picker_input_spec.rb +449 -0
  116. data/spec/inputs/date_select_input_spec.rb +249 -0
  117. data/spec/inputs/datetime_picker_input_spec.rb +490 -0
  118. data/spec/inputs/datetime_select_input_spec.rb +209 -0
  119. data/spec/inputs/email_input_spec.rb +5 -5
  120. data/spec/inputs/file_input_spec.rb +6 -6
  121. data/spec/inputs/hidden_input_spec.rb +22 -35
  122. data/spec/inputs/include_blank_spec.rb +11 -11
  123. data/spec/inputs/label_spec.rb +62 -25
  124. data/spec/inputs/number_input_spec.rb +112 -112
  125. data/spec/inputs/password_input_spec.rb +5 -5
  126. data/spec/inputs/phone_input_spec.rb +5 -5
  127. data/spec/inputs/placeholder_spec.rb +6 -6
  128. data/spec/inputs/radio_input_spec.rb +99 -55
  129. data/spec/inputs/range_input_spec.rb +66 -66
  130. data/spec/inputs/readonly_spec.rb +50 -0
  131. data/spec/inputs/search_input_spec.rb +5 -5
  132. data/spec/inputs/select_input_spec.rb +170 -170
  133. data/spec/inputs/string_input_spec.rb +68 -16
  134. data/spec/inputs/text_input_spec.rb +16 -16
  135. data/spec/inputs/time_picker_input_spec.rb +455 -0
  136. data/spec/inputs/time_select_input_spec.rb +261 -0
  137. data/spec/inputs/time_zone_input_spec.rb +54 -28
  138. data/spec/inputs/url_input_spec.rb +5 -5
  139. data/spec/inputs/with_options_spec.rb +7 -7
  140. data/spec/localizer_spec.rb +39 -17
  141. data/spec/namespaced_class_finder_spec.rb +79 -0
  142. data/spec/schema.rb +21 -0
  143. data/spec/spec_helper.rb +254 -221
  144. data/spec/support/custom_macros.rb +128 -95
  145. data/spec/support/shared_examples.rb +12 -0
  146. data/spec/support/specialized_class_finder_shared_example.rb +27 -0
  147. data/spec/support/test_environment.rb +26 -10
  148. metadata +177 -238
  149. data/.travis.yml +0 -8
  150. data/Appraisals +0 -11
  151. data/CHANGELOG +0 -371
  152. data/gemfiles/rails-3.0.gemfile +0 -7
  153. data/gemfiles/rails-3.1.gemfile +0 -7
  154. data/gemfiles/rails-3.2.gemfile +0 -7
  155. data/lib/formtastic/helpers/buttons_helper.rb +0 -310
  156. data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
  157. data/lib/formtastic/util.rb +0 -25
  158. data/lib/tasks/verify_rcov.rb +0 -44
  159. data/spec/helpers/buttons_helper_spec.rb +0 -166
  160. data/spec/helpers/commit_button_helper_spec.rb +0 -530
  161. data/spec/inputs/date_input_spec.rb +0 -227
  162. data/spec/inputs/datetime_input_spec.rb +0 -185
  163. data/spec/inputs/time_input_spec.rb +0 -267
  164. data/spec/support/deferred_garbage_collection.rb +0 -21
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
  require 'spec_helper'
3
3
 
4
- describe 'select input' do
4
+ RSpec.describe 'select input' do
5
5
 
6
6
  include FormtasticSpecHelper
7
7
 
@@ -23,26 +23,46 @@ describe 'select input' do
23
23
 
24
24
  it 'should have a option for each key and/or value' do
25
25
  @array_with_values.each do |v|
26
- output_buffer.should have_tag("form li select option[@value='#{v}']", /^#{v}$/)
26
+ expect(output_buffer).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
27
27
  end
28
28
  @array_with_keys_and_values.each do |v|
29
- output_buffer.should have_tag("form li select option[@value='#{v.second}']", /^#{v.first}$/)
29
+ expect(output_buffer).to have_tag("form li select option[@value='#{v.second}']", :text => /^#{v.first}$/)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe 'using a set of values' do
35
+ before do
36
+ @set_with_values = Set.new(["Title A", "Title B", "Title C"])
37
+ @set_with_keys_and_values = [["Title D", :d], ["Title E", :e], ["Title F", :f]]
38
+ concat(semantic_form_for(@new_post) do |builder|
39
+ concat(builder.input(:title, :as => :select, :collection => @set_with_values))
40
+ concat(builder.input(:title, :as => :select, :collection => @set_with_keys_and_values))
41
+ end)
42
+ end
43
+
44
+ it 'should have a option for each key and/or value' do
45
+ @set_with_values.each do |v|
46
+ expect(output_buffer).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
47
+ end
48
+ @set_with_keys_and_values.each do |v|
49
+ expect(output_buffer).to have_tag("form li select option[@value='#{v.second}']", :text => /^#{v.first}$/)
30
50
  end
31
51
  end
32
52
  end
33
53
 
34
54
  describe "using a related model without reflection's options (Mongoid Document)" do
35
55
  before do
36
- @new_post.stub!(:mongoid_reviewer)
56
+ allow(@new_post).to receive(:mongoid_reviewer)
37
57
  concat(semantic_form_for(@new_post) do |builder|
38
58
  concat(builder.input(:mongoid_reviewer, :as => :select))
39
59
  end)
40
60
  end
41
61
 
42
62
  it 'should draw select options' do
43
- output_buffer.should have_tag('form li select')
44
- output_buffer.should have_tag('form li select#post_reviewer_id')
45
- output_buffer.should_not have_tag('form li select#post_mongoid_reviewer_id')
63
+ expect(output_buffer).to have_tag('form li select')
64
+ expect(output_buffer).to have_tag('form li select#post_reviewer_id')
65
+ expect(output_buffer).not_to have_tag('form li select#post_mongoid_reviewer_id')
46
66
  end
47
67
  end
48
68
 
@@ -56,14 +76,14 @@ describe 'select input' do
56
76
 
57
77
  it 'should have an option for each value' do
58
78
  @range_with_values.each do |v|
59
- output_buffer.should have_tag("form li select option[@value='#{v}']", /^#{v}$/)
79
+ expect(output_buffer).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
60
80
  end
61
81
  end
62
82
  end
63
83
 
64
84
  describe 'using a string' do
65
85
  before do
66
- @string ="<option value='0'>0</option><option value='1'>1</option>"
86
+ @string ="<option value='0'>0</option><option value='1'>1</option>".html_safe
67
87
  concat(semantic_form_for(@new_post) do |builder|
68
88
  concat(builder.input(:title, :as => :select, :collection => @string))
69
89
  end)
@@ -71,7 +91,7 @@ describe 'select input' do
71
91
 
72
92
  it 'should render select options using provided HTML string' do
73
93
  2.times do |v|
74
- output_buffer.should have_tag("form li select option[@value='#{v}']", /^#{v}$/)
94
+ expect(output_buffer).to have_tag("form li select option[@value='#{v}']", :text => /^#{v}$/)
75
95
  end
76
96
  end
77
97
  end
@@ -105,8 +125,8 @@ describe 'select input' do
105
125
  end
106
126
 
107
127
  it 'should render a select with at least options: true/false' do
108
- output_buffer.should have_tag("form li select option[@value='true']", /^Yes$/)
109
- output_buffer.should have_tag("form li select option[@value='false']", /^No$/)
128
+ expect(output_buffer).to have_tag("form li select option[@value='true']", :text => /^Yes$/)
129
+ expect(output_buffer).to have_tag("form li select option[@value='false']", :text => /^No$/)
110
130
  end
111
131
  end
112
132
 
@@ -125,8 +145,79 @@ describe 'select input' do
125
145
  end
126
146
 
127
147
  it 'should render a select with at least options: true/false' do
128
- output_buffer.should have_tag("form li select option[@value='true']", /#{@boolean_select_labels[:yes]}/)
129
- output_buffer.should have_tag("form li select option[@value='false']", /#{@boolean_select_labels[:no]}/)
148
+ expect(output_buffer).to have_tag("form li select option[@value='true']", :text => /#{@boolean_select_labels[:yes]}/)
149
+ expect(output_buffer).to have_tag("form li select option[@value='false']", :text => /#{@boolean_select_labels[:no]}/)
150
+ end
151
+ end
152
+ end
153
+
154
+ describe 'for a enum column' do
155
+ before do
156
+ allow(@new_post).to receive(:status) { 'inactive' }
157
+ statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
158
+ allow(@new_post.class).to receive(:statuses) { statuses }
159
+ allow(@new_post).to receive(:defined_enums) { { "status" => statuses } }
160
+ end
161
+
162
+ context 'single choice' do
163
+ before do
164
+ concat(semantic_form_for(@new_post) do |builder|
165
+ concat(builder.input(:status, :as => :select))
166
+ end)
167
+ end
168
+
169
+ it_should_have_input_wrapper_with_class("select")
170
+ it_should_have_input_wrapper_with_class(:input)
171
+ it_should_have_input_wrapper_with_id("post_status_input")
172
+ it_should_have_label_with_text(/Status/)
173
+ it_should_have_label_for('post_status')
174
+ it_should_apply_error_logic_for_input_type(:select)
175
+
176
+ it 'should have a select inside the wrapper' do
177
+ expect(output_buffer).to have_tag('form li select')
178
+ expect(output_buffer).to have_tag('form li select#post_status')
179
+ end
180
+
181
+ it 'should have a valid name' do
182
+ expect(output_buffer).to have_tag("form li select[@name='post[status]']")
183
+ expect(output_buffer).not_to have_tag("form li select[@name='post[status][]']")
184
+ end
185
+
186
+ it 'should not create a multi-select' do
187
+ expect(output_buffer).not_to have_tag('form li select[@multiple]')
188
+ end
189
+
190
+ it 'should not add a hidden input' do
191
+ expect(output_buffer).not_to have_tag('form li input[@type="hidden"]')
192
+ end
193
+
194
+ it 'should create a select without size' do
195
+ expect(output_buffer).not_to have_tag('form li select[@size]')
196
+ end
197
+
198
+ it 'should have a blank option' do
199
+ expect(output_buffer).to have_tag("form li select option[@value='']")
200
+ end
201
+
202
+ it 'should have a select option for each defined enum status' do
203
+ expect(output_buffer).to have_tag("form li select[@name='post[status]'] option", :count => @new_post.class.statuses.count + 1)
204
+ @new_post.class.statuses.each do |label, value|
205
+ expect(output_buffer).to have_tag("form li select option[@value='#{label}']", :text => /#{label.humanize}/)
206
+ end
207
+ end
208
+
209
+ it 'should have one option with a "selected" attribute (TODO)' do
210
+ expect(output_buffer).to have_tag("form li select[@name='post[status]'] option[@selected]", :count => 1)
211
+ end
212
+ end
213
+
214
+ context 'multiple choice' do
215
+ it 'raises an error' do
216
+ expect {
217
+ concat(semantic_form_for(@new_post) do |builder|
218
+ concat(builder.input(:status, :as => :select, :multiple => true))
219
+ end)
220
+ }.to raise_error Formtastic::UnsupportedEnumCollection
130
221
  end
131
222
  end
132
223
  end
@@ -149,164 +240,73 @@ describe 'select input' do
149
240
  it_should_use_the_collection_when_provided(:select, 'option')
150
241
 
151
242
  it 'should have a select inside the wrapper' do
152
- output_buffer.should have_tag('form li select')
153
- output_buffer.should have_tag('form li select#post_author_id')
154
- output_buffer.should have_tag('form li select#post_reviewer_id')
243
+ expect(output_buffer).to have_tag('form li select')
244
+ expect(output_buffer).to have_tag('form li select#post_author_id')
245
+ expect(output_buffer).to have_tag('form li select#post_reviewer_id')
155
246
  end
156
247
 
157
248
  it 'should have a valid name' do
158
- output_buffer.should have_tag("form li select[@name='post[author_id]']")
159
- output_buffer.should_not have_tag("form li select[@name='post[author_id][]']")
160
- output_buffer.should_not have_tag("form li select[@name='post[reviewer_id][]']")
249
+ expect(output_buffer).to have_tag("form li select[@name='post[author_id]']")
250
+ expect(output_buffer).not_to have_tag("form li select[@name='post[author_id][]']")
251
+ expect(output_buffer).not_to have_tag("form li select[@name='post[reviewer_id][]']")
161
252
  end
162
253
 
163
254
  it 'should not create a multi-select' do
164
- output_buffer.should_not have_tag('form li select[@multiple]')
255
+ expect(output_buffer).not_to have_tag('form li select[@multiple]')
165
256
  end
166
257
 
167
258
  it 'should not add a hidden input' do
168
- output_buffer.should_not have_tag('form li input[@type="hidden"]')
259
+ expect(output_buffer).not_to have_tag('form li input[@type="hidden"]')
169
260
  end
170
261
 
171
262
  it 'should create a select without size' do
172
- output_buffer.should_not have_tag('form li select[@size]')
263
+ expect(output_buffer).not_to have_tag('form li select[@size]')
173
264
  end
174
265
 
175
266
  it 'should have a blank option' do
176
- output_buffer.should have_tag("form li select option[@value='']")
267
+ expect(output_buffer).to have_tag("form li select option[@value='']")
177
268
  end
178
269
 
179
270
  it 'should have a select option for each Author' do
180
- output_buffer.should have_tag("form li select[@name='post[author_id]'] option", :count => ::Author.all.size + 1)
271
+ expect(output_buffer).to have_tag("form li select[@name='post[author_id]'] option", :count => ::Author.all.size + 1)
181
272
  ::Author.all.each do |author|
182
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
273
+ expect(output_buffer).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
183
274
  end
184
275
  end
185
276
 
186
277
  it 'should have one option with a "selected" attribute (bob)' do
187
- output_buffer.should have_tag("form li select[@name='post[author_id]'] option[@selected]", :count => 1)
278
+ expect(output_buffer).to have_tag("form li select[@name='post[author_id]'] option[@selected]", :count => 1)
188
279
  end
189
280
 
190
281
  it 'should not singularize the association name' do
191
- @new_post.stub!(:author_status).and_return(@bob)
192
- @new_post.stub!(:author_status_id).and_return(@bob.id)
193
- @new_post.stub!(:column_for_attribute).and_return(mock('column', :type => :integer, :limit => 255))
282
+ allow(@new_post).to receive(:author_status).and_return(@bob)
283
+ allow(@new_post).to receive(:author_status_id).and_return(@bob.id)
284
+ allow(@new_post).to receive(:column_for_attribute).and_return(double('column', :type => :integer, :limit => 255))
194
285
 
195
286
  concat(semantic_form_for(@new_post) do |builder|
196
287
  concat(builder.input(:author_status, :as => :select))
197
288
  end)
198
289
 
199
- output_buffer.should have_tag('form li select#post_author_status_id')
200
- end
201
- end
202
-
203
- describe "for a belongs_to association with :group_by => :author" do
204
- it "should call author.posts" do
205
- ::Author.stub!(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [mock('reflection', :klass => Post, :name => :posts)] : []}
206
-
207
- [@freds_post].each { |post| post.stub!(:to_label).and_return("Post - #{post.id}") }
208
- @fred.should_receive(:posts)
209
-
210
- concat(semantic_form_for(@new_post) do |builder|
211
- concat(builder.input(:main_post, :as => :select, :group_by => :author ) )
212
- end)
290
+ expect(output_buffer).to have_tag('form li select#post_author_status_id')
213
291
  end
214
292
  end
215
293
 
216
294
  describe "for a belongs_to association with :conditions" do
217
295
  before do
218
- ::Post.stub!(:reflect_on_association).with(:author).and_return do
219
- mock = mock('reflection', :options => {:conditions => {:active => true}}, :klass => ::Author, :macro => :belongs_to)
220
- mock.stub!(:[]).with(:class_name).and_return("Author")
296
+ allow(::Post).to receive(:reflect_on_association).with(:author) do
297
+ mock = double('reflection', :options => {:conditions => {:active => true}}, :klass => ::Author, :macro => :belongs_to)
298
+ allow(mock).to receive(:[]).with(:class_name).and_return("Author")
221
299
  mock
222
300
  end
223
301
  end
224
302
 
225
- it "should call author.find with association conditions" do
226
- ::Author.should_receive(:scoped).with(:conditions => {:active => true})
303
+ it "should call author.(scoped|where) with association conditions" do
304
+ expect(::Author).to receive(:where).with({:active => true})
227
305
 
228
306
  semantic_form_for(@new_post) do |builder|
229
307
  concat(builder.input(:author, :as => :select))
230
308
  end
231
309
  end
232
-
233
- it "should call author.find with association conditions and find_options conditions" do
234
- ::Author.should_receive(:scoped).with(:conditions => {:active => true})
235
- ::Author.should_receive(:where).with({:publisher => true})
236
-
237
- semantic_form_for(@new_post) do |builder|
238
- concat(builder.input(:author, :as => :select, :find_options => {:conditions => {:publisher => true}}))
239
- end
240
- end
241
- end
242
-
243
- describe 'for a belongs_to association with :group_by => :continent' do
244
- before do
245
- @authors = [@bob, @fred, @fred, @fred]
246
- ::Author.stub!(:find).and_return(@authors)
247
- @continent_names = %w(Europe Africa)
248
- @continents = (0..1).map { |i| c = ::Continent.new; c.stub!(:id).and_return(100 - i);c }
249
- @authors[0..1].each_with_index { |author, i| author.stub!(:continent).and_return(@continents[i]) }
250
-
251
- ::Continent.stub!(:reflect_on_all_associations).and_return { |macro| macro == :has_many ? [mock('reflection', :klass => Author, :name => :authors)] : [] }
252
- ::Continent.stub!(:reflect_on_association).and_return {|column_name| mock('reflection', :klass => Author) if column_name == :authors}
253
- ::Author.stub!(:reflect_on_association).and_return { |column_name| mock('reflection', :options => {}, :klass => Continent, :macro => :belongs_to) if column_name == :continent }
254
-
255
-
256
- @continents.each_with_index do |continent, i|
257
- continent.stub!(:to_label).and_return(@continent_names[i])
258
- continent.stub!(:authors).and_return([@authors[i]])
259
- end
260
-
261
- concat(semantic_form_for(@new_post) do |builder|
262
- concat(builder.input(:author, :as => :select, :group_by => :continent ) )
263
- concat(builder.input(:author, :as => :select, :group_by => :continent, :group_label => :id ) )
264
- concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login ) )
265
- concat(builder.input(:author, :as => :select, :group_by => :continent, :member_label => :login, :group_label => :id ) )
266
- end)
267
- end
268
-
269
- it_should_have_input_wrapper_with_class("select")
270
- it_should_have_input_wrapper_with_id("post_author_input")
271
- it_should_have_label_with_text(/Author/)
272
- it_should_have_label_for('post_author_id')
273
-
274
- # TODO, need to find a way to repeat some of the specs and logic from the belongs_to specs without grouping
275
-
276
- 0.upto(1) do |i|
277
- it 'should have all option groups and the right values' do
278
- output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].to_label)
279
- end
280
-
281
- it 'should have custom group labels' do
282
- output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].to_label)
283
- end
284
-
285
- it 'should have custom author labels' do
286
- output_buffer.should have_tag("form li select optgroup[@label='#{@continent_names[i]}']", @authors[i].login)
287
- end
288
-
289
- it 'should have custom author and group labels' do
290
- output_buffer.should have_tag("form li select optgroup[@label='#{@continents[i].id}']", @authors[i].login)
291
- end
292
- end
293
-
294
- it 'should have no duplicate groups' do
295
- output_buffer.should have_tag('form li select optgroup', :count => 8)
296
- end
297
-
298
- it 'should sort the groups on the label method' do
299
- output_buffer.should have_tag("form li select optgroup[@label='Africa']")
300
- output_buffer.should have_tag("form li select optgroup[@label='99']")
301
- end
302
-
303
- it 'should call find with :include for more optimized queries' do
304
- Author.should_receive(:where).with(:include => :continent)
305
-
306
- semantic_form_for(@new_post) do |builder|
307
- concat(builder.input(:author, :as => :select, :group_by => :continent ) )
308
- end
309
- end
310
310
  end
311
311
 
312
312
  describe 'for a has_many association' do
@@ -325,31 +325,31 @@ describe 'select input' do
325
325
  it_should_use_the_collection_when_provided(:select, 'option')
326
326
 
327
327
  it 'should have a select inside the wrapper' do
328
- output_buffer.should have_tag('form li select')
329
- output_buffer.should have_tag('form li select#author_post_ids')
328
+ expect(output_buffer).to have_tag('form li select')
329
+ expect(output_buffer).to have_tag('form li select#author_post_ids')
330
330
  end
331
331
 
332
332
  it 'should have a multi-select select' do
333
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
333
+ expect(output_buffer).to have_tag('form li select[@multiple="multiple"]')
334
334
  end
335
335
 
336
336
  it 'should append [] to the name attribute for multiple select' do
337
- output_buffer.should have_tag('form li select[@multiple="multiple"][@name="author[post_ids][]"]')
337
+ expect(output_buffer).to have_tag('form li select[@multiple="multiple"][@name="author[post_ids][]"]')
338
338
  end
339
339
 
340
340
  it 'should have a hidden field' do
341
- output_buffer.should have_tag('form li input[@type="hidden"][@name="author[post_ids][]"]')
341
+ expect(output_buffer).to have_tag('form li input[@type="hidden"][@name="author[post_ids][]"]', :count => 1)
342
342
  end
343
343
 
344
344
  it 'should have a select option for each Post' do
345
- output_buffer.should have_tag('form li select option', :count => ::Post.all.size)
345
+ expect(output_buffer).to have_tag('form li select option', :count => ::Post.all.size)
346
346
  ::Post.all.each do |post|
347
- output_buffer.should have_tag("form li select option[@value='#{post.id}']", /#{post.to_label}/)
347
+ expect(output_buffer).to have_tag("form li select option[@value='#{post.id}']", :text => /#{post.to_label}/)
348
348
  end
349
349
  end
350
350
 
351
351
  it 'should not have a blank option by default' do
352
- output_buffer.should_not have_tag("form li select option[@value='']")
352
+ expect(output_buffer).not_to have_tag("form li select option[@value='']")
353
353
  end
354
354
 
355
355
  it 'should respect the :include_blank option for single selects' do
@@ -357,7 +357,7 @@ describe 'select input' do
357
357
  concat(builder.input(:posts, :as => :select, :multiple => false, :include_blank => true))
358
358
  end)
359
359
 
360
- output_buffer.should have_tag("form li select option[@value='']")
360
+ expect(output_buffer).to have_tag("form li select option[@value='']")
361
361
  end
362
362
 
363
363
  it 'should respect the :include_blank option for multiple selects' do
@@ -365,11 +365,11 @@ describe 'select input' do
365
365
  concat(builder.input(:posts, :as => :select, :multiple => true, :include_blank => true))
366
366
  end)
367
367
 
368
- output_buffer.should have_tag("form li select option[@value='']")
368
+ expect(output_buffer).to have_tag("form li select option[@value='']")
369
369
  end
370
370
 
371
371
  it 'should have one option with a "selected" attribute' do
372
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
372
+ expect(output_buffer).to have_tag('form li select option[@selected]', :count => 1)
373
373
  end
374
374
  end
375
375
 
@@ -389,23 +389,23 @@ describe 'select input' do
389
389
  it_should_use_the_collection_when_provided(:select, 'option')
390
390
 
391
391
  it 'should have a select inside the wrapper' do
392
- output_buffer.should have_tag('form li select')
393
- output_buffer.should have_tag('form li select#post_author_ids')
392
+ expect(output_buffer).to have_tag('form li select')
393
+ expect(output_buffer).to have_tag('form li select#post_author_ids')
394
394
  end
395
395
 
396
396
  it 'should have a multi-select select' do
397
- output_buffer.should have_tag('form li select[@multiple="multiple"]')
397
+ expect(output_buffer).to have_tag('form li select[@multiple="multiple"]')
398
398
  end
399
399
 
400
400
  it 'should have a select option for each Author' do
401
- output_buffer.should have_tag('form li select option', :count => ::Author.all.size)
401
+ expect(output_buffer).to have_tag('form li select option', :count => ::Author.all.size)
402
402
  ::Author.all.each do |author|
403
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
403
+ expect(output_buffer).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
404
404
  end
405
405
  end
406
406
 
407
407
  it 'should not have a blank option by default' do
408
- output_buffer.should_not have_tag("form li select option[@value='']")
408
+ expect(output_buffer).not_to have_tag("form li select option[@value='']")
409
409
  end
410
410
 
411
411
  it 'should respect the :include_blank option for single selects' do
@@ -413,7 +413,7 @@ describe 'select input' do
413
413
  concat(builder.input(:authors, :as => :select, :multiple => false, :include_blank => true))
414
414
  end)
415
415
 
416
- output_buffer.should have_tag("form li select option[@value='']")
416
+ expect(output_buffer).to have_tag("form li select option[@value='']")
417
417
  end
418
418
 
419
419
  it 'should respect the :include_blank option for multiple selects' do
@@ -421,51 +421,51 @@ describe 'select input' do
421
421
  concat(builder.input(:authors, :as => :select, :multiple => true, :include_blank => true))
422
422
  end)
423
423
 
424
- output_buffer.should have_tag("form li select option[@value='']")
424
+ expect(output_buffer).to have_tag("form li select option[@value='']")
425
425
  end
426
426
 
427
427
  it 'should have one option with a "selected" attribute' do
428
- output_buffer.should have_tag('form li select option[@selected]', :count => 1)
428
+ expect(output_buffer).to have_tag('form li select option[@selected]', :count => 1)
429
429
  end
430
430
  end
431
431
 
432
432
  describe 'when :prompt => "choose something" is set' do
433
433
  before do
434
- @new_post.stub!(:author_id).and_return(nil)
434
+ allow(@new_post).to receive(:author_id).and_return(nil)
435
435
  concat(semantic_form_for(@new_post) do |builder|
436
436
  concat(builder.input(:author, :as => :select, :prompt => "choose author"))
437
437
  end)
438
438
  end
439
439
 
440
440
  it 'should have a select with prompt' do
441
- output_buffer.should have_tag("form li select option[@value='']", /choose author/, :count => 1)
441
+ expect(output_buffer).to have_tag("form li select option[@value='']", :text => /choose author/, :count => 1)
442
442
  end
443
443
 
444
444
  it 'should not have a second blank select option' do
445
- output_buffer.should have_tag("form li select option[@value='']", :count => 1)
445
+ expect(output_buffer).to have_tag("form li select option[@value='']", :count => 1)
446
446
  end
447
447
  end
448
448
 
449
449
  describe 'when no object is given' do
450
- before(:each) do
450
+ before(:example) do
451
451
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
452
452
  concat(builder.input(:author, :as => :select, :collection => ::Author.all))
453
453
  end)
454
454
  end
455
455
 
456
456
  it 'should generate label' do
457
- output_buffer.should have_tag('form li label', /Author/)
458
- output_buffer.should have_tag("form li label[@for='project_author']")
457
+ expect(output_buffer).to have_tag('form li label', :text => /Author/)
458
+ expect(output_buffer).to have_tag("form li label[@for='project_author']")
459
459
  end
460
460
 
461
461
  it 'should generate select inputs' do
462
- output_buffer.should have_tag('form li select#project_author')
463
- output_buffer.should have_tag('form li select option', :count => ::Author.all.size + 1)
462
+ expect(output_buffer).to have_tag('form li select#project_author')
463
+ expect(output_buffer).to have_tag('form li select option', :count => ::Author.all.size + 1)
464
464
  end
465
465
 
466
466
  it 'should generate an option to each item' do
467
467
  ::Author.all.each do |author|
468
- output_buffer.should have_tag("form li select option[@value='#{author.id}']", /#{author.to_label}/)
468
+ expect(output_buffer).to have_tag("form li select option[@value='#{author.id}']", :text => /#{author.to_label}/)
469
469
  end
470
470
  end
471
471
  end
@@ -476,7 +476,7 @@ describe 'select input' do
476
476
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
477
477
  concat(builder.input(:author_name, :as => :select, :collection => ::Author.all))
478
478
  end)
479
- output_buffer.should have_tag("form li select[@name='project[author_name]']")
479
+ expect(output_buffer).to have_tag("form li select[@name='project[author_name]']")
480
480
  end
481
481
 
482
482
  describe 'and :multiple is set to true through :input_html' do
@@ -484,7 +484,7 @@ describe 'select input' do
484
484
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
485
485
  concat(builder.input(:author_name, :as => :select, :input_html => {:multiple => true} ))
486
486
  end)
487
- output_buffer.should have_tag("form li select[@multiple]")
487
+ expect(output_buffer).to have_tag("form li select[@multiple]")
488
488
  end
489
489
  end
490
490
 
@@ -493,14 +493,14 @@ describe 'select input' do
493
493
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
494
494
  concat(builder.input(:author_name, :as => :select, :multiple => true, :collection => ["Fred", "Bob"]))
495
495
  end)
496
- output_buffer.should have_tag("form li select[@multiple]")
496
+ expect(output_buffer).to have_tag("form li select[@multiple]")
497
497
  end
498
498
  end
499
499
 
500
500
  end
501
501
 
502
502
  describe 'when a grouped collection collection is given' do
503
- before(:each) do
503
+ before(:example) do
504
504
  concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
505
505
  @grouped_opts = [['one', ['pencil', 'crayon', 'pen']],
506
506
  ['two', ['eyes', 'hands', 'feet']],
@@ -511,12 +511,12 @@ describe 'select input' do
511
511
 
512
512
  it 'should generate an option to each item' do
513
513
  @grouped_opts.each do |opt_pair|
514
- output_buffer.should have_tag("form li select optgroup[@label='#{opt_pair[0]}']")
514
+ expect(output_buffer).to have_tag("form li select optgroup[@label='#{opt_pair[0]}']")
515
515
  opt_pair[1].each do |v|
516
- output_buffer.should have_tag("form li select optgroup[@label='#{opt_pair[0]}'] option[@value='#{v}']")
516
+ expect(output_buffer).to have_tag("form li select optgroup[@label='#{opt_pair[0]}'] option[@value='#{v}']")
517
517
  end
518
518
  end
519
- output_buffer.should have_tag("form li select optgroup option[@selected]","hands")
519
+ expect(output_buffer).to have_tag("form li select optgroup option[@selected]","hands")
520
520
  end
521
521
  end
522
522
 
@@ -524,7 +524,7 @@ describe 'select input' do
524
524
  before do
525
525
  @output_buffer = ''
526
526
  @some_meta_descriptions = ["One", "Two", "Three"]
527
- @new_post.stub!(:meta_description).any_number_of_times
527
+ allow(@new_post).to receive(:meta_description).at_least(:once)
528
528
  end
529
529
 
530
530
  describe ":as is not set" do
@@ -538,7 +538,7 @@ describe 'select input' do
538
538
  end
539
539
 
540
540
  it "should render a select field" do
541
- output_buffer.should have_tag("form li select", :count => 2)
541
+ expect(output_buffer).to have_tag("form li select", :count => 2)
542
542
  end
543
543
  end
544
544
 
@@ -554,7 +554,7 @@ describe 'select input' do
554
554
  end
555
555
 
556
556
  it "should render a text field" do
557
- output_buffer.should have_tag("form li input[@type='text']", :count => 2)
557
+ expect(output_buffer).to have_tag("form li input[@type='text']", :count => 2)
558
558
  end
559
559
  end
560
560
  end
@@ -584,15 +584,15 @@ describe 'select input' do
584
584
  end
585
585
 
586
586
  it 'should index the id of the wrapper' do
587
- output_buffer.should have_tag("li#post_author_attributes_3_name_input")
587
+ expect(output_buffer).to have_tag("li#post_author_attributes_3_name_input")
588
588
  end
589
589
 
590
590
  it 'should index the id of the select tag' do
591
- output_buffer.should have_tag("select#post_author_attributes_3_name")
591
+ expect(output_buffer).to have_tag("select#post_author_attributes_3_name")
592
592
  end
593
593
 
594
594
  it 'should index the name of the select' do
595
- output_buffer.should have_tag("select[@name='post[author_attributes][3][name]']")
595
+ expect(output_buffer).to have_tag("select[@name='post[author_attributes][3][name]']")
596
596
  end
597
597
 
598
598
  end
@@ -603,7 +603,7 @@ describe 'select input' do
603
603
  concat(semantic_form_for(@new_post) do |builder|
604
604
  concat(builder.input(:author, :as => :select, :required => true))
605
605
  end)
606
- output_buffer.should have_tag("select[@required]")
606
+ expect(output_buffer).to have_tag("select[@required]")
607
607
  end
608
608
  end
609
609
  end