formtastic 2.1.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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