formtastic 3.0.0 → 5.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 +5 -13
- data/.gitattributes +1 -0
- data/.github/workflows/test.yml +61 -0
- data/.gitignore +3 -2
- data/CHANGELOG.md +61 -0
- data/Gemfile.lock +140 -0
- data/MIT-LICENSE +1 -1
- data/{README.textile → README.md} +191 -168
- data/RELEASE_PROCESS +3 -1
- data/Rakefile +24 -8
- data/app/assets/stylesheets/formtastic.css +1 -1
- data/bin/appraisal +8 -0
- data/formtastic.gemspec +13 -17
- data/gemfiles/rails_6.0/Gemfile +5 -0
- data/gemfiles/rails_6.1/Gemfile +5 -0
- data/gemfiles/rails_7.0/Gemfile +5 -0
- data/gemfiles/rails_7.1/Gemfile +5 -0
- data/gemfiles/rails_edge/Gemfile +13 -0
- data/lib/formtastic/action_class_finder.rb +19 -0
- data/lib/formtastic/actions/base.rb +1 -0
- data/lib/formtastic/actions/button_action.rb +56 -53
- data/lib/formtastic/actions/buttonish.rb +1 -0
- data/lib/formtastic/actions/input_action.rb +60 -57
- data/lib/formtastic/actions/link_action.rb +69 -67
- data/lib/formtastic/actions.rb +7 -3
- data/lib/formtastic/deprecation.rb +6 -0
- data/lib/formtastic/engine.rb +4 -1
- data/lib/formtastic/form_builder.rb +32 -25
- data/lib/formtastic/helpers/action_helper.rb +22 -31
- data/lib/formtastic/helpers/actions_helper.rb +1 -0
- data/lib/formtastic/helpers/enum.rb +14 -0
- data/lib/formtastic/helpers/errors_helper.rb +3 -2
- data/lib/formtastic/helpers/fieldset_wrapper.rb +16 -11
- data/lib/formtastic/helpers/file_column_detection.rb +1 -0
- data/lib/formtastic/helpers/form_helper.rb +4 -3
- data/lib/formtastic/helpers/input_helper.rb +59 -80
- data/lib/formtastic/helpers/inputs_helper.rb +33 -27
- data/lib/formtastic/helpers/reflection.rb +5 -4
- data/lib/formtastic/helpers.rb +2 -2
- data/lib/formtastic/html_attributes.rb +13 -1
- data/lib/formtastic/i18n.rb +2 -1
- data/lib/formtastic/input_class_finder.rb +19 -0
- data/lib/formtastic/inputs/base/associations.rb +1 -0
- data/lib/formtastic/inputs/base/choices.rb +4 -3
- data/lib/formtastic/inputs/base/collections.rb +47 -11
- data/lib/formtastic/inputs/base/database.rb +8 -5
- data/lib/formtastic/inputs/base/datetime_pickerish.rb +1 -0
- data/lib/formtastic/inputs/base/errors.rb +7 -6
- data/lib/formtastic/inputs/base/fileish.rb +1 -0
- data/lib/formtastic/inputs/base/hints.rb +2 -1
- data/lib/formtastic/inputs/base/html.rb +12 -10
- data/lib/formtastic/inputs/base/labelling.rb +3 -2
- data/lib/formtastic/inputs/base/naming.rb +5 -4
- data/lib/formtastic/inputs/base/numeric.rb +1 -0
- data/lib/formtastic/inputs/base/options.rb +3 -3
- data/lib/formtastic/inputs/base/placeholder.rb +1 -0
- data/lib/formtastic/inputs/base/stringish.rb +1 -0
- data/lib/formtastic/inputs/base/timeish.rb +9 -4
- data/lib/formtastic/inputs/base/validations.rb +39 -12
- data/lib/formtastic/inputs/base/wrapping.rb +2 -3
- data/lib/formtastic/inputs/base.rb +17 -12
- data/lib/formtastic/inputs/boolean_input.rb +2 -1
- data/lib/formtastic/inputs/check_boxes_input.rb +16 -24
- data/lib/formtastic/inputs/color_input.rb +1 -1
- data/lib/formtastic/inputs/country_input.rb +4 -1
- data/lib/formtastic/inputs/datalist_input.rb +42 -0
- data/lib/formtastic/inputs/date_picker_input.rb +1 -0
- data/lib/formtastic/inputs/date_select_input.rb +1 -0
- data/lib/formtastic/inputs/datetime_picker_input.rb +1 -0
- data/lib/formtastic/inputs/datetime_select_input.rb +1 -0
- data/lib/formtastic/inputs/email_input.rb +1 -0
- data/lib/formtastic/inputs/file_input.rb +3 -2
- data/lib/formtastic/inputs/hidden_input.rb +3 -2
- data/lib/formtastic/inputs/number_input.rb +1 -0
- data/lib/formtastic/inputs/password_input.rb +1 -0
- data/lib/formtastic/inputs/phone_input.rb +1 -0
- data/lib/formtastic/inputs/radio_input.rb +26 -21
- data/lib/formtastic/inputs/range_input.rb +1 -0
- data/lib/formtastic/inputs/search_input.rb +1 -0
- data/lib/formtastic/inputs/select_input.rb +32 -10
- data/lib/formtastic/inputs/string_input.rb +1 -0
- data/lib/formtastic/inputs/text_input.rb +1 -0
- data/lib/formtastic/inputs/time_picker_input.rb +1 -0
- data/lib/formtastic/inputs/time_select_input.rb +1 -0
- data/lib/formtastic/inputs/time_zone_input.rb +17 -6
- data/lib/formtastic/inputs/url_input.rb +1 -0
- data/lib/formtastic/inputs.rb +33 -28
- data/lib/formtastic/localized_string.rb +2 -1
- data/lib/formtastic/localizer.rb +23 -24
- data/lib/formtastic/namespaced_class_finder.rb +98 -0
- data/lib/formtastic/version.rb +2 -1
- data/lib/formtastic.rb +19 -14
- data/lib/generators/formtastic/form/form_generator.rb +8 -2
- data/lib/generators/formtastic/input/input_generator.rb +47 -0
- data/lib/generators/formtastic/install/install_generator.rb +2 -0
- data/lib/generators/templates/formtastic.rb +29 -7
- data/lib/generators/templates/input.rb +19 -0
- data/sample/basic_inputs.html +1 -1
- data/script/integration-template.rb +73 -0
- data/script/integration.sh +19 -0
- data/spec/action_class_finder_spec.rb +13 -0
- data/spec/actions/button_action_spec.rb +21 -20
- data/spec/actions/generic_action_spec.rb +134 -133
- data/spec/actions/input_action_spec.rb +20 -19
- data/spec/actions/link_action_spec.rb +30 -29
- data/spec/builder/custom_builder_spec.rb +39 -22
- data/spec/builder/error_proc_spec.rb +6 -5
- data/spec/builder/semantic_fields_for_spec.rb +46 -45
- data/spec/fast_spec_helper.rb +13 -0
- data/spec/generators/formtastic/form/form_generator_spec.rb +33 -32
- data/spec/generators/formtastic/input/input_generator_spec.rb +125 -0
- data/spec/generators/formtastic/install/install_generator_spec.rb +10 -9
- data/spec/helpers/action_helper_spec.rb +70 -97
- data/spec/helpers/actions_helper_spec.rb +43 -42
- data/spec/helpers/form_helper_spec.rb +56 -39
- data/spec/helpers/input_helper_spec.rb +314 -255
- data/spec/helpers/inputs_helper_spec.rb +217 -202
- data/spec/helpers/reflection_helper_spec.rb +7 -6
- data/spec/helpers/semantic_errors_helper_spec.rb +26 -25
- data/spec/i18n_spec.rb +30 -29
- data/spec/input_class_finder_spec.rb +11 -0
- data/spec/inputs/base/collections_spec.rb +78 -0
- data/spec/inputs/base/validations_spec.rb +481 -0
- data/spec/inputs/boolean_input_spec.rb +73 -72
- data/spec/inputs/check_boxes_input_spec.rb +174 -123
- data/spec/inputs/color_input_spec.rb +53 -64
- data/spec/inputs/country_input_spec.rb +23 -22
- data/spec/inputs/custom_input_spec.rb +3 -6
- data/spec/inputs/datalist_input_spec.rb +62 -0
- data/spec/inputs/date_picker_input_spec.rb +114 -113
- data/spec/inputs/date_select_input_spec.rb +76 -61
- data/spec/inputs/datetime_picker_input_spec.rb +123 -122
- data/spec/inputs/datetime_select_input_spec.rb +85 -68
- data/spec/inputs/email_input_spec.rb +17 -16
- data/spec/inputs/file_input_spec.rb +18 -17
- data/spec/inputs/hidden_input_spec.rb +32 -31
- data/spec/inputs/include_blank_spec.rb +10 -9
- data/spec/inputs/label_spec.rb +36 -31
- data/spec/inputs/number_input_spec.rb +212 -211
- data/spec/inputs/password_input_spec.rb +17 -16
- data/spec/inputs/phone_input_spec.rb +17 -16
- data/spec/inputs/placeholder_spec.rb +18 -17
- data/spec/inputs/radio_input_spec.rb +92 -65
- data/spec/inputs/range_input_spec.rb +136 -135
- data/spec/inputs/readonly_spec.rb +51 -0
- data/spec/inputs/search_input_spec.rb +16 -15
- data/spec/inputs/select_input_spec.rb +209 -102
- data/spec/inputs/string_input_spec.rb +51 -50
- data/spec/inputs/text_input_spec.rb +34 -33
- data/spec/inputs/time_picker_input_spec.rb +115 -114
- data/spec/inputs/time_select_input_spec.rb +84 -70
- data/spec/inputs/time_zone_input_spec.rb +58 -31
- data/spec/inputs/url_input_spec.rb +17 -16
- data/spec/inputs/with_options_spec.rb +9 -8
- data/spec/localizer_spec.rb +18 -17
- data/spec/namespaced_class_finder_spec.rb +91 -0
- data/spec/schema.rb +22 -0
- data/spec/spec_helper.rb +180 -249
- data/spec/support/custom_macros.rb +128 -98
- data/spec/support/deprecation.rb +2 -1
- data/spec/support/shared_examples.rb +13 -0
- data/spec/support/specialized_class_finder_shared_example.rb +28 -0
- data/spec/support/test_environment.rb +25 -10
- metadata +95 -136
- data/.travis.yml +0 -28
- data/Appraisals +0 -25
- data/CHANGELOG +0 -27
- data/gemfiles/rails_3.2.gemfile +0 -7
- data/gemfiles/rails_4.0.4.gemfile +0 -7
- data/gemfiles/rails_4.1.gemfile +0 -7
- data/gemfiles/rails_4.gemfile +0 -7
- data/gemfiles/rails_edge.gemfile +0 -10
- data/lib/formtastic/util.rb +0 -53
- data/spec/support/deferred_garbage_collection.rb +0 -21
- data/spec/util_spec.rb +0 -52
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
require 'spec_helper'
|
|
3
4
|
|
|
4
|
-
describe '
|
|
5
|
-
|
|
6
|
-
include FormtasticSpecHelper
|
|
5
|
+
RSpec.describe 'with input class finder' do
|
|
6
|
+
include_context 'form builder'
|
|
7
7
|
|
|
8
8
|
before do
|
|
9
|
-
@output_buffer = ''
|
|
10
|
-
mock_everything
|
|
11
|
-
|
|
12
9
|
@errors = double('errors')
|
|
13
|
-
@errors.
|
|
14
|
-
@new_post.
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
after do
|
|
18
|
-
::I18n.backend.reload!
|
|
10
|
+
allow(@errors).to receive(:[]).and_return([])
|
|
11
|
+
allow(@new_post).to receive(:errors).and_return(@errors)
|
|
19
12
|
end
|
|
20
13
|
|
|
21
14
|
describe 'arguments and options' do
|
|
22
15
|
|
|
23
16
|
it 'should require the first argument (the method on form\'s object)' do
|
|
24
|
-
|
|
17
|
+
expect {
|
|
25
18
|
concat(semantic_form_for(@new_post) do |builder|
|
|
26
19
|
concat(builder.input()) # no args passed in at all
|
|
27
20
|
end)
|
|
28
|
-
}.
|
|
21
|
+
}.to raise_error(ArgumentError)
|
|
29
22
|
end
|
|
30
23
|
|
|
31
24
|
describe ':required option' do
|
|
@@ -37,8 +30,8 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
37
30
|
concat(semantic_form_for(@new_post) do |builder|
|
|
38
31
|
concat(builder.input(:title, :required => true))
|
|
39
32
|
end)
|
|
40
|
-
output_buffer.
|
|
41
|
-
output_buffer.
|
|
33
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
34
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
42
35
|
end
|
|
43
36
|
end
|
|
44
37
|
|
|
@@ -47,7 +40,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
47
40
|
concat(semantic_form_for(@new_post) do |builder|
|
|
48
41
|
concat(builder.input(:title, :required => true))
|
|
49
42
|
end)
|
|
50
|
-
output_buffer.
|
|
43
|
+
expect(output_buffer.to_str).to have_tag('form li.required label', :text => /required yo/)
|
|
51
44
|
end
|
|
52
45
|
end
|
|
53
46
|
end
|
|
@@ -56,7 +49,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
56
49
|
|
|
57
50
|
before do
|
|
58
51
|
@string = Formtastic::FormBuilder.optional_string = " optional yo!" # ensure there's something in the string
|
|
59
|
-
@new_post.class.
|
|
52
|
+
expect(@new_post.class).not_to receive(:reflect_on_all_validations)
|
|
60
53
|
end
|
|
61
54
|
|
|
62
55
|
after do
|
|
@@ -67,26 +60,26 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
67
60
|
concat(semantic_form_for(@new_post) do |builder|
|
|
68
61
|
concat(builder.input(:title, :required => false))
|
|
69
62
|
end)
|
|
70
|
-
output_buffer.
|
|
71
|
-
output_buffer.
|
|
63
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
64
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
72
65
|
end
|
|
73
66
|
|
|
74
67
|
it 'should set and "optional" class also when there is presence validator' do
|
|
75
|
-
@new_post.class.
|
|
76
|
-
|
|
77
|
-
|
|
68
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
69
|
+
active_model_presence_validator([:title])
|
|
70
|
+
])
|
|
78
71
|
concat(semantic_form_for(@new_post) do |builder|
|
|
79
72
|
concat(builder.input(:title, :required => false))
|
|
80
73
|
end)
|
|
81
|
-
output_buffer.
|
|
82
|
-
output_buffer.
|
|
74
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
75
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
83
76
|
end
|
|
84
77
|
|
|
85
78
|
it 'should append the "optional" string to the label' do
|
|
86
79
|
concat(semantic_form_for(@new_post) do |builder|
|
|
87
80
|
concat(builder.input(:title, :required => false))
|
|
88
81
|
end)
|
|
89
|
-
output_buffer.
|
|
82
|
+
expect(output_buffer.to_str).to have_tag('form li.optional label', :text => /#{@string}$/)
|
|
90
83
|
end
|
|
91
84
|
|
|
92
85
|
end
|
|
@@ -96,14 +89,14 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
96
89
|
describe 'and an object was not given' do
|
|
97
90
|
|
|
98
91
|
it 'should use the default value' do
|
|
99
|
-
Formtastic::FormBuilder.all_fields_required_by_default.
|
|
92
|
+
expect(Formtastic::FormBuilder.all_fields_required_by_default).to eq(true)
|
|
100
93
|
Formtastic::FormBuilder.all_fields_required_by_default = false
|
|
101
94
|
|
|
102
95
|
concat(semantic_form_for(:project, :url => 'http://test.host/') do |builder|
|
|
103
96
|
concat(builder.input(:title))
|
|
104
97
|
end)
|
|
105
|
-
output_buffer.
|
|
106
|
-
output_buffer.
|
|
98
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
99
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
107
100
|
|
|
108
101
|
Formtastic::FormBuilder.all_fields_required_by_default = true
|
|
109
102
|
end
|
|
@@ -112,90 +105,151 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
112
105
|
|
|
113
106
|
describe 'and an object with :validators_on was given (ActiveModel, Active Resource)' do
|
|
114
107
|
before do
|
|
115
|
-
@new_post.
|
|
108
|
+
allow(@new_post).to receive(:class).and_return(::PostModel)
|
|
116
109
|
end
|
|
117
110
|
|
|
118
111
|
after do
|
|
119
|
-
@new_post.
|
|
112
|
+
allow(@new_post).to receive(:class).and_return(::Post)
|
|
120
113
|
end
|
|
121
114
|
describe 'and validates_presence_of was called for the method' do
|
|
122
115
|
it 'should be required' do
|
|
123
116
|
|
|
124
|
-
@new_post.class.
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
118
|
+
active_model_presence_validator([:title])
|
|
119
|
+
])
|
|
127
120
|
|
|
128
|
-
@new_post.class.
|
|
129
|
-
|
|
130
|
-
|
|
121
|
+
expect(@new_post.class).to receive(:validators_on).with(:body).at_least(:once).and_return([
|
|
122
|
+
active_model_presence_validator([:body], {:if => true})
|
|
123
|
+
])
|
|
131
124
|
|
|
132
125
|
concat(semantic_form_for(@new_post) do |builder|
|
|
133
126
|
concat(builder.input(:title))
|
|
134
127
|
concat(builder.input(:body))
|
|
135
128
|
end)
|
|
136
|
-
output_buffer.
|
|
137
|
-
output_buffer.
|
|
129
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
130
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
138
131
|
end
|
|
139
132
|
|
|
140
133
|
it 'should be required when there is :on => :create option on create' do
|
|
141
134
|
with_config :required_string, " required yo!" do
|
|
142
|
-
@new_post.class.
|
|
143
|
-
|
|
144
|
-
|
|
135
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
136
|
+
active_model_presence_validator([:title], {:on => :create})
|
|
137
|
+
])
|
|
138
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
139
|
+
concat(builder.input(:title))
|
|
140
|
+
end)
|
|
141
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
142
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
it 'should be required when there is :create option in validation contexts array on create' do
|
|
147
|
+
with_config :required_string, " required yo!" do
|
|
148
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
149
|
+
active_model_presence_validator([:title], {:on => [:create]})
|
|
150
|
+
])
|
|
145
151
|
concat(semantic_form_for(@new_post) do |builder|
|
|
146
152
|
concat(builder.input(:title))
|
|
147
153
|
end)
|
|
148
|
-
output_buffer.
|
|
149
|
-
output_buffer.
|
|
154
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
155
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
150
156
|
end
|
|
151
157
|
end
|
|
152
158
|
|
|
153
159
|
it 'should be required when there is :on => :save option on create' do
|
|
154
160
|
with_config :required_string, " required yo!" do
|
|
155
|
-
@new_post.class.
|
|
156
|
-
|
|
157
|
-
|
|
161
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
162
|
+
active_model_presence_validator([:title], {:on => :save})
|
|
163
|
+
])
|
|
164
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
165
|
+
concat(builder.input(:title))
|
|
166
|
+
end)
|
|
167
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
168
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
it 'should be required when there is :save option in validation contexts array on create' do
|
|
173
|
+
with_config :required_string, " required yo!" do
|
|
174
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
175
|
+
active_model_presence_validator([:title], {:on => [:save]})
|
|
176
|
+
])
|
|
158
177
|
concat(semantic_form_for(@new_post) do |builder|
|
|
159
178
|
concat(builder.input(:title))
|
|
160
179
|
end)
|
|
161
|
-
output_buffer.
|
|
162
|
-
output_buffer.
|
|
180
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
181
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
163
182
|
end
|
|
164
183
|
end
|
|
165
184
|
|
|
166
185
|
it 'should be required when there is :on => :save option on update' do
|
|
167
186
|
with_config :required_string, " required yo!" do
|
|
168
|
-
@fred.class.
|
|
169
|
-
|
|
170
|
-
|
|
187
|
+
expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
|
|
188
|
+
active_model_presence_validator([:login], {:on => :save})
|
|
189
|
+
])
|
|
171
190
|
concat(semantic_form_for(@fred) do |builder|
|
|
172
191
|
concat(builder.input(:login))
|
|
173
192
|
end)
|
|
174
|
-
output_buffer.
|
|
175
|
-
output_buffer.
|
|
193
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
194
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
it 'should be required when there is :save option in validation contexts array on update' do
|
|
199
|
+
with_config :required_string, " required yo!" do
|
|
200
|
+
expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
|
|
201
|
+
active_model_presence_validator([:login], {:on => [:save]})
|
|
202
|
+
])
|
|
203
|
+
concat(semantic_form_for(@fred) do |builder|
|
|
204
|
+
concat(builder.input(:login))
|
|
205
|
+
end)
|
|
206
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
207
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
176
208
|
end
|
|
177
209
|
end
|
|
178
210
|
|
|
179
211
|
it 'should not be required when there is :on => :create option on update' do
|
|
180
|
-
@fred.class.
|
|
181
|
-
|
|
182
|
-
|
|
212
|
+
expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
|
|
213
|
+
active_model_presence_validator([:login], {:on => :create})
|
|
214
|
+
])
|
|
215
|
+
concat(semantic_form_for(@fred) do |builder|
|
|
216
|
+
concat(builder.input(:login))
|
|
217
|
+
end)
|
|
218
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
219
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it 'should not be required when there is :create option in validation contexts array on update' do
|
|
223
|
+
expect(@fred.class).to receive(:validators_on).with(:login).at_least(:once).and_return([
|
|
224
|
+
active_model_presence_validator([:login], {:on => [:create]})
|
|
225
|
+
])
|
|
183
226
|
concat(semantic_form_for(@fred) do |builder|
|
|
184
227
|
concat(builder.input(:login))
|
|
185
228
|
end)
|
|
186
|
-
output_buffer.
|
|
187
|
-
output_buffer.
|
|
229
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
230
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
188
231
|
end
|
|
189
232
|
|
|
190
233
|
it 'should not be required when there is :on => :update option on create' do
|
|
191
|
-
@new_post.class.
|
|
192
|
-
|
|
193
|
-
|
|
234
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
235
|
+
active_model_presence_validator([:title], {:on => :update})
|
|
236
|
+
])
|
|
194
237
|
concat(semantic_form_for(@new_post) do |builder|
|
|
195
238
|
concat(builder.input(:title))
|
|
196
239
|
end)
|
|
197
|
-
output_buffer.
|
|
198
|
-
output_buffer.
|
|
240
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
241
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
it 'should not be required when there is :update option in validation contexts array on create' do
|
|
245
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).at_least(:once).and_return([
|
|
246
|
+
active_model_presence_validator([:title], {:on => [:update]})
|
|
247
|
+
])
|
|
248
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
249
|
+
concat(builder.input(:title))
|
|
250
|
+
end)
|
|
251
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
252
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
199
253
|
end
|
|
200
254
|
|
|
201
255
|
it 'should be not be required if the optional :if condition is not satisifed' do
|
|
@@ -219,38 +273,38 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
219
273
|
end
|
|
220
274
|
|
|
221
275
|
it 'should be required if the optional :if with a method string evaluates to true' do
|
|
222
|
-
@new_post.
|
|
276
|
+
expect(@new_post).to receive(:required_condition).and_return(true)
|
|
223
277
|
presence_should_be_required(:required => true, :tag => :body, :options => { :if => :required_condition })
|
|
224
278
|
end
|
|
225
279
|
|
|
226
280
|
it 'should be required if the optional :if with a method string evaluates to false' do
|
|
227
|
-
@new_post.
|
|
281
|
+
expect(@new_post).to receive(:required_condition).and_return(false)
|
|
228
282
|
presence_should_be_required(:required => false, :tag => :body, :options => { :if => :required_condition })
|
|
229
283
|
end
|
|
230
284
|
|
|
231
285
|
it 'should be required if the optional :unless with a method string evaluates to false' do
|
|
232
|
-
|
|
286
|
+
expect(@new_post).to receive(:required_condition).and_return(false)
|
|
233
287
|
presence_should_be_required(:required => true, :tag => :body, :options => { :unless => :required_condition })
|
|
234
288
|
end
|
|
235
289
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
290
|
+
it 'should not be required if the optional :unless with a method string evaluates to true' do
|
|
291
|
+
expect(@new_post).to receive(:required_condition).and_return(true)
|
|
292
|
+
presence_should_be_required(:required => false, :tag => :body, :options => { :unless => :required_condition })
|
|
293
|
+
end
|
|
240
294
|
end
|
|
241
295
|
|
|
242
296
|
describe 'and validates_inclusion_of was called for the method' do
|
|
243
297
|
it 'should be required' do
|
|
244
|
-
@new_post.class.
|
|
245
|
-
|
|
246
|
-
|
|
298
|
+
expect(@new_post.class).to receive(:validators_on).with(:published).at_least(:once).and_return([
|
|
299
|
+
active_model_inclusion_validator([:published], {:in => [false, true]})
|
|
300
|
+
])
|
|
247
301
|
should_be_required(:tag => :published, :required => true)
|
|
248
302
|
end
|
|
249
303
|
|
|
250
304
|
it 'should not be required if allow_blank is true' do
|
|
251
|
-
@new_post.class.
|
|
252
|
-
|
|
253
|
-
|
|
305
|
+
expect(@new_post.class).to receive(:validators_on).with(:published).at_least(:once).and_return([
|
|
306
|
+
active_model_inclusion_validator([:published], {:in => [false, true], :allow_blank => true})
|
|
307
|
+
])
|
|
254
308
|
should_be_required(:tag => :published, :required => false)
|
|
255
309
|
end
|
|
256
310
|
end
|
|
@@ -282,14 +336,14 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
282
336
|
end
|
|
283
337
|
|
|
284
338
|
def add_presence_validator(options)
|
|
285
|
-
@new_post.class.
|
|
286
|
-
|
|
287
|
-
|
|
339
|
+
allow(@new_post.class).to receive(:validators_on).with(options[:tag]).and_return([
|
|
340
|
+
active_model_presence_validator([options[:tag]], options[:options])
|
|
341
|
+
])
|
|
288
342
|
end
|
|
289
343
|
|
|
290
344
|
def add_length_validator(options)
|
|
291
|
-
@new_post.class.
|
|
292
|
-
|
|
345
|
+
expect(@new_post.class).to receive(:validators_on).with(options[:tag]).at_least(:once) {[
|
|
346
|
+
active_model_length_validator([options[:tag]], options[:options])
|
|
293
347
|
]}
|
|
294
348
|
end
|
|
295
349
|
|
|
@@ -300,11 +354,11 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
300
354
|
end)
|
|
301
355
|
|
|
302
356
|
if options[:required]
|
|
303
|
-
output_buffer.
|
|
304
|
-
output_buffer.
|
|
357
|
+
expect(output_buffer.to_str).not_to have_tag('form li.optional')
|
|
358
|
+
expect(output_buffer.to_str).to have_tag('form li.required')
|
|
305
359
|
else
|
|
306
|
-
output_buffer.
|
|
307
|
-
output_buffer.
|
|
360
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
361
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
308
362
|
end
|
|
309
363
|
end
|
|
310
364
|
|
|
@@ -321,15 +375,15 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
321
375
|
# TODO JF reversed this during refactor, need to make sure
|
|
322
376
|
describe 'and there are no requirement validations on the method' do
|
|
323
377
|
before do
|
|
324
|
-
@new_post.class.
|
|
378
|
+
expect(@new_post.class).to receive(:validators_on).with(:title).and_return([])
|
|
325
379
|
end
|
|
326
380
|
|
|
327
381
|
it 'should not be required' do
|
|
328
382
|
concat(semantic_form_for(@new_post) do |builder|
|
|
329
383
|
concat(builder.input(:title))
|
|
330
384
|
end)
|
|
331
|
-
output_buffer.
|
|
332
|
-
output_buffer.
|
|
385
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
386
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
333
387
|
end
|
|
334
388
|
end
|
|
335
389
|
|
|
@@ -337,21 +391,21 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
337
391
|
|
|
338
392
|
describe 'and an object without :validators_on' do
|
|
339
393
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
concat(semantic_form_for(@new_post) do |builder|
|
|
345
|
-
concat(builder.input(:title))
|
|
346
|
-
end)
|
|
347
|
-
output_buffer.should_not have_tag('form li.required')
|
|
348
|
-
output_buffer.should have_tag('form li.optional')
|
|
394
|
+
it 'should use the default value' do
|
|
395
|
+
expect(Formtastic::FormBuilder.all_fields_required_by_default).to eq(true)
|
|
396
|
+
Formtastic::FormBuilder.all_fields_required_by_default = false
|
|
349
397
|
|
|
350
|
-
|
|
351
|
-
|
|
398
|
+
concat(semantic_form_for(@new_post) do |builder|
|
|
399
|
+
concat(builder.input(:title))
|
|
400
|
+
end)
|
|
401
|
+
expect(output_buffer.to_str).not_to have_tag('form li.required')
|
|
402
|
+
expect(output_buffer.to_str).to have_tag('form li.optional')
|
|
352
403
|
|
|
404
|
+
Formtastic::FormBuilder.all_fields_required_by_default = true
|
|
353
405
|
end
|
|
354
406
|
|
|
407
|
+
end
|
|
408
|
+
|
|
355
409
|
end
|
|
356
410
|
|
|
357
411
|
end
|
|
@@ -364,7 +418,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
364
418
|
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
365
419
|
concat(builder.input(:anything))
|
|
366
420
|
end)
|
|
367
|
-
output_buffer.
|
|
421
|
+
expect(output_buffer.to_str).to have_tag('form li.string')
|
|
368
422
|
end
|
|
369
423
|
|
|
370
424
|
it 'should default to password for forms without objects if column is password' do
|
|
@@ -373,107 +427,129 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
373
427
|
concat(builder.input(:password_confirmation))
|
|
374
428
|
concat(builder.input(:confirm_password))
|
|
375
429
|
end)
|
|
376
|
-
output_buffer.
|
|
430
|
+
expect(output_buffer.to_str).to have_tag('form li.password', :count => 3)
|
|
377
431
|
end
|
|
378
432
|
|
|
379
433
|
it 'should default to a string for methods on objects that don\'t respond to "column_for_attribute"' do
|
|
380
|
-
@new_post.
|
|
381
|
-
@new_post.
|
|
382
|
-
default_input_type(nil, :method_without_a_database_column).
|
|
434
|
+
allow(@new_post).to receive(:method_without_a_database_column)
|
|
435
|
+
allow(@new_post).to receive(:column_for_attribute).and_return(nil)
|
|
436
|
+
expect(default_input_type(nil, :method_without_a_database_column)).to eq(:string)
|
|
383
437
|
end
|
|
384
438
|
|
|
385
439
|
it 'should default to :password for methods that don\'t have a column in the database but "password" is in the method name' do
|
|
386
|
-
@new_post.
|
|
387
|
-
@new_post.
|
|
388
|
-
default_input_type(nil, :password_method_without_a_database_column).
|
|
440
|
+
allow(@new_post).to receive(:password_method_without_a_database_column)
|
|
441
|
+
allow(@new_post).to receive(:column_for_attribute).and_return(nil)
|
|
442
|
+
expect(default_input_type(nil, :password_method_without_a_database_column)).to eq(:password)
|
|
389
443
|
end
|
|
390
444
|
|
|
391
445
|
it 'should default to :password for methods on objects that don\'t respond to "column_for_attribute" but "password" is in the method name' do
|
|
392
|
-
@new_post.
|
|
393
|
-
@new_post.
|
|
394
|
-
default_input_type(nil, :password_method_without_a_database_column).
|
|
446
|
+
allow(@new_post).to receive(:password_method_without_a_database_column)
|
|
447
|
+
allow(@new_post).to receive(:column_for_attribute).and_return(nil)
|
|
448
|
+
expect(default_input_type(nil, :password_method_without_a_database_column)).to eq(:password)
|
|
395
449
|
end
|
|
396
450
|
|
|
397
451
|
it 'should default to :number for "integer" column with name ending in "_id"' do
|
|
398
|
-
@new_post.
|
|
399
|
-
@new_post.
|
|
400
|
-
default_input_type(:integer, :aws_instance_id).
|
|
452
|
+
allow(@new_post).to receive(:aws_instance_id)
|
|
453
|
+
allow(@new_post).to receive(:column_for_attribute).with(:aws_instance_id).and_return(double('column', :type => :integer))
|
|
454
|
+
expect(default_input_type(:integer, :aws_instance_id)).to eq(:number)
|
|
401
455
|
end
|
|
402
456
|
|
|
403
457
|
it 'should default to :select for associations' do
|
|
404
|
-
@new_post.class.
|
|
405
|
-
@new_post.class.
|
|
406
|
-
default_input_type(:integer, :user_id).
|
|
407
|
-
default_input_type(:integer, :section_id).
|
|
458
|
+
allow(@new_post.class).to receive(:reflect_on_association).with(:user_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
|
|
459
|
+
allow(@new_post.class).to receive(:reflect_on_association).with(:section_id).and_return(double('ActiveRecord::Reflection::AssociationReflection'))
|
|
460
|
+
expect(default_input_type(:integer, :user_id)).to eq(:select)
|
|
461
|
+
expect(default_input_type(:integer, :section_id)).to eq(:select)
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it 'should default to :select for enum' do
|
|
465
|
+
statuses = ActiveSupport::HashWithIndifferentAccess.new("active"=>0, "inactive"=>1)
|
|
466
|
+
allow(@new_post.class).to receive(:statuses) { statuses }
|
|
467
|
+
allow(@new_post).to receive(:defined_enums) { {"status" => statuses } }
|
|
468
|
+
|
|
469
|
+
expect(default_input_type(:integer, :status)).to eq(:select)
|
|
408
470
|
end
|
|
409
471
|
|
|
410
472
|
it 'should default to :password for :string column types with "password" in the method name' do
|
|
411
|
-
default_input_type(:string, :password).
|
|
412
|
-
default_input_type(:string, :hashed_password).
|
|
413
|
-
default_input_type(:string, :password_hash).
|
|
473
|
+
expect(default_input_type(:string, :password)).to eq(:password)
|
|
474
|
+
expect(default_input_type(:string, :hashed_password)).to eq(:password)
|
|
475
|
+
expect(default_input_type(:string, :password_hash)).to eq(:password)
|
|
414
476
|
end
|
|
415
477
|
|
|
416
478
|
it 'should default to :text for :text column types' do
|
|
417
|
-
default_input_type(:text).
|
|
479
|
+
expect(default_input_type(:text)).to eq(:text)
|
|
418
480
|
end
|
|
419
481
|
|
|
420
482
|
it 'should default to :date_select for :date column types' do
|
|
421
|
-
default_input_type(:date).
|
|
483
|
+
expect(default_input_type(:date)).to eq(:date_select)
|
|
484
|
+
end
|
|
485
|
+
|
|
486
|
+
it 'should default to :text for :hstore, :json and :jsonb column types' do
|
|
487
|
+
expect(default_input_type(:hstore)).to eq(:text)
|
|
488
|
+
expect(default_input_type(:json)).to eq(:text)
|
|
489
|
+
expect(default_input_type(:jsonb)).to eq(:text)
|
|
422
490
|
end
|
|
423
491
|
|
|
424
492
|
it 'should default to :datetime_select for :datetime and :timestamp column types' do
|
|
425
|
-
default_input_type(:datetime).
|
|
426
|
-
default_input_type(:timestamp).
|
|
493
|
+
expect(default_input_type(:datetime)).to eq(:datetime_select)
|
|
494
|
+
expect(default_input_type(:timestamp)).to eq(:datetime_select)
|
|
427
495
|
end
|
|
428
496
|
|
|
429
497
|
it 'should default to :time_select for :time column types' do
|
|
430
|
-
default_input_type(:time).
|
|
498
|
+
expect(default_input_type(:time)).to eq(:time_select)
|
|
431
499
|
end
|
|
432
500
|
|
|
433
501
|
it 'should default to :boolean for :boolean column types' do
|
|
434
|
-
default_input_type(:boolean).
|
|
502
|
+
expect(default_input_type(:boolean)).to eq(:boolean)
|
|
435
503
|
end
|
|
436
504
|
|
|
437
505
|
it 'should default to :string for :string column types' do
|
|
438
|
-
default_input_type(:string).
|
|
506
|
+
expect(default_input_type(:string)).to eq(:string)
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
it 'should default to :string for :citext column types' do
|
|
510
|
+
expect(default_input_type(:citext)).to eq(:string)
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
it 'should default to :string for :inet column types' do
|
|
514
|
+
expect(default_input_type(:inet)).to eq(:string)
|
|
439
515
|
end
|
|
440
516
|
|
|
441
517
|
it 'should default to :number for :integer, :float and :decimal column types' do
|
|
442
|
-
default_input_type(:integer).
|
|
443
|
-
default_input_type(:float).
|
|
444
|
-
default_input_type(:decimal).
|
|
518
|
+
expect(default_input_type(:integer)).to eq(:number)
|
|
519
|
+
expect(default_input_type(:float)).to eq(:number)
|
|
520
|
+
expect(default_input_type(:decimal)).to eq(:number)
|
|
445
521
|
end
|
|
446
522
|
|
|
447
523
|
it 'should default to :country for :string columns named country' do
|
|
448
|
-
default_input_type(:string, :country).
|
|
524
|
+
expect(default_input_type(:string, :country)).to eq(:country)
|
|
449
525
|
end
|
|
450
526
|
|
|
451
527
|
it 'should default to :email for :string columns matching email' do
|
|
452
|
-
default_input_type(:string, :email).
|
|
453
|
-
default_input_type(:string, :customer_email).
|
|
454
|
-
default_input_type(:string, :email_work).
|
|
528
|
+
expect(default_input_type(:string, :email)).to eq(:email)
|
|
529
|
+
expect(default_input_type(:string, :customer_email)).to eq(:email)
|
|
530
|
+
expect(default_input_type(:string, :email_work)).to eq(:email)
|
|
455
531
|
end
|
|
456
532
|
|
|
457
533
|
it 'should default to :url for :string columns named url or website' do
|
|
458
|
-
default_input_type(:string, :url).
|
|
459
|
-
default_input_type(:string, :website).
|
|
460
|
-
default_input_type(:string, :my_url).
|
|
461
|
-
default_input_type(:string, :hurl).
|
|
534
|
+
expect(default_input_type(:string, :url)).to eq(:url)
|
|
535
|
+
expect(default_input_type(:string, :website)).to eq(:url)
|
|
536
|
+
expect(default_input_type(:string, :my_url)).to eq(:url)
|
|
537
|
+
expect(default_input_type(:string, :hurl)).not_to eq(:url)
|
|
462
538
|
end
|
|
463
539
|
|
|
464
540
|
it 'should default to :phone for :string columns named phone or fax' do
|
|
465
|
-
default_input_type(:string, :phone).
|
|
466
|
-
default_input_type(:string, :fax).
|
|
541
|
+
expect(default_input_type(:string, :phone)).to eq(:phone)
|
|
542
|
+
expect(default_input_type(:string, :fax)).to eq(:phone)
|
|
467
543
|
end
|
|
468
544
|
|
|
469
545
|
it 'should default to :search for :string columns named search' do
|
|
470
|
-
default_input_type(:string, :search).
|
|
546
|
+
expect(default_input_type(:string, :search)).to eq(:search)
|
|
471
547
|
end
|
|
472
548
|
|
|
473
549
|
it 'should default to :color for :string columns matching color' do
|
|
474
|
-
default_input_type(:string, :color).
|
|
475
|
-
default_input_type(:string, :user_color).
|
|
476
|
-
default_input_type(:string, :color_for_image).
|
|
550
|
+
expect(default_input_type(:string, :color)).to eq(:color)
|
|
551
|
+
expect(default_input_type(:string, :user_color)).to eq(:color)
|
|
552
|
+
expect(default_input_type(:string, :color_for_image)).to eq(:color)
|
|
477
553
|
end
|
|
478
554
|
|
|
479
555
|
describe 'defaulting to file column' do
|
|
@@ -483,13 +559,13 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
483
559
|
|
|
484
560
|
Formtastic::FormBuilder.file_methods.each do |test|
|
|
485
561
|
### TODO: Check if this is ok
|
|
486
|
-
column.
|
|
562
|
+
allow(column).to receive(method).with(test).and_return(method == test)
|
|
487
563
|
end
|
|
488
564
|
|
|
489
|
-
@new_post.
|
|
565
|
+
expect(@new_post).to receive(method).and_return(column)
|
|
490
566
|
|
|
491
567
|
semantic_form_for(@new_post) do |builder|
|
|
492
|
-
builder.send(:default_input_type, method).
|
|
568
|
+
expect(builder.send(:default_input_type, method)).to eq(:file)
|
|
493
569
|
end
|
|
494
570
|
end
|
|
495
571
|
end
|
|
@@ -499,15 +575,15 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
499
575
|
|
|
500
576
|
it 'should call the corresponding input class with .to_html' do
|
|
501
577
|
[:select, :time_zone, :radio, :date_select, :datetime_select, :time_select, :boolean, :check_boxes, :hidden, :string, :password, :number, :text, :file].each do |input_style|
|
|
502
|
-
@new_post.
|
|
503
|
-
@new_post.
|
|
578
|
+
allow(@new_post).to receive(:generic_column_name)
|
|
579
|
+
allow(@new_post).to receive(:column_for_attribute).and_return(double('column', :type => :string, :limit => 255))
|
|
504
580
|
semantic_form_for(@new_post) do |builder|
|
|
505
581
|
input_instance = double('Input instance')
|
|
506
582
|
input_class = "#{input_style.to_s}_input".classify
|
|
507
583
|
input_constant = "Formtastic::Inputs::#{input_class}".constantize
|
|
508
584
|
|
|
509
|
-
input_constant.
|
|
510
|
-
input_instance.
|
|
585
|
+
expect(input_constant).to receive(:new).and_return(input_instance)
|
|
586
|
+
expect(input_instance).to receive(:to_html).and_return("some HTML")
|
|
511
587
|
|
|
512
588
|
concat(builder.input(:generic_column_name, :as => input_style))
|
|
513
589
|
end
|
|
@@ -523,21 +599,21 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
523
599
|
concat(semantic_form_for(@new_post) do |builder|
|
|
524
600
|
concat(builder.input(:title, :label => "Kustom"))
|
|
525
601
|
end)
|
|
526
|
-
output_buffer.
|
|
602
|
+
expect(output_buffer.to_str).to have_tag("form li label", :text => /Kustom/)
|
|
527
603
|
end
|
|
528
604
|
|
|
529
605
|
it 'should not generate a label if false' do
|
|
530
606
|
concat(semantic_form_for(@new_post) do |builder|
|
|
531
607
|
concat(builder.input(:title, :label => false))
|
|
532
608
|
end)
|
|
533
|
-
output_buffer.
|
|
609
|
+
expect(output_buffer.to_str).not_to have_tag("form li label")
|
|
534
610
|
end
|
|
535
611
|
|
|
536
612
|
it 'should be dupped if frozen' do
|
|
537
613
|
concat(semantic_form_for(@new_post) do |builder|
|
|
538
614
|
concat(builder.input(:title, :label => "Kustom".freeze))
|
|
539
615
|
end)
|
|
540
|
-
output_buffer.
|
|
616
|
+
expect(output_buffer.to_str).to have_tag("form li label", :text => /Kustom/)
|
|
541
617
|
end
|
|
542
618
|
end
|
|
543
619
|
|
|
@@ -548,18 +624,18 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
548
624
|
it 'should render a label with localized text and not apply the label_str_method' do
|
|
549
625
|
with_config :label_str_method, :reverse do
|
|
550
626
|
@localized_label_text = 'Localized title'
|
|
551
|
-
@new_post.
|
|
627
|
+
allow(@new_post).to receive(:meta_description)
|
|
552
628
|
::I18n.backend.store_translations :en,
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
629
|
+
:formtastic => {
|
|
630
|
+
:labels => {
|
|
631
|
+
:meta_description => @localized_label_text
|
|
632
|
+
}
|
|
633
|
+
}
|
|
558
634
|
|
|
559
635
|
concat(semantic_form_for(@new_post) do |builder|
|
|
560
636
|
concat(builder.input(:meta_description))
|
|
561
637
|
end)
|
|
562
|
-
output_buffer.
|
|
638
|
+
expect(output_buffer.to_str).to have_tag('form li label', :text => /Localized title/)
|
|
563
639
|
end
|
|
564
640
|
end
|
|
565
641
|
end
|
|
@@ -574,32 +650,32 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
574
650
|
concat(semantic_form_for(:project, :url => 'http://test.host') do |builder|
|
|
575
651
|
concat(builder.input(:meta_description))
|
|
576
652
|
end)
|
|
577
|
-
output_buffer.
|
|
653
|
+
expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.humanize}/)
|
|
578
654
|
end
|
|
579
655
|
end
|
|
580
656
|
end
|
|
581
657
|
|
|
582
658
|
describe 'and object is given' do
|
|
583
659
|
it 'should delegate the label logic to class human attribute name and pass it down to the label tag' do
|
|
584
|
-
@new_post.
|
|
585
|
-
@new_post.class.
|
|
660
|
+
allow(@new_post).to receive(:meta_description) # a two word method name
|
|
661
|
+
expect(@new_post.class).to receive(:human_attribute_name).with('meta_description').and_return('meta_description'.humanize)
|
|
586
662
|
|
|
587
663
|
concat(semantic_form_for(@new_post) do |builder|
|
|
588
664
|
concat(builder.input(:meta_description))
|
|
589
665
|
end)
|
|
590
|
-
output_buffer.
|
|
666
|
+
expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.humanize}/)
|
|
591
667
|
end
|
|
592
668
|
end
|
|
593
669
|
|
|
594
670
|
describe 'and object is given with label_str_method set to :capitalize' do
|
|
595
671
|
it 'should capitalize method name, passing it down to the label tag' do
|
|
596
672
|
with_config :label_str_method, :capitalize do
|
|
597
|
-
@new_post.
|
|
673
|
+
allow(@new_post).to receive(:meta_description)
|
|
598
674
|
|
|
599
675
|
concat(semantic_form_for(@new_post) do |builder|
|
|
600
676
|
concat(builder.input(:meta_description))
|
|
601
677
|
end)
|
|
602
|
-
output_buffer.
|
|
678
|
+
expect(output_buffer.to_str).to have_tag("form li label", :text => /#{'meta_description'.capitalize}/)
|
|
603
679
|
end
|
|
604
680
|
end
|
|
605
681
|
end
|
|
@@ -610,16 +686,16 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
610
686
|
@localized_label_text = 'Localized title'
|
|
611
687
|
@default_localized_label_text = 'Default localized title'
|
|
612
688
|
::I18n.backend.store_translations :en,
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
689
|
+
:formtastic => {
|
|
690
|
+
:labels => {
|
|
691
|
+
:title => @default_localized_label_text,
|
|
692
|
+
:published => @default_localized_label_text,
|
|
693
|
+
:post => {
|
|
694
|
+
:title => @localized_label_text,
|
|
695
|
+
:published => @default_localized_label_text
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
623
699
|
end
|
|
624
700
|
|
|
625
701
|
it 'should render a label with localized label (I18n)' do
|
|
@@ -628,26 +704,26 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
628
704
|
concat(builder.input(:title, :label => true))
|
|
629
705
|
concat(builder.input(:published, :as => :boolean, :label => true))
|
|
630
706
|
end)
|
|
631
|
-
output_buffer.
|
|
707
|
+
expect(output_buffer.to_str).to have_tag('form li label', :text => Regexp.new('^' + @localized_label_text))
|
|
632
708
|
end
|
|
633
709
|
end
|
|
634
710
|
|
|
635
711
|
it 'should render a hint paragraph containing an optional localized label (I18n) if first is not set' do
|
|
636
712
|
with_config :i18n_lookups_by_default, false do
|
|
637
713
|
::I18n.backend.store_translations :en,
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
714
|
+
:formtastic => {
|
|
715
|
+
:labels => {
|
|
716
|
+
:post => {
|
|
717
|
+
:title => nil,
|
|
718
|
+
:published => nil
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
646
722
|
concat(semantic_form_for(@new_post) do |builder|
|
|
647
723
|
concat(builder.input(:title, :label => true))
|
|
648
724
|
concat(builder.input(:published, :as => :boolean, :label => true))
|
|
649
725
|
end)
|
|
650
|
-
output_buffer.
|
|
726
|
+
expect(output_buffer.to_str).to have_tag('form li label', :text => Regexp.new('^' + @default_localized_label_text))
|
|
651
727
|
end
|
|
652
728
|
end
|
|
653
729
|
end
|
|
@@ -668,7 +744,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
668
744
|
concat(semantic_form_for(@new_post) do |builder|
|
|
669
745
|
concat(builder.input(:title, :hint => hint_text))
|
|
670
746
|
end)
|
|
671
|
-
output_buffer.
|
|
747
|
+
expect(output_buffer.to_str).to have_tag("form li p.inline-hints", :text => hint_text)
|
|
672
748
|
end
|
|
673
749
|
|
|
674
750
|
it 'should have a custom hint class defaulted for all forms' do
|
|
@@ -677,7 +753,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
677
753
|
concat(semantic_form_for(@new_post) do |builder|
|
|
678
754
|
concat(builder.input(:title, :hint => hint_text))
|
|
679
755
|
end)
|
|
680
|
-
output_buffer.
|
|
756
|
+
expect(output_buffer.to_str).to have_tag("form li p.custom-hint-class", :text => hint_text)
|
|
681
757
|
end
|
|
682
758
|
end
|
|
683
759
|
|
|
@@ -687,11 +763,11 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
687
763
|
@localized_hint_text = "This is the localized hint."
|
|
688
764
|
@default_localized_hint_text = "This is the default localized hint."
|
|
689
765
|
::I18n.backend.store_translations :en,
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
766
|
+
:formtastic => {
|
|
767
|
+
:hints => {
|
|
768
|
+
:title => @default_localized_hint_text,
|
|
769
|
+
}
|
|
770
|
+
}
|
|
695
771
|
end
|
|
696
772
|
|
|
697
773
|
after do
|
|
@@ -702,17 +778,17 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
702
778
|
it 'should render a hint paragraph containing a localized hint (I18n)' do
|
|
703
779
|
with_config :i18n_lookups_by_default, false do
|
|
704
780
|
::I18n.backend.store_translations :en,
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
781
|
+
:formtastic => {
|
|
782
|
+
:hints => {
|
|
783
|
+
:post => {
|
|
784
|
+
:title => @localized_hint_text
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
}
|
|
712
788
|
concat(semantic_form_for(@new_post) do |builder|
|
|
713
789
|
concat(builder.input(:title, :hint => true))
|
|
714
790
|
end)
|
|
715
|
-
output_buffer.
|
|
791
|
+
expect(output_buffer.to_str).to have_tag('form li p.inline-hints', :text => @localized_hint_text)
|
|
716
792
|
end
|
|
717
793
|
end
|
|
718
794
|
|
|
@@ -721,7 +797,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
721
797
|
concat(semantic_form_for(@new_post) do |builder|
|
|
722
798
|
concat(builder.input(:title, :hint => true))
|
|
723
799
|
end)
|
|
724
|
-
output_buffer.
|
|
800
|
+
expect(output_buffer.to_str).to have_tag('form li p.inline-hints', :text => @default_localized_hint_text)
|
|
725
801
|
end
|
|
726
802
|
end
|
|
727
803
|
end
|
|
@@ -732,7 +808,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
732
808
|
concat(semantic_form_for(@new_post) do |builder|
|
|
733
809
|
concat(builder.input(:title, :hint => false))
|
|
734
810
|
end)
|
|
735
|
-
output_buffer.
|
|
811
|
+
expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints', :text => @localized_hint_text)
|
|
736
812
|
end
|
|
737
813
|
end
|
|
738
814
|
end
|
|
@@ -742,17 +818,17 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
742
818
|
it "should see the provided hash as a blank entry" do
|
|
743
819
|
with_config :i18n_lookups_by_default, false do
|
|
744
820
|
::I18n.backend.store_translations :en,
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
821
|
+
:formtastic => {
|
|
822
|
+
:hints => {
|
|
823
|
+
:title => { # movie title
|
|
824
|
+
:summary => @localized_hint_text # summary of movie
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
}
|
|
752
828
|
semantic_form_for(@new_post) do |builder|
|
|
753
829
|
concat(builder.input(:title, :hint => true))
|
|
754
830
|
end
|
|
755
|
-
output_buffer.
|
|
831
|
+
expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints', :text => @localized_hint_text)
|
|
756
832
|
end
|
|
757
833
|
end
|
|
758
834
|
end
|
|
@@ -763,7 +839,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
763
839
|
concat(semantic_form_for(@new_post) do |builder|
|
|
764
840
|
concat(builder.input(:title))
|
|
765
841
|
end)
|
|
766
|
-
output_buffer.
|
|
842
|
+
expect(output_buffer.to_str).not_to have_tag('form li p.inline-hints')
|
|
767
843
|
end
|
|
768
844
|
end
|
|
769
845
|
end
|
|
@@ -778,25 +854,25 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
778
854
|
concat(semantic_form_for(@new_post) do |builder|
|
|
779
855
|
concat(builder.input(:title, :wrapper_html => {:id => :another_id}))
|
|
780
856
|
end)
|
|
781
|
-
output_buffer.
|
|
857
|
+
expect(output_buffer.to_str).to have_tag("form li#another_id")
|
|
782
858
|
end
|
|
783
859
|
|
|
784
860
|
it 'should append given classes to li default classes' do
|
|
785
861
|
concat(semantic_form_for(@new_post) do |builder|
|
|
786
862
|
concat(builder.input(:title, :wrapper_html => {:class => :another_class}, :required => true))
|
|
787
863
|
end)
|
|
788
|
-
output_buffer.
|
|
789
|
-
output_buffer.
|
|
790
|
-
output_buffer.
|
|
864
|
+
expect(output_buffer.to_str).to have_tag("form li.string")
|
|
865
|
+
expect(output_buffer.to_str).to have_tag("form li.required")
|
|
866
|
+
expect(output_buffer.to_str).to have_tag("form li.another_class")
|
|
791
867
|
end
|
|
792
868
|
|
|
793
869
|
it 'should allow classes to be an array' do
|
|
794
870
|
concat(semantic_form_for(@new_post) do |builder|
|
|
795
871
|
concat(builder.input(:title, :wrapper_html => {:class => [ :my_class, :another_class ]}))
|
|
796
872
|
end)
|
|
797
|
-
output_buffer.
|
|
798
|
-
output_buffer.
|
|
799
|
-
output_buffer.
|
|
873
|
+
expect(output_buffer.to_str).to have_tag("form li.string")
|
|
874
|
+
expect(output_buffer.to_str).to have_tag("form li.my_class")
|
|
875
|
+
expect(output_buffer.to_str).to have_tag("form li.another_class")
|
|
800
876
|
end
|
|
801
877
|
|
|
802
878
|
describe 'when nil' do
|
|
@@ -804,7 +880,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
804
880
|
concat(semantic_form_for(@new_post) do |builder|
|
|
805
881
|
concat(builder.input(:title, :wrapper_html => {:id => nil}))
|
|
806
882
|
end)
|
|
807
|
-
output_buffer.
|
|
883
|
+
expect(output_buffer.to_str).to have_tag('form li:not([id])')
|
|
808
884
|
end
|
|
809
885
|
end
|
|
810
886
|
end
|
|
@@ -814,8 +890,8 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
814
890
|
concat(semantic_form_for(@new_post) do |builder|
|
|
815
891
|
concat(builder.input(:title))
|
|
816
892
|
end)
|
|
817
|
-
output_buffer.
|
|
818
|
-
output_buffer.
|
|
893
|
+
expect(output_buffer.to_str).to have_tag("form li#post_title_input")
|
|
894
|
+
expect(output_buffer.to_str).to have_tag("form li.string")
|
|
819
895
|
end
|
|
820
896
|
end
|
|
821
897
|
|
|
@@ -824,15 +900,15 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
824
900
|
describe ':collection option' do
|
|
825
901
|
|
|
826
902
|
it "should be required on polymorphic associations" do
|
|
827
|
-
@new_post.
|
|
828
|
-
@new_post.class.
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
@new_post.
|
|
832
|
-
|
|
903
|
+
allow(@new_post).to receive(:commentable)
|
|
904
|
+
allow(@new_post.class).to receive(:reflections).and_return({
|
|
905
|
+
:commentable => double('macro_reflection', :options => { :polymorphic => true }, :macro => :belongs_to)
|
|
906
|
+
})
|
|
907
|
+
allow(@new_post).to receive(:column_for_attribute).with(:commentable).and_return(
|
|
908
|
+
double('column', :type => :integer)
|
|
833
909
|
)
|
|
834
|
-
@new_post.class.
|
|
835
|
-
|
|
910
|
+
allow(@new_post.class).to receive(:reflect_on_association).with(:commentable).and_return(
|
|
911
|
+
double('reflection', :macro => :belongs_to, :options => { :polymorphic => true })
|
|
836
912
|
)
|
|
837
913
|
expect {
|
|
838
914
|
concat(semantic_form_for(@new_post) do |builder|
|
|
@@ -857,21 +933,18 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
857
933
|
concat(builder.input(:title, my_options))
|
|
858
934
|
concat(builder.input(:publish_at, my_options))
|
|
859
935
|
end)
|
|
860
|
-
output_buffer.
|
|
936
|
+
expect(output_buffer.to_str).to have_tag 'li.string', :count => 2
|
|
861
937
|
end
|
|
862
|
-
|
|
863
|
-
|
|
864
938
|
end
|
|
865
939
|
|
|
866
940
|
describe 'instantiating an input class' do
|
|
867
|
-
|
|
868
941
|
context 'when a class does not exist' do
|
|
869
942
|
it "should raise an error" do
|
|
870
|
-
|
|
943
|
+
expect {
|
|
871
944
|
concat(semantic_form_for(@new_post) do |builder|
|
|
872
945
|
builder.input(:title, :as => :non_existant)
|
|
873
946
|
end)
|
|
874
|
-
}.
|
|
947
|
+
}.to raise_error(Formtastic::UnknownInputError)
|
|
875
948
|
end
|
|
876
949
|
end
|
|
877
950
|
|
|
@@ -879,7 +952,7 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
879
952
|
|
|
880
953
|
it 'should instantiate the Formtastic input' do
|
|
881
954
|
input = double('input', :to_html => 'some HTML')
|
|
882
|
-
Formtastic::Inputs::StringInput.
|
|
955
|
+
expect(Formtastic::Inputs::StringInput).to receive(:new).and_return(input)
|
|
883
956
|
concat(semantic_form_for(@new_post) do |builder|
|
|
884
957
|
builder.input(:title, :as => :string)
|
|
885
958
|
end)
|
|
@@ -893,8 +966,8 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
893
966
|
end
|
|
894
967
|
|
|
895
968
|
input = double('input', :to_html => 'some HTML')
|
|
896
|
-
Formtastic::Inputs::StringInput.
|
|
897
|
-
::StringInput.
|
|
969
|
+
expect(Formtastic::Inputs::StringInput).not_to receive(:new)
|
|
970
|
+
expect(::StringInput).to receive(:new).and_return(input)
|
|
898
971
|
|
|
899
972
|
concat(semantic_form_for(@new_post) do |builder|
|
|
900
973
|
builder.input(:title, :as => :string)
|
|
@@ -902,20 +975,6 @@ describe 'Formtastic::FormBuilder#input' do
|
|
|
902
975
|
end
|
|
903
976
|
end
|
|
904
977
|
|
|
905
|
-
describe 'when instantiated multiple times with the same input type' do
|
|
906
|
-
|
|
907
|
-
it "should be cached (not calling the internal methods)" do
|
|
908
|
-
# TODO this is really tied to the underlying implementation
|
|
909
|
-
concat(semantic_form_for(@new_post) do |builder|
|
|
910
|
-
builder.should_receive(:custom_input_class_name).with(:string).once.and_return(::Formtastic::Inputs::StringInput)
|
|
911
|
-
builder.input(:title, :as => :string)
|
|
912
|
-
builder.input(:title, :as => :string)
|
|
913
|
-
end)
|
|
914
|
-
end
|
|
915
|
-
|
|
916
|
-
end
|
|
917
978
|
|
|
918
979
|
end
|
|
919
|
-
|
|
920
980
|
end
|
|
921
|
-
|