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.
- checksums.yaml +7 -0
- data/.gitattributes +1 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +4 -2
- data/CHANGELOG.md +52 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +105 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +204 -219
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +27 -29
- data/app/assets/stylesheets/formtastic.css +3 -2
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +11 -14
- data/gemfiles/rails_5.2/Gemfile +5 -0
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_6.1/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/action_class_finder.rb +18 -0
- data/lib/formtastic/actions/button_action.rb +55 -60
- data/lib/formtastic/actions/input_action.rb +59 -57
- data/lib/formtastic/actions/link_action.rb +68 -67
- data/lib/formtastic/actions.rb +6 -3
- data/lib/formtastic/deprecation.rb +5 -0
- data/lib/formtastic/engine.rb +3 -1
- data/lib/formtastic/form_builder.rb +35 -16
- data/lib/formtastic/helpers/action_helper.rb +34 -28
- data/lib/formtastic/helpers/enum.rb +13 -0
- data/lib/formtastic/helpers/errors_helper.rb +2 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -12
- data/lib/formtastic/helpers/form_helper.rb +19 -16
- data/lib/formtastic/helpers/input_helper.rb +69 -97
- data/lib/formtastic/helpers/inputs_helper.rb +35 -25
- data/lib/formtastic/helpers/reflection.rb +4 -4
- data/lib/formtastic/helpers.rb +1 -2
- data/lib/formtastic/html_attributes.rb +12 -1
- data/lib/formtastic/i18n.rb +1 -1
- data/lib/formtastic/input_class_finder.rb +18 -0
- data/lib/formtastic/inputs/base/choices.rb +2 -2
- data/lib/formtastic/inputs/base/collections.rb +46 -14
- data/lib/formtastic/inputs/base/database.rb +7 -2
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +85 -0
- data/lib/formtastic/inputs/base/errors.rb +7 -7
- data/lib/formtastic/inputs/base/hints.rb +2 -2
- data/lib/formtastic/inputs/base/html.rb +10 -9
- data/lib/formtastic/inputs/base/labelling.rb +5 -8
- data/lib/formtastic/inputs/base/naming.rb +4 -4
- data/lib/formtastic/inputs/base/numeric.rb +1 -1
- data/lib/formtastic/inputs/base/options.rb +3 -4
- data/lib/formtastic/inputs/base/stringish.rb +10 -2
- data/lib/formtastic/inputs/base/timeish.rb +34 -22
- data/lib/formtastic/inputs/base/validations.rb +41 -13
- data/lib/formtastic/inputs/base/wrapping.rb +29 -26
- data/lib/formtastic/inputs/base.rb +22 -15
- data/lib/formtastic/inputs/boolean_input.rb +26 -12
- data/lib/formtastic/inputs/check_boxes_input.rb +39 -31
- data/lib/formtastic/inputs/color_input.rb +41 -0
- data/lib/formtastic/inputs/country_input.rb +24 -5
- data/lib/formtastic/inputs/datalist_input.rb +41 -0
- data/lib/formtastic/inputs/date_picker_input.rb +93 -0
- data/lib/formtastic/inputs/{date_input.rb → date_select_input.rb} +1 -1
- data/lib/formtastic/inputs/datetime_picker_input.rb +103 -0
- data/lib/formtastic/inputs/{datetime_input.rb → datetime_select_input.rb} +1 -1
- data/lib/formtastic/inputs/file_input.rb +2 -2
- data/lib/formtastic/inputs/hidden_input.rb +2 -6
- data/lib/formtastic/inputs/radio_input.rb +28 -22
- data/lib/formtastic/inputs/select_input.rb +36 -39
- data/lib/formtastic/inputs/time_picker_input.rb +99 -0
- data/lib/formtastic/inputs/{time_input.rb → time_select_input.rb} +6 -2
- data/lib/formtastic/inputs/time_zone_input.rb +16 -6
- data/lib/formtastic/inputs.rb +32 -21
- data/lib/formtastic/localized_string.rb +1 -1
- data/lib/formtastic/localizer.rb +24 -24
- data/lib/formtastic/namespaced_class_finder.rb +99 -0
- data/lib/formtastic/version.rb +1 -1
- data/lib/formtastic.rb +20 -10
- data/lib/generators/formtastic/form/form_generator.rb +10 -4
- data/lib/generators/formtastic/input/input_generator.rb +46 -0
- data/lib/generators/formtastic/install/install_generator.rb +5 -19
- data/lib/generators/templates/_form.html.slim +2 -2
- data/lib/generators/templates/formtastic.rb +46 -25
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +23 -3
- data/script/integration-template.rb +74 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +12 -0
- data/spec/actions/button_action_spec.rb +8 -8
- data/spec/actions/generic_action_spec.rb +92 -56
- data/spec/actions/input_action_spec.rb +7 -7
- data/spec/actions/link_action_spec.rb +10 -10
- data/spec/builder/custom_builder_spec.rb +36 -20
- data/spec/builder/error_proc_spec.rb +4 -4
- data/spec/builder/semantic_fields_for_spec.rb +28 -29
- data/spec/fast_spec_helper.rb +12 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +45 -32
- data/spec/generators/formtastic/input/input_generator_spec.rb +124 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +9 -9
- data/spec/helpers/action_helper_spec.rb +75 -103
- data/spec/helpers/actions_helper_spec.rb +17 -17
- data/spec/helpers/form_helper_spec.rb +84 -33
- data/spec/helpers/input_helper_spec.rb +333 -285
- data/spec/helpers/inputs_helper_spec.rb +167 -121
- data/spec/helpers/reflection_helper_spec.rb +3 -3
- data/spec/helpers/semantic_errors_helper_spec.rb +23 -23
- data/spec/i18n_spec.rb +26 -26
- data/spec/input_class_finder_spec.rb +10 -0
- data/spec/inputs/base/collections_spec.rb +76 -0
- data/spec/inputs/base/validations_spec.rb +480 -0
- data/spec/inputs/boolean_input_spec.rb +100 -65
- data/spec/inputs/check_boxes_input_spec.rb +200 -101
- data/spec/inputs/color_input_spec.rb +85 -0
- data/spec/inputs/country_input_spec.rb +20 -20
- data/spec/inputs/custom_input_spec.rb +3 -4
- data/spec/inputs/datalist_input_spec.rb +61 -0
- data/spec/inputs/date_picker_input_spec.rb +449 -0
- data/spec/inputs/date_select_input_spec.rb +249 -0
- data/spec/inputs/datetime_picker_input_spec.rb +490 -0
- data/spec/inputs/datetime_select_input_spec.rb +209 -0
- data/spec/inputs/email_input_spec.rb +5 -5
- data/spec/inputs/file_input_spec.rb +6 -6
- data/spec/inputs/hidden_input_spec.rb +22 -35
- data/spec/inputs/include_blank_spec.rb +11 -11
- data/spec/inputs/label_spec.rb +62 -25
- data/spec/inputs/number_input_spec.rb +112 -112
- data/spec/inputs/password_input_spec.rb +5 -5
- data/spec/inputs/phone_input_spec.rb +5 -5
- data/spec/inputs/placeholder_spec.rb +6 -6
- data/spec/inputs/radio_input_spec.rb +99 -55
- data/spec/inputs/range_input_spec.rb +66 -66
- data/spec/inputs/readonly_spec.rb +50 -0
- data/spec/inputs/search_input_spec.rb +5 -5
- data/spec/inputs/select_input_spec.rb +170 -170
- data/spec/inputs/string_input_spec.rb +68 -16
- data/spec/inputs/text_input_spec.rb +16 -16
- data/spec/inputs/time_picker_input_spec.rb +455 -0
- data/spec/inputs/time_select_input_spec.rb +261 -0
- data/spec/inputs/time_zone_input_spec.rb +54 -28
- data/spec/inputs/url_input_spec.rb +5 -5
- data/spec/inputs/with_options_spec.rb +7 -7
- data/spec/localizer_spec.rb +39 -17
- data/spec/namespaced_class_finder_spec.rb +79 -0
- data/spec/schema.rb +21 -0
- data/spec/spec_helper.rb +254 -221
- data/spec/support/custom_macros.rb +128 -95
- data/spec/support/shared_examples.rb +12 -0
- data/spec/support/specialized_class_finder_shared_example.rb +27 -0
- data/spec/support/test_environment.rb +26 -10
- metadata +177 -238
- data/.travis.yml +0 -8
- data/Appraisals +0 -11
- data/CHANGELOG +0 -371
- data/gemfiles/rails-3.0.gemfile +0 -7
- data/gemfiles/rails-3.1.gemfile +0 -7
- data/gemfiles/rails-3.2.gemfile +0 -7
- data/lib/formtastic/helpers/buttons_helper.rb +0 -310
- data/lib/formtastic/inputs/base/grouped_collections.rb +0 -77
- data/lib/formtastic/util.rb +0 -25
- data/lib/tasks/verify_rcov.rb +0 -44
- data/spec/helpers/buttons_helper_spec.rb +0 -166
- data/spec/helpers/commit_button_helper_spec.rb +0 -530
- data/spec/inputs/date_input_spec.rb +0 -227
- data/spec/inputs/datetime_input_spec.rb +0 -185
- data/spec/inputs/time_input_spec.rb +0 -267
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
44
|
-
output_buffer.
|
|
45
|
-
output_buffer.
|
|
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.
|
|
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.
|
|
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.
|
|
109
|
-
output_buffer.
|
|
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.
|
|
129
|
-
output_buffer.
|
|
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.
|
|
153
|
-
output_buffer.
|
|
154
|
-
output_buffer.
|
|
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.
|
|
159
|
-
output_buffer.
|
|
160
|
-
output_buffer.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
192
|
-
@new_post.
|
|
193
|
-
@new_post.
|
|
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.
|
|
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.
|
|
219
|
-
mock =
|
|
220
|
-
mock.
|
|
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.
|
|
226
|
-
::Author.
|
|
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.
|
|
329
|
-
output_buffer.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
393
|
-
output_buffer.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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(:
|
|
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.
|
|
458
|
-
output_buffer.
|
|
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.
|
|
463
|
-
output_buffer.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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(:
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
606
|
+
expect(output_buffer).to have_tag("select[@required]")
|
|
607
607
|
end
|
|
608
608
|
end
|
|
609
609
|
end
|