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
|
@@ -10,104 +10,122 @@ module CustomMacros
|
|
|
10
10
|
|
|
11
11
|
def it_should_have_input_wrapper_with_class(class_name)
|
|
12
12
|
it "should have input wrapper with class '#{class_name}'" do
|
|
13
|
-
output_buffer.
|
|
13
|
+
expect(output_buffer).to have_tag("form li.#{class_name}")
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
def it_should_have_input_wrapper_with_id(id_string)
|
|
18
18
|
it "should have input wrapper with id '#{id_string}'" do
|
|
19
|
-
output_buffer.
|
|
19
|
+
expect(output_buffer).to have_tag("form li##{id_string}")
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def it_should_not_have_a_label
|
|
24
24
|
it "should not have a label" do
|
|
25
|
-
output_buffer.
|
|
25
|
+
expect(output_buffer).not_to have_tag("form li label")
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def it_should_have_a_nested_fieldset
|
|
30
30
|
it "should have a nested_fieldset" do
|
|
31
|
-
output_buffer.
|
|
31
|
+
expect(output_buffer).to have_tag("form li fieldset")
|
|
32
32
|
end
|
|
33
33
|
end
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
def it_should_have_a_nested_fieldset_with_class(klass)
|
|
36
36
|
it "should have a nested_fieldset with class #{klass}" do
|
|
37
|
-
output_buffer.
|
|
37
|
+
expect(output_buffer).to have_tag("form li fieldset.#{klass}")
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
def it_should_have_a_nested_ordered_list_with_class(klass)
|
|
42
42
|
it "should have a nested fieldset with class #{klass}" do
|
|
43
|
-
output_buffer.
|
|
43
|
+
expect(output_buffer).to have_tag("form li ol.#{klass}")
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def it_should_have_label_with_text(string_or_regex)
|
|
48
48
|
it "should have a label with text '#{string_or_regex}'" do
|
|
49
|
-
output_buffer.
|
|
49
|
+
expect(output_buffer).to have_tag("form li label", :text => string_or_regex)
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
def it_should_have_label_for(element_id)
|
|
54
54
|
it "should have a label for ##{element_id}" do
|
|
55
|
-
output_buffer.
|
|
55
|
+
expect(output_buffer).to have_tag("form li label.label[@for='#{element_id}']")
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
def it_should_have_an_inline_label_for(element_id)
|
|
60
60
|
it "should have a label for ##{element_id}" do
|
|
61
|
-
output_buffer.
|
|
61
|
+
expect(output_buffer).to have_tag("form li label[@for='#{element_id}']")
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
def it_should_have_input_with_id(element_id)
|
|
66
66
|
it "should have an input with id '#{element_id}'" do
|
|
67
|
-
output_buffer.
|
|
67
|
+
expect(output_buffer).to have_tag("form li input##{element_id}")
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
def it_should_have_select_with_id(element_id)
|
|
72
72
|
it "should have a select box with id '#{element_id}'" do
|
|
73
|
-
output_buffer.
|
|
73
|
+
expect(output_buffer).to have_tag("form li select##{element_id}")
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# TODO use for many of the other macros
|
|
78
|
+
def it_should_have_tag_with(type, attribute_value_hash)
|
|
79
|
+
attribute_value_hash.each do |attribute, value|
|
|
80
|
+
it "should have a #{type} box with #{attribute} '#{value}'" do
|
|
81
|
+
expect(output_buffer).to have_tag("form li #{type}[@#{attribute}=\"#{value}\"]")
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
def it_should_have_input_with(attribute_value_hash)
|
|
86
|
+
it_should_have_tag_with(:input, attribute_value_hash)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def it_should_have_many_tags(type, count)
|
|
90
|
+
it "should have #{count} #{type} tags" do
|
|
91
|
+
expect(output_buffer).to have_tag("form li #{type}", count: count)
|
|
74
92
|
end
|
|
75
93
|
end
|
|
76
94
|
|
|
77
95
|
def it_should_have_input_with_type(input_type)
|
|
78
96
|
it "should have a #{input_type} input" do
|
|
79
|
-
output_buffer.
|
|
97
|
+
expect(output_buffer).to have_tag("form li input[@type=\"#{input_type}\"]")
|
|
80
98
|
end
|
|
81
99
|
end
|
|
82
100
|
|
|
83
101
|
def it_should_have_input_with_name(name)
|
|
84
102
|
it "should have an input named #{name}" do
|
|
85
|
-
output_buffer.
|
|
103
|
+
expect(output_buffer).to have_tag("form li input[@name=\"#{name}\"]")
|
|
86
104
|
end
|
|
87
105
|
end
|
|
88
106
|
|
|
89
107
|
def it_should_have_select_with_name(name)
|
|
90
108
|
it "should have an input named #{name}" do
|
|
91
|
-
output_buffer.
|
|
109
|
+
expect(output_buffer).to have_tag("form li select[@name=\"#{name}\"]")
|
|
92
110
|
end
|
|
93
111
|
end
|
|
94
112
|
|
|
95
113
|
def it_should_have_textarea_with_name(name)
|
|
96
114
|
it "should have an input named #{name}" do
|
|
97
|
-
output_buffer.
|
|
115
|
+
expect(output_buffer).to have_tag("form li textarea[@name=\"#{name}\"]")
|
|
98
116
|
end
|
|
99
117
|
end
|
|
100
118
|
|
|
101
119
|
def it_should_have_textarea_with_id(element_id)
|
|
102
120
|
it "should have an input with id '#{element_id}'" do
|
|
103
|
-
output_buffer.
|
|
121
|
+
expect(output_buffer).to have_tag("form li textarea##{element_id}")
|
|
104
122
|
end
|
|
105
123
|
end
|
|
106
124
|
|
|
107
125
|
def it_should_have_label_and_input_with_id(element_id)
|
|
108
126
|
it "should have an input with id '#{element_id}'" do
|
|
109
|
-
output_buffer.
|
|
110
|
-
output_buffer.
|
|
127
|
+
expect(output_buffer).to have_tag("form li input##{element_id}")
|
|
128
|
+
expect(output_buffer).to have_tag("form li label[@for='#{element_id}']")
|
|
111
129
|
end
|
|
112
130
|
end
|
|
113
131
|
|
|
@@ -117,7 +135,7 @@ module CustomMacros
|
|
|
117
135
|
concat(semantic_form_for(@new_post) do |builder|
|
|
118
136
|
concat(builder.input(:title, :as => as))
|
|
119
137
|
end)
|
|
120
|
-
output_buffer.
|
|
138
|
+
expect(output_buffer).to have_tag("form li input[@size='#{Formtastic::FormBuilder.default_text_field_size}']")
|
|
121
139
|
end
|
|
122
140
|
end
|
|
123
141
|
end
|
|
@@ -128,8 +146,8 @@ module CustomMacros
|
|
|
128
146
|
concat(semantic_form_for(@new_post) do |builder|
|
|
129
147
|
concat(builder.input(:title, :as => as))
|
|
130
148
|
end)
|
|
131
|
-
output_buffer.
|
|
132
|
-
output_buffer.
|
|
149
|
+
expect(output_buffer).to have_tag("form li input")
|
|
150
|
+
expect(output_buffer).not_to have_tag("form li input[@size]")
|
|
133
151
|
end
|
|
134
152
|
end
|
|
135
153
|
end
|
|
@@ -139,7 +157,7 @@ module CustomMacros
|
|
|
139
157
|
concat(semantic_form_for(@new_post) do |builder|
|
|
140
158
|
concat(builder.input(:title, :as => as, :input_html => { :class => 'myclass' }))
|
|
141
159
|
end)
|
|
142
|
-
output_buffer.
|
|
160
|
+
expect(output_buffer).to have_tag("form li input.myclass")
|
|
143
161
|
end
|
|
144
162
|
end
|
|
145
163
|
|
|
@@ -148,27 +166,28 @@ module CustomMacros
|
|
|
148
166
|
concat(semantic_form_for(@new_post) do |builder|
|
|
149
167
|
concat(builder.input(:title, :as => as, :input_html => { :id => 'myid' }))
|
|
150
168
|
end)
|
|
151
|
-
output_buffer.
|
|
169
|
+
expect(output_buffer).to have_tag('form li label[@for="myid"]')
|
|
152
170
|
end
|
|
153
171
|
end
|
|
154
172
|
|
|
155
173
|
def it_should_have_maxlength_matching_column_limit
|
|
156
174
|
it 'should have a maxlength matching column limit' do
|
|
157
|
-
@new_post.column_for_attribute(:title).limit.
|
|
158
|
-
output_buffer.
|
|
175
|
+
expect(@new_post.column_for_attribute(:title).limit).to eq(50)
|
|
176
|
+
expect(output_buffer).to have_tag("form li input[@maxlength='50']")
|
|
159
177
|
end
|
|
160
178
|
end
|
|
161
179
|
|
|
162
180
|
def it_should_use_column_size_for_columns_shorter_than_default_text_field_size(as)
|
|
163
181
|
it 'should use the column size for columns shorter than default_text_field_size' do
|
|
164
182
|
column_limit_shorted_than_default = 1
|
|
165
|
-
@new_post.
|
|
183
|
+
allow(@new_post).to receive(:column_for_attribute)
|
|
184
|
+
.and_return(double('column', :type => as, :limit => column_limit_shorted_than_default))
|
|
166
185
|
|
|
167
186
|
concat(semantic_form_for(@new_post) do |builder|
|
|
168
187
|
concat(builder.input(:title, :as => as))
|
|
169
188
|
end)
|
|
170
189
|
|
|
171
|
-
output_buffer.
|
|
190
|
+
expect(output_buffer).to have_tag("form li input[@size='#{column_limit_shorted_than_default}']")
|
|
172
191
|
end
|
|
173
192
|
end
|
|
174
193
|
|
|
@@ -176,26 +195,26 @@ module CustomMacros
|
|
|
176
195
|
describe 'when there are errors on the object for this method' do
|
|
177
196
|
before do
|
|
178
197
|
@title_errors = ['must not be blank', 'must be longer than 10 characters', 'must be awesome']
|
|
179
|
-
@errors =
|
|
180
|
-
@errors.
|
|
198
|
+
@errors = double('errors')
|
|
199
|
+
allow(@errors).to receive(:[]).with(errors_matcher(:title)).and_return(@title_errors)
|
|
181
200
|
Formtastic::FormBuilder.file_metadata_suffixes.each do |suffix|
|
|
182
|
-
@errors.
|
|
201
|
+
allow(@errors).to receive(:[]).with(errors_matcher("title_#{suffix}".to_sym)).and_return(nil)
|
|
183
202
|
end
|
|
184
|
-
@new_post.
|
|
203
|
+
allow(@new_post).to receive(:errors).and_return(@errors)
|
|
185
204
|
end
|
|
186
205
|
|
|
187
206
|
it 'should apply an errors class to the list item' do
|
|
188
207
|
concat(semantic_form_for(@new_post) do |builder|
|
|
189
208
|
concat(builder.input(:title, :as => type))
|
|
190
209
|
end)
|
|
191
|
-
output_buffer.
|
|
210
|
+
expect(output_buffer).to have_tag('form li.error')
|
|
192
211
|
end
|
|
193
212
|
|
|
194
213
|
it 'should not wrap the input with the Rails default error wrapping' do
|
|
195
214
|
concat(semantic_form_for(@new_post) do |builder|
|
|
196
215
|
concat(builder.input(:title, :as => type))
|
|
197
216
|
end)
|
|
198
|
-
output_buffer.
|
|
217
|
+
expect(output_buffer).not_to have_tag('div.fieldWithErrors')
|
|
199
218
|
end
|
|
200
219
|
|
|
201
220
|
it 'should render a paragraph for the errors' do
|
|
@@ -203,7 +222,7 @@ module CustomMacros
|
|
|
203
222
|
concat(semantic_form_for(@new_post) do |builder|
|
|
204
223
|
concat(builder.input(:title, :as => type))
|
|
205
224
|
end)
|
|
206
|
-
output_buffer.
|
|
225
|
+
expect(output_buffer).to have_tag('form li.error p.inline-errors')
|
|
207
226
|
end
|
|
208
227
|
|
|
209
228
|
it 'should not display an error list' do
|
|
@@ -211,7 +230,7 @@ module CustomMacros
|
|
|
211
230
|
concat(semantic_form_for(@new_post) do |builder|
|
|
212
231
|
concat(builder.input(:title, :as => type))
|
|
213
232
|
end)
|
|
214
|
-
output_buffer.
|
|
233
|
+
expect(output_buffer).to have_tag('form li.error ul.errors')
|
|
215
234
|
end
|
|
216
235
|
end
|
|
217
236
|
|
|
@@ -223,15 +242,15 @@ module CustomMacros
|
|
|
223
242
|
end
|
|
224
243
|
|
|
225
244
|
it 'should not apply an errors class to the list item' do
|
|
226
|
-
output_buffer.
|
|
245
|
+
expect(output_buffer).not_to have_tag('form li.error')
|
|
227
246
|
end
|
|
228
247
|
|
|
229
248
|
it 'should not render a paragraph for the errors' do
|
|
230
|
-
output_buffer.
|
|
249
|
+
expect(output_buffer).not_to have_tag('form li.error p.inline-errors')
|
|
231
250
|
end
|
|
232
251
|
|
|
233
252
|
it 'should not display an error list' do
|
|
234
|
-
output_buffer.
|
|
253
|
+
expect(output_buffer).not_to have_tag('form li.error ul.errors')
|
|
235
254
|
end
|
|
236
255
|
end
|
|
237
256
|
|
|
@@ -243,22 +262,22 @@ module CustomMacros
|
|
|
243
262
|
end
|
|
244
263
|
|
|
245
264
|
it 'should not apply an errors class to the list item' do
|
|
246
|
-
output_buffer.
|
|
265
|
+
expect(output_buffer).not_to have_tag('form li.error')
|
|
247
266
|
end
|
|
248
267
|
|
|
249
268
|
it 'should not render a paragraph for the errors' do
|
|
250
|
-
output_buffer.
|
|
269
|
+
expect(output_buffer).not_to have_tag('form li.error p.inline-errors')
|
|
251
270
|
end
|
|
252
271
|
|
|
253
272
|
it 'should not display an error list' do
|
|
254
|
-
output_buffer.
|
|
273
|
+
expect(output_buffer).not_to have_tag('form li.error ul.errors')
|
|
255
274
|
end
|
|
256
275
|
end
|
|
257
276
|
end
|
|
258
277
|
|
|
259
278
|
def it_should_call_find_on_association_class_when_no_collection_is_provided(as)
|
|
260
279
|
it "should call find on the association class when no collection is provided" do
|
|
261
|
-
::Author.
|
|
280
|
+
expect(::Author).to receive(:where)
|
|
262
281
|
concat(semantic_form_for(@new_post) do |builder|
|
|
263
282
|
concat(builder.input(:author, :as => as))
|
|
264
283
|
end)
|
|
@@ -269,7 +288,7 @@ module CustomMacros
|
|
|
269
288
|
describe 'when the :collection option is provided' do
|
|
270
289
|
|
|
271
290
|
before do
|
|
272
|
-
@authors = ::Author.all * 2
|
|
291
|
+
@authors = ([::Author.all] * 2).flatten
|
|
273
292
|
output_buffer.replace ''
|
|
274
293
|
end
|
|
275
294
|
|
|
@@ -277,7 +296,7 @@ module CustomMacros
|
|
|
277
296
|
concat(semantic_form_for(@new_post) do |builder|
|
|
278
297
|
concat(builder.input(:author, :as => as, :collection => @authors))
|
|
279
298
|
end)
|
|
280
|
-
output_buffer.
|
|
299
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}", :count => @authors.size + (as == :select ? 1 : 0))
|
|
281
300
|
end
|
|
282
301
|
|
|
283
302
|
describe 'and the :collection is an array of strings' do
|
|
@@ -291,24 +310,24 @@ module CustomMacros
|
|
|
291
310
|
end)
|
|
292
311
|
|
|
293
312
|
@categories.each do |value|
|
|
294
|
-
output_buffer.
|
|
295
|
-
output_buffer.
|
|
313
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{value}/)
|
|
314
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
|
|
296
315
|
end
|
|
297
316
|
end
|
|
298
317
|
|
|
299
318
|
if as == :radio
|
|
300
319
|
it 'should generate a sanitized label for attribute' do
|
|
301
|
-
@bob.
|
|
320
|
+
allow(@bob).to receive(:category_name).and_return(@categories)
|
|
302
321
|
concat(semantic_form_for(@new_post) do |builder|
|
|
303
322
|
fields = builder.semantic_fields_for(@bob) do |bob_builder|
|
|
304
323
|
concat(bob_builder.input(:category_name, :as => as, :collection => @categories))
|
|
305
324
|
end
|
|
306
325
|
concat(fields)
|
|
307
326
|
end)
|
|
308
|
-
output_buffer.
|
|
309
|
-
output_buffer.
|
|
310
|
-
output_buffer.
|
|
311
|
-
output_buffer.
|
|
327
|
+
expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_general']")
|
|
328
|
+
expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_design']")
|
|
329
|
+
expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_development']")
|
|
330
|
+
expect(output_buffer).to have_tag("form li fieldset ol li label[@for='post_author_category_name_quasi-serious_inventions']")
|
|
312
331
|
end
|
|
313
332
|
end
|
|
314
333
|
end
|
|
@@ -324,8 +343,8 @@ module CustomMacros
|
|
|
324
343
|
end)
|
|
325
344
|
|
|
326
345
|
@categories.each do |label, value|
|
|
327
|
-
output_buffer.
|
|
328
|
-
output_buffer.
|
|
346
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{label}/)
|
|
347
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
|
|
329
348
|
end
|
|
330
349
|
end
|
|
331
350
|
end
|
|
@@ -342,9 +361,9 @@ module CustomMacros
|
|
|
342
361
|
|
|
343
362
|
@categories.each do |text, value|
|
|
344
363
|
label = as == :select ? :option : :label
|
|
345
|
-
output_buffer.
|
|
346
|
-
output_buffer.
|
|
347
|
-
output_buffer.
|
|
364
|
+
expect(output_buffer).to have_tag("form li.#{as} #{label}", :text => /#{text}/i)
|
|
365
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
|
|
366
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_#{value.to_s}") if as == :radio
|
|
348
367
|
end
|
|
349
368
|
end
|
|
350
369
|
end
|
|
@@ -360,8 +379,8 @@ module CustomMacros
|
|
|
360
379
|
concat(builder.input(:category_name, :as => as, :collection => @choices))
|
|
361
380
|
end)
|
|
362
381
|
|
|
363
|
-
output_buffer.
|
|
364
|
-
output_buffer.
|
|
382
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_true")
|
|
383
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}#post_category_name_false")
|
|
365
384
|
end
|
|
366
385
|
end
|
|
367
386
|
end
|
|
@@ -378,8 +397,8 @@ module CustomMacros
|
|
|
378
397
|
|
|
379
398
|
@categories.each do |value|
|
|
380
399
|
label = as == :select ? :option : :label
|
|
381
|
-
output_buffer.
|
|
382
|
-
output_buffer.
|
|
400
|
+
expect(output_buffer).to have_tag("form li.#{as} #{label}", :text => /#{value}/i)
|
|
401
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value.to_s}']")
|
|
383
402
|
end
|
|
384
403
|
end
|
|
385
404
|
end
|
|
@@ -395,8 +414,8 @@ module CustomMacros
|
|
|
395
414
|
end)
|
|
396
415
|
|
|
397
416
|
@categories.each do |label, value|
|
|
398
|
-
output_buffer.
|
|
399
|
-
output_buffer.
|
|
417
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{label}/)
|
|
418
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{value}']")
|
|
400
419
|
end
|
|
401
420
|
end
|
|
402
421
|
|
|
@@ -406,28 +425,32 @@ module CustomMacros
|
|
|
406
425
|
|
|
407
426
|
describe 'as a symbol' do
|
|
408
427
|
before do
|
|
409
|
-
|
|
410
|
-
concat(
|
|
411
|
-
|
|
428
|
+
with_deprecation_silenced do
|
|
429
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
430
|
+
concat(builder.input(:author, :as => as, :member_label => :login))
|
|
431
|
+
end)
|
|
432
|
+
end
|
|
412
433
|
end
|
|
413
434
|
|
|
414
435
|
it 'should have options with text content from the specified method' do
|
|
415
436
|
::Author.all.each do |author|
|
|
416
|
-
output_buffer.
|
|
437
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login}/)
|
|
417
438
|
end
|
|
418
439
|
end
|
|
419
440
|
end
|
|
420
441
|
|
|
421
442
|
describe 'as a proc' do
|
|
422
443
|
before do
|
|
423
|
-
|
|
424
|
-
concat(
|
|
425
|
-
|
|
444
|
+
with_deprecation_silenced do
|
|
445
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
446
|
+
concat(builder.input(:author, :as => as, :member_label => Proc.new {|a| a.login.reverse }))
|
|
447
|
+
end)
|
|
448
|
+
end
|
|
426
449
|
end
|
|
427
450
|
|
|
428
451
|
it 'should have options with the proc applied to each' do
|
|
429
452
|
::Author.all.each do |author|
|
|
430
|
-
output_buffer.
|
|
453
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
|
|
431
454
|
end
|
|
432
455
|
end
|
|
433
456
|
end
|
|
@@ -437,14 +460,16 @@ module CustomMacros
|
|
|
437
460
|
def reverse_login(a)
|
|
438
461
|
a.login.reverse
|
|
439
462
|
end
|
|
440
|
-
|
|
441
|
-
concat(
|
|
442
|
-
|
|
463
|
+
with_deprecation_silenced do
|
|
464
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
465
|
+
concat(builder.input(:author, :as => as, :member_label => method(:reverse_login)))
|
|
466
|
+
end)
|
|
467
|
+
end
|
|
443
468
|
end
|
|
444
469
|
|
|
445
470
|
it 'should have options with the proc applied to each' do
|
|
446
471
|
::Author.all.each do |author|
|
|
447
|
-
output_buffer.
|
|
472
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /#{author.login.reverse}/)
|
|
448
473
|
end
|
|
449
474
|
end
|
|
450
475
|
end
|
|
@@ -455,17 +480,19 @@ module CustomMacros
|
|
|
455
480
|
|
|
456
481
|
describe "when the collection objects respond to #{label_method}" do
|
|
457
482
|
before do
|
|
458
|
-
@fred.
|
|
459
|
-
|
|
483
|
+
allow(@fred).to receive(:respond_to?) { |m| m.to_s == label_method || m.to_s == 'id' }
|
|
484
|
+
[@fred, @bob].each { |a| allow(a).to receive(label_method).and_return('The Label Text') }
|
|
460
485
|
|
|
461
|
-
|
|
462
|
-
concat(
|
|
463
|
-
|
|
486
|
+
with_deprecation_silenced do
|
|
487
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
488
|
+
concat(builder.input(:author, :as => as))
|
|
489
|
+
end)
|
|
490
|
+
end
|
|
464
491
|
end
|
|
465
492
|
|
|
466
493
|
it "should render the options with #{label_method} as the label" do
|
|
467
494
|
::Author.all.each do |author|
|
|
468
|
-
output_buffer.
|
|
495
|
+
expect(output_buffer).to have_tag("form li.#{as}", :text => /The Label Text/)
|
|
469
496
|
end
|
|
470
497
|
end
|
|
471
498
|
end
|
|
@@ -477,28 +504,32 @@ module CustomMacros
|
|
|
477
504
|
|
|
478
505
|
describe 'as a symbol' do
|
|
479
506
|
before do
|
|
480
|
-
|
|
481
|
-
concat(
|
|
482
|
-
|
|
507
|
+
with_deprecation_silenced do
|
|
508
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
509
|
+
concat(builder.input(:author, :as => as, :member_value => :login))
|
|
510
|
+
end)
|
|
511
|
+
end
|
|
483
512
|
end
|
|
484
513
|
|
|
485
514
|
it 'should have options with values from specified method' do
|
|
486
515
|
::Author.all.each do |author|
|
|
487
|
-
output_buffer.
|
|
516
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login}']")
|
|
488
517
|
end
|
|
489
518
|
end
|
|
490
519
|
end
|
|
491
520
|
|
|
492
521
|
describe 'as a proc' do
|
|
493
522
|
before do
|
|
494
|
-
|
|
495
|
-
concat(
|
|
496
|
-
|
|
523
|
+
with_deprecation_silenced do
|
|
524
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
525
|
+
concat(builder.input(:author, :as => as, :member_value => Proc.new {|a| a.login.reverse }))
|
|
526
|
+
end)
|
|
527
|
+
end
|
|
497
528
|
end
|
|
498
529
|
|
|
499
530
|
it 'should have options with the proc applied to each value' do
|
|
500
531
|
::Author.all.each do |author|
|
|
501
|
-
output_buffer.
|
|
532
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
|
|
502
533
|
end
|
|
503
534
|
end
|
|
504
535
|
end
|
|
@@ -508,14 +539,16 @@ module CustomMacros
|
|
|
508
539
|
def reverse_login(a)
|
|
509
540
|
a.login.reverse
|
|
510
541
|
end
|
|
511
|
-
|
|
512
|
-
concat(
|
|
513
|
-
|
|
542
|
+
with_deprecation_silenced do
|
|
543
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
544
|
+
concat(builder.input(:author, :as => as, :member_value => method(:reverse_login)))
|
|
545
|
+
end)
|
|
546
|
+
end
|
|
514
547
|
end
|
|
515
548
|
|
|
516
549
|
it 'should have options with the proc applied to each value' do
|
|
517
550
|
::Author.all.each do |author|
|
|
518
|
-
output_buffer.
|
|
551
|
+
expect(output_buffer).to have_tag("form li.#{as} #{countable}[@value='#{author.login.reverse}']")
|
|
519
552
|
end
|
|
520
553
|
end
|
|
521
554
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
#
|
|
3
|
+
RSpec.shared_examples 'Specialized Class Finder' do
|
|
4
|
+
let(:builder) { Formtastic::FormBuilder.allocate }
|
|
5
|
+
subject(:finder) { described_class.new(builder) }
|
|
6
|
+
|
|
7
|
+
context 'by default' do
|
|
8
|
+
it 'includes Object and the default namespaces' do
|
|
9
|
+
expect(finder.namespaces).to eq([Object, default])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'with namespace configuration set to a custom list of modules' do
|
|
14
|
+
before do
|
|
15
|
+
stub_const('CustomModule', Module.new)
|
|
16
|
+
stub_const('AnotherModule', Module.new)
|
|
17
|
+
|
|
18
|
+
allow(Formtastic::FormBuilder).to receive(namespaces_setting)
|
|
19
|
+
.and_return([ CustomModule, AnotherModule ])
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'includes just the custom namespaces' do
|
|
23
|
+
expect(finder.namespaces).to eq([CustomModule, AnotherModule])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
-
require 'rspec'
|
|
3
|
-
|
|
2
|
+
require 'rspec/core'
|
|
3
|
+
|
|
4
|
+
require 'rspec-dom-testing'
|
|
4
5
|
|
|
5
6
|
RSpec.configure do |config|
|
|
6
|
-
config.include RspecTagMatchers
|
|
7
7
|
config.include CustomMacros
|
|
8
|
+
config.include RSpec::Dom::Testing::Matchers
|
|
8
9
|
config.mock_with :rspec
|
|
10
|
+
|
|
11
|
+
# rspec-rails 3 will no longer automatically infer an example group's spec type
|
|
12
|
+
# from the file location. You can explicitly opt-in to the feature using this
|
|
13
|
+
# config option.
|
|
14
|
+
# To explicitly tag specs without using automatic inference, set the `:type`
|
|
15
|
+
# metadata manually:
|
|
16
|
+
#
|
|
17
|
+
# describe ThingsController, :type => :controller do
|
|
18
|
+
# # Equivalent to being in spec/controllers
|
|
19
|
+
# end
|
|
20
|
+
config.infer_spec_type_from_file_location!
|
|
21
|
+
|
|
22
|
+
# Setting this config option `false` removes rspec-core's monkey patching of the
|
|
23
|
+
# top level methods like `describe`, `shared_examples_for` and `shared_context`
|
|
24
|
+
# on `main` and `Module`. The methods are always available through the `RSpec`
|
|
25
|
+
# module like `RSpec.describe` regardless of this setting.
|
|
26
|
+
# For backwards compatibility this defaults to `true`.
|
|
27
|
+
#
|
|
28
|
+
# https://relishapp.com/rspec/rspec-core/v/3-0/docs/configuration/global-namespace-dsl
|
|
29
|
+
config.expose_dsl_globally = false
|
|
9
30
|
end
|
|
10
31
|
|
|
11
32
|
require "action_controller/railtie"
|
|
@@ -14,16 +35,11 @@ require 'active_model'
|
|
|
14
35
|
# Create a simple rails application for use in testing the viewhelper
|
|
15
36
|
module FormtasticTest
|
|
16
37
|
class Application < Rails::Application
|
|
17
|
-
# Configure the default encoding used in templates for Ruby 1.9.
|
|
18
|
-
config.encoding = "utf-8"
|
|
19
38
|
config.active_support.deprecation = :stderr
|
|
39
|
+
config.secret_key_base = "secret"
|
|
40
|
+
config.eager_load = false
|
|
20
41
|
end
|
|
21
42
|
end
|
|
22
43
|
FormtasticTest::Application.initialize!
|
|
23
44
|
|
|
24
45
|
require 'rspec/rails'
|
|
25
|
-
|
|
26
|
-
# Quick hack to avoid the 'Spec' deprecation warnings from rspec_tag_matchers
|
|
27
|
-
module Spec
|
|
28
|
-
include RSpec
|
|
29
|
-
end
|