simple_form 3.4.0 → 4.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +62 -0
- data/README.md +208 -36
- data/lib/generators/simple_form/install_generator.rb +1 -0
- data/lib/generators/simple_form/templates/README +3 -3
- data/lib/generators/simple_form/templates/_form.html.erb +2 -0
- data/lib/generators/simple_form/templates/_form.html.haml +2 -0
- data/lib/generators/simple_form/templates/_form.html.slim +1 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +15 -5
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +358 -73
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +20 -8
- data/lib/simple_form/action_view_extensions/builder.rb +1 -0
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -0
- data/lib/simple_form/components/errors.rb +15 -2
- data/lib/simple_form/components/hints.rb +1 -0
- data/lib/simple_form/components/html5.rb +1 -0
- data/lib/simple_form/components/label_input.rb +2 -1
- data/lib/simple_form/components/labels.rb +11 -4
- data/lib/simple_form/components/maxlength.rb +4 -13
- data/lib/simple_form/components/min_max.rb +1 -0
- data/lib/simple_form/components/minlength.rb +5 -14
- data/lib/simple_form/components/pattern.rb +1 -0
- data/lib/simple_form/components/placeholders.rb +2 -1
- data/lib/simple_form/components/readonly.rb +1 -0
- data/lib/simple_form/components.rb +1 -0
- data/lib/simple_form/error_notification.rb +1 -0
- data/lib/simple_form/form_builder.rb +81 -26
- data/lib/simple_form/helpers/autofocus.rb +1 -0
- data/lib/simple_form/helpers/disabled.rb +1 -0
- data/lib/simple_form/helpers/readonly.rb +1 -0
- data/lib/simple_form/helpers/required.rb +1 -0
- data/lib/simple_form/helpers/validators.rb +2 -1
- data/lib/simple_form/helpers.rb +1 -0
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs/base.rb +24 -2
- data/lib/simple_form/inputs/block_input.rb +1 -0
- data/lib/simple_form/inputs/boolean_input.rb +4 -2
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
- data/lib/simple_form/inputs/collection_input.rb +3 -2
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +2 -1
- data/lib/simple_form/inputs/collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/color_input.rb +14 -0
- data/lib/simple_form/inputs/date_time_input.rb +1 -0
- data/lib/simple_form/inputs/file_input.rb +1 -0
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -0
- data/lib/simple_form/inputs/hidden_input.rb +1 -0
- data/lib/simple_form/inputs/numeric_input.rb +1 -0
- data/lib/simple_form/inputs/password_input.rb +1 -0
- data/lib/simple_form/inputs/priority_input.rb +1 -0
- data/lib/simple_form/inputs/range_input.rb +1 -0
- data/lib/simple_form/inputs/string_input.rb +2 -1
- data/lib/simple_form/inputs/text_input.rb +1 -0
- data/lib/simple_form/inputs.rb +2 -0
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +1 -0
- data/lib/simple_form/tags.rb +1 -0
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +1 -0
- data/lib/simple_form/wrappers/leaf.rb +2 -1
- data/lib/simple_form/wrappers/many.rb +1 -0
- data/lib/simple_form/wrappers/root.rb +2 -0
- data/lib/simple_form/wrappers/single.rb +2 -1
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form.rb +58 -7
- data/test/action_view_extensions/builder_test.rb +6 -5
- data/test/action_view_extensions/form_helper_test.rb +3 -2
- data/test/components/custom_components_test.rb +62 -0
- data/test/components/label_test.rb +33 -4
- data/test/form_builder/association_test.rb +27 -2
- data/test/form_builder/button_test.rb +1 -0
- data/test/form_builder/error_notification_test.rb +1 -0
- data/test/form_builder/error_test.rb +12 -0
- data/test/form_builder/general_test.rb +67 -3
- data/test/form_builder/hint_test.rb +6 -0
- data/test/form_builder/input_field_test.rb +30 -10
- data/test/form_builder/label_test.rb +9 -3
- data/test/form_builder/wrapper_test.rb +24 -4
- data/test/generators/simple_form_generator_test.rb +4 -3
- data/test/inputs/boolean_input_test.rb +17 -0
- data/test/inputs/collection_check_boxes_input_test.rb +30 -14
- data/test/inputs/collection_radio_buttons_input_test.rb +40 -24
- data/test/inputs/collection_select_input_test.rb +40 -39
- data/test/inputs/color_input_test.rb +10 -0
- data/test/inputs/datetime_input_test.rb +7 -16
- data/test/inputs/disabled_test.rb +14 -0
- data/test/inputs/discovery_test.rb +22 -0
- data/test/inputs/file_input_test.rb +1 -0
- data/test/inputs/general_test.rb +3 -2
- data/test/inputs/grouped_collection_select_input_test.rb +11 -10
- data/test/inputs/hidden_input_test.rb +1 -0
- data/test/inputs/numeric_input_test.rb +2 -1
- data/test/inputs/priority_input_test.rb +3 -10
- data/test/inputs/readonly_test.rb +1 -0
- data/test/inputs/required_test.rb +1 -0
- data/test/inputs/string_input_test.rb +10 -16
- data/test/inputs/text_input_test.rb +1 -0
- data/test/simple_form_test.rb +1 -0
- data/test/support/discovery_inputs.rb +8 -0
- data/test/support/misc_helpers.rb +22 -1
- data/test/support/mock_controller.rb +7 -1
- data/test/support/models.rb +52 -16
- data/test/test_helper.rb +2 -0
- metadata +40 -47
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
class Leaf
|
@@ -11,7 +12,7 @@ module SimpleForm
|
|
11
12
|
def render(input)
|
12
13
|
method = input.method(@namespace)
|
13
14
|
|
14
|
-
if method.arity
|
15
|
+
if method.arity.zero?
|
15
16
|
ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
|
16
17
|
|
17
18
|
method.call
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# `Root` is the root wrapper for all components. It is special cased to
|
@@ -29,6 +30,7 @@ module SimpleForm
|
|
29
30
|
end
|
30
31
|
css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
|
31
32
|
css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
|
33
|
+
css << (options[:wrapper_valid_class] || @defaults[:valid_class]) if input.valid?
|
32
34
|
css.compact
|
33
35
|
end
|
34
36
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module SimpleForm
|
2
3
|
module Wrappers
|
3
4
|
# `Single` is an optimization for a wrapper that has only one component.
|
@@ -19,7 +20,7 @@ module SimpleForm
|
|
19
20
|
private
|
20
21
|
|
21
22
|
def html_options(options)
|
22
|
-
[
|
23
|
+
%i[label input].include?(namespace) ? {} : super
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
data/lib/simple_form/wrappers.rb
CHANGED
data/lib/simple_form.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'action_view'
|
3
|
+
require 'action_pack'
|
2
4
|
require 'simple_form/action_view_extensions/form_helper'
|
3
5
|
require 'simple_form/action_view_extensions/builder'
|
4
6
|
require 'active_support/core_ext/hash/slice'
|
@@ -58,11 +60,11 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
58
60
|
|
59
61
|
# Series of attemps to detect a default label method for collection.
|
60
62
|
mattr_accessor :collection_label_methods
|
61
|
-
@@collection_label_methods = [
|
63
|
+
@@collection_label_methods = %i[to_label name title to_s]
|
62
64
|
|
63
65
|
# Series of attemps to detect a default value method for collection.
|
64
66
|
mattr_accessor :collection_value_methods
|
65
|
-
@@collection_value_methods = [
|
67
|
+
@@collection_value_methods = %i[id to_s]
|
66
68
|
|
67
69
|
# You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
|
68
70
|
mattr_accessor :collection_wrapper_tag
|
@@ -84,7 +86,7 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
84
86
|
|
85
87
|
# How the label text should be generated altogether with the required text.
|
86
88
|
mattr_accessor :label_text
|
87
|
-
@@label_text =
|
89
|
+
@@label_text = ->(label, required, explicit_label) { "#{required} #{label}" }
|
88
90
|
|
89
91
|
# You can define the class to be used on all labels. Defaults to none.
|
90
92
|
mattr_accessor :label_class
|
@@ -108,7 +110,7 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
108
110
|
|
109
111
|
# You can define which elements should obtain additional classes.
|
110
112
|
mattr_accessor :generate_additional_classes_for
|
111
|
-
@@generate_additional_classes_for = [
|
113
|
+
@@generate_additional_classes_for = %i[wrapper label input]
|
112
114
|
|
113
115
|
# Whether attributes are required by default or not.
|
114
116
|
mattr_accessor :required_by_default
|
@@ -120,7 +122,7 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
120
122
|
|
121
123
|
# Collection of methods to detect if a file type was given.
|
122
124
|
mattr_accessor :file_methods
|
123
|
-
@@file_methods = [
|
125
|
+
@@file_methods = %i[mounted_as file? public_filename attached?]
|
124
126
|
|
125
127
|
# Custom mappings for input types. This should be a hash containing a regexp
|
126
128
|
# to match as key, and the input type that will be used when the field name
|
@@ -163,7 +165,7 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
163
165
|
|
164
166
|
# Cache SimpleForm inputs discovery.
|
165
167
|
mattr_accessor :cache_discovery
|
166
|
-
@@cache_discovery = defined?(Rails) && !Rails.env.development?
|
168
|
+
@@cache_discovery = defined?(Rails.env) && !Rails.env.development?
|
167
169
|
|
168
170
|
# Adds a class to each generated button, mostly for compatiblity.
|
169
171
|
mattr_accessor :button_class
|
@@ -198,6 +200,12 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
198
200
|
mattr_accessor :i18n_scope
|
199
201
|
@@i18n_scope = 'simple_form'
|
200
202
|
|
203
|
+
mattr_accessor :input_field_error_class
|
204
|
+
@@input_field_error_class = nil
|
205
|
+
|
206
|
+
mattr_accessor :input_field_valid_class
|
207
|
+
@@input_field_valid_class = nil
|
208
|
+
|
201
209
|
# Retrieves a given wrapper
|
202
210
|
def self.wrapper(name)
|
203
211
|
@@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
|
@@ -227,7 +235,7 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
227
235
|
SimpleForm::Wrappers::Root.new(builder.to_a, options)
|
228
236
|
end
|
229
237
|
|
230
|
-
wrappers class: :input, hint_class: :field_with_hint, error_class: :field_with_errors do |b|
|
238
|
+
wrappers class: :input, hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|
|
231
239
|
b.use :html5
|
232
240
|
|
233
241
|
b.use :min_max
|
@@ -263,6 +271,49 @@ See https://github.com/plataformatec/simple_form/pull/997 for more information.
|
|
263
271
|
@@configured = true
|
264
272
|
yield self
|
265
273
|
end
|
274
|
+
|
275
|
+
# Includes a component to be used by Simple Form. Methods defined in a
|
276
|
+
# component will be exposed to be used in the wrapper as Simple::Components
|
277
|
+
#
|
278
|
+
# Examples
|
279
|
+
#
|
280
|
+
# # The application needs to tell where the components will be.
|
281
|
+
# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }
|
282
|
+
#
|
283
|
+
# # Create a custom component in the path specified above.
|
284
|
+
# # lib/components/input_group_component.rb
|
285
|
+
# module InputGroupComponent
|
286
|
+
# def prepend
|
287
|
+
# ...
|
288
|
+
# end
|
289
|
+
#
|
290
|
+
# def append
|
291
|
+
# ...
|
292
|
+
# end
|
293
|
+
# end
|
294
|
+
#
|
295
|
+
# SimpleForm.setup do |config|
|
296
|
+
# # Create a wrapper using the custom component.
|
297
|
+
# config.wrappers :input_group, tag: :div, error_class: :error do |b|
|
298
|
+
# b.use :label
|
299
|
+
# b.optional :prepend
|
300
|
+
# b.use :input
|
301
|
+
# b.use :append
|
302
|
+
# end
|
303
|
+
# end
|
304
|
+
#
|
305
|
+
# # Using the custom component in the form.
|
306
|
+
# <%= simple_form_for @blog, wrapper: input_group do |f| %>
|
307
|
+
# <%= f.input :title, prepend: true %>
|
308
|
+
# <% end %>
|
309
|
+
#
|
310
|
+
def self.include_component(component)
|
311
|
+
if Module === component
|
312
|
+
SimpleForm::Inputs::Base.include(component)
|
313
|
+
else
|
314
|
+
raise TypeError, "SimpleForm.include_component expects a module but got: #{component.class}"
|
315
|
+
end
|
316
|
+
end
|
266
317
|
end
|
267
318
|
|
268
319
|
require 'simple_form/railtie' if defined?(Rails)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
class BuilderTest < ActionView::TestCase
|
@@ -36,7 +37,7 @@ class BuilderTest < ActionView::TestCase
|
|
36
37
|
end
|
37
38
|
|
38
39
|
test "collection radio handles camelized collection values for labels correctly" do
|
39
|
-
with_collection_radio_buttons @user, :active, [
|
40
|
+
with_collection_radio_buttons @user, :active, %w[Yes No], :to_s, :to_s
|
40
41
|
|
41
42
|
assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'
|
42
43
|
assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
|
@@ -243,7 +244,7 @@ class BuilderTest < ActionView::TestCase
|
|
243
244
|
|
244
245
|
test "collection radio with block helpers does not leak the template" do
|
245
246
|
with_concat_form_for(@user) do |f|
|
246
|
-
collection_input =
|
247
|
+
collection_input = f.collection_radio_buttons :active, [true, false], :to_s, :to_s do |b|
|
247
248
|
b.label(class: b.object) { b.radio_button + b.text }
|
248
249
|
end
|
249
250
|
concat collection_input
|
@@ -283,7 +284,7 @@ class BuilderTest < ActionView::TestCase
|
|
283
284
|
end
|
284
285
|
|
285
286
|
test "collection check box handles camelized collection values for labels correctly" do
|
286
|
-
with_collection_check_boxes @user, :active, [
|
287
|
+
with_collection_check_boxes @user, :active, %w[Yes No], :to_s, :to_s
|
287
288
|
|
288
289
|
assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
|
289
290
|
assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
|
@@ -317,7 +318,7 @@ class BuilderTest < ActionView::TestCase
|
|
317
318
|
|
318
319
|
test "collection check boxes accepts selected string values as :checked option" do
|
319
320
|
collection = (1..3).map { |i| [i, "Category #{i}"] }
|
320
|
-
with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: [
|
321
|
+
with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: %w[1 3]
|
321
322
|
|
322
323
|
assert_select 'input[type=checkbox][value="1"][checked=checked]'
|
323
324
|
assert_select 'input[type=checkbox][value="3"][checked=checked]'
|
@@ -541,7 +542,7 @@ class BuilderTest < ActionView::TestCase
|
|
541
542
|
|
542
543
|
test "collection check boxes with block helpers does not leak the template" do
|
543
544
|
with_concat_form_for(@user) do |f|
|
544
|
-
collection_input =
|
545
|
+
collection_input = f.collection_check_boxes :active, [true, false], :to_s, :to_s do |b|
|
545
546
|
b.label(class: b.object) { b.check_box + b.text }
|
546
547
|
end
|
547
548
|
concat collection_input
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
class FormHelperTest < ActionView::TestCase
|
@@ -151,7 +152,7 @@ class FormHelperTest < ActionView::TestCase
|
|
151
152
|
end
|
152
153
|
|
153
154
|
test 'SimpleForm for swaps default action view field_error_proc' do
|
154
|
-
expected_error_proc =
|
155
|
+
expected_error_proc = -> {}
|
155
156
|
swap SimpleForm, field_error_proc: expected_error_proc do
|
156
157
|
simple_form_for :user do |f|
|
157
158
|
assert_equal expected_error_proc, ::ActionView::Base.field_error_proc
|
@@ -161,7 +162,7 @@ class FormHelperTest < ActionView::TestCase
|
|
161
162
|
|
162
163
|
private
|
163
164
|
|
164
|
-
def swap_field_error_proc(expected_error_proc =
|
165
|
+
def swap_field_error_proc(expected_error_proc = -> {})
|
165
166
|
swap ActionView::Base, field_error_proc: expected_error_proc do
|
166
167
|
yield
|
167
168
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
|
5
|
+
# Module that represents a custom component.
|
6
|
+
module Numbers
|
7
|
+
def number(wrapper_options = nil)
|
8
|
+
@number ||= options[:number].to_s.html_safe
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Module that represents a custom component.
|
13
|
+
module InputGroup
|
14
|
+
def prepend(wrapper_options = nil)
|
15
|
+
span_tag = content_tag(:span, options[:prepend], class: 'input-group-text')
|
16
|
+
template.content_tag(:div, span_tag, class: 'input-group-prepend')
|
17
|
+
end
|
18
|
+
|
19
|
+
def append(wrapper_options = nil)
|
20
|
+
span_tag = content_tag(:span, options[:append], class: 'input-group-text')
|
21
|
+
template.content_tag(:div, span_tag, class: 'input-group-append')
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class CustomComponentsTest < ActionView::TestCase
|
26
|
+
test 'includes the custom components' do
|
27
|
+
SimpleForm.include_component Numbers
|
28
|
+
|
29
|
+
custom_wrapper = SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
30
|
+
b.use :number, wrap_with: { tag: 'div', class: 'number' }
|
31
|
+
end
|
32
|
+
|
33
|
+
with_form_for @user, :name, number: 1, wrapper: custom_wrapper
|
34
|
+
|
35
|
+
assert_select 'div.number', text: '1'
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'includes custom components and use it as optional in the wrapper' do
|
39
|
+
SimpleForm.include_component InputGroup
|
40
|
+
|
41
|
+
custom_wrapper = SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
|
42
|
+
b.use :label
|
43
|
+
b.optional :prepend
|
44
|
+
b.use :input
|
45
|
+
b.use :append
|
46
|
+
end
|
47
|
+
|
48
|
+
with_form_for @user, :name, prepend: true, wrapper: custom_wrapper
|
49
|
+
|
50
|
+
assert_select 'div.input-group-prepend > span.input-group-text'
|
51
|
+
assert_select 'div.input-group-append > span.input-group-text'
|
52
|
+
end
|
53
|
+
|
54
|
+
test 'raises a TypeError when the component is not a Module' do
|
55
|
+
component = 'MyComponent'
|
56
|
+
|
57
|
+
exception = assert_raises TypeError do
|
58
|
+
SimpleForm.include_component(component)
|
59
|
+
end
|
60
|
+
assert_equal exception.message, "SimpleForm.include_component expects a module but got: String"
|
61
|
+
end
|
62
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -177,7 +178,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
177
178
|
end
|
178
179
|
|
179
180
|
test 'label does not have css class from type when generate_additional_classes_for does not include :label' do
|
180
|
-
swap SimpleForm, generate_additional_classes_for: [
|
181
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
181
182
|
with_label_for @user, :name, :string
|
182
183
|
assert_no_select 'label.string'
|
183
184
|
with_label_for @user, :description, :text
|
@@ -192,7 +193,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
192
193
|
end
|
193
194
|
|
194
195
|
test 'label does not generate empty css class' do
|
195
|
-
swap SimpleForm, generate_additional_classes_for: [
|
196
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
196
197
|
with_label_for @user, :name, :string
|
197
198
|
assert_no_select 'label[class]'
|
198
199
|
end
|
@@ -206,7 +207,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
206
207
|
end
|
207
208
|
|
208
209
|
test 'label does not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do
|
209
|
-
swap SimpleForm, generate_additional_classes_for: [
|
210
|
+
swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do
|
210
211
|
with_label_for @validating_user, :name, :string
|
211
212
|
assert_no_select 'label.required'
|
212
213
|
with_label_for @validating_user, :status, :string
|
@@ -248,6 +249,15 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
248
249
|
end
|
249
250
|
end
|
250
251
|
|
252
|
+
test 'label uses custom i18n scope to find required text' do
|
253
|
+
store_translations(:en, my_scope: { required: { text: 'Pflichtfeld' } }) do
|
254
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
255
|
+
with_label_for @user, :name, :string
|
256
|
+
assert_select 'form label abbr[title="Pflichtfeld"]', '*'
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
251
261
|
test 'label uses i18n to find required mark' do
|
252
262
|
store_translations(:en, simple_form: { required: { mark: '*-*' } }) do
|
253
263
|
with_label_for @user, :name, :string
|
@@ -255,6 +265,15 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
255
265
|
end
|
256
266
|
end
|
257
267
|
|
268
|
+
test 'label uses custom i18n scope to find required mark' do
|
269
|
+
store_translations(:en, my_scope: { required: { mark: '!!' } }) do
|
270
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
271
|
+
with_label_for @user, :name, :string
|
272
|
+
assert_select 'form label abbr', '!!'
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
258
277
|
test 'label uses i18n to find required string tag' do
|
259
278
|
store_translations(:en, simple_form: { required: { html: '<span class="required" title="requerido">*</span>' } }) do
|
260
279
|
with_label_for @user, :name, :string
|
@@ -263,6 +282,16 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
263
282
|
end
|
264
283
|
end
|
265
284
|
|
285
|
+
test 'label uses custom i18n scope to find required string tag' do
|
286
|
+
store_translations(:en, my_scope: { required: { html: '<span class="mandatory" title="Pflichtfeld">!!</span>' } }) do
|
287
|
+
swap SimpleForm, i18n_scope: :my_scope do
|
288
|
+
with_label_for @user, :name, :string
|
289
|
+
assert_no_select 'form label abbr'
|
290
|
+
assert_select 'form label span.mandatory[title=Pflichtfeld]', '!!'
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
266
295
|
test 'label allows overwriting input id' do
|
267
296
|
with_label_for @user, :name, :string, input_html: { id: 'my_new_id' }
|
268
297
|
assert_select 'label[for=my_new_id]'
|
@@ -289,7 +318,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
289
318
|
end
|
290
319
|
|
291
320
|
test 'label includes for attribute for select collection' do
|
292
|
-
with_label_for @user, :sex, :select, collection: [
|
321
|
+
with_label_for @user, :sex, :select, collection: %i[male female]
|
293
322
|
assert_select 'label[for=user_sex]'
|
294
323
|
end
|
295
324
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -14,6 +15,12 @@ class AssociationTest < ActionView::TestCase
|
|
14
15
|
end
|
15
16
|
end
|
16
17
|
|
18
|
+
test 'builder association works with decorated object responsive to #to_model' do
|
19
|
+
assert_nothing_raised do
|
20
|
+
with_association_for @decorated_user, :company
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
test 'builder association with a block calls simple_fields_for' do
|
18
25
|
simple_form_for @user do |f|
|
19
26
|
f.association :posts do |posts_form|
|
@@ -121,6 +128,15 @@ class AssociationTest < ActionView::TestCase
|
|
121
128
|
assert_no_select 'form select option[value="2"]'
|
122
129
|
end
|
123
130
|
|
131
|
+
test 'builder allows collection to have a scope with parameter' do
|
132
|
+
with_association_for @user, :special_tags
|
133
|
+
assert_select 'form select.select#user_special_tag_ids'
|
134
|
+
assert_select 'form select[multiple=multiple]'
|
135
|
+
assert_select 'form select option[value="1"]', 'Tag 1'
|
136
|
+
assert_no_select 'form select option[value="2"]'
|
137
|
+
assert_no_select 'form select option[value="3"]'
|
138
|
+
end
|
139
|
+
|
124
140
|
test 'builder marks the record which already belongs to the user' do
|
125
141
|
@user.company_id = 2
|
126
142
|
with_association_for @user, :company, as: :radio_buttons
|
@@ -154,6 +170,15 @@ class AssociationTest < ActionView::TestCase
|
|
154
170
|
end
|
155
171
|
end
|
156
172
|
|
173
|
+
test 'builder does not call where if the given association does not respond to it' do
|
174
|
+
with_association_for @user, :friends
|
175
|
+
assert_select 'form select.select#user_friend_ids'
|
176
|
+
assert_select 'form select[multiple=multiple]'
|
177
|
+
assert_select 'form select option[value="1"]', 'Friend 1'
|
178
|
+
assert_select 'form select option[value="2"]', 'Friend 2'
|
179
|
+
assert_select 'form select option[value="3"]', 'Friend 3'
|
180
|
+
end
|
181
|
+
|
157
182
|
test 'builder does not call order if the given association does not respond to it' do
|
158
183
|
with_association_for @user, :pictures
|
159
184
|
assert_select 'form select.select#user_picture_ids'
|
@@ -210,12 +235,12 @@ class AssociationTest < ActionView::TestCase
|
|
210
235
|
end
|
211
236
|
|
212
237
|
test 'builder with collection support does not change the options hash' do
|
213
|
-
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li}
|
238
|
+
options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li }
|
214
239
|
with_association_for @user, :tags, options
|
215
240
|
|
216
241
|
assert_select 'form ul', count: 1
|
217
242
|
assert_select 'form ul li', count: 3
|
218
|
-
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li},
|
243
|
+
assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li },
|
219
244
|
options)
|
220
245
|
end
|
221
246
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.error and f.full_error
|
@@ -35,6 +36,11 @@ class ErrorTest < ActionView::TestCase
|
|
35
36
|
assert_select 'span.error', "cannot be blank"
|
36
37
|
end
|
37
38
|
|
39
|
+
test 'error generates messages with decorated object responsive to #to_model' do
|
40
|
+
with_error_for @decorated_user, :name
|
41
|
+
assert_select 'span.error', "cannot be blank"
|
42
|
+
end
|
43
|
+
|
38
44
|
test 'error generates messages for attribute with one error when using first' do
|
39
45
|
swap SimpleForm, error_method: :first do
|
40
46
|
with_error_for @user, :age
|
@@ -218,6 +224,12 @@ class ErrorTest < ActionView::TestCase
|
|
218
224
|
assert_no_select 'span.error'
|
219
225
|
end
|
220
226
|
|
227
|
+
test 'input with custom error works when form does not use a model' do
|
228
|
+
with_form_for :user, :active, error: "Super User Active! cannot be blank"
|
229
|
+
|
230
|
+
assert_select 'span.error'
|
231
|
+
end
|
232
|
+
|
221
233
|
test 'input with custom error works when using full_error component' do
|
222
234
|
swap_wrapper :default, custom_wrapper_with_full_error do
|
223
235
|
error_text = "Super User Name! cannot be blank"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
# encoding: UTF-8
|
2
3
|
require 'test_helper'
|
3
4
|
|
@@ -30,6 +31,12 @@ class FormBuilderTest < ActionView::TestCase
|
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
34
|
+
test 'builder works with decorated object responsive to #to_model' do
|
35
|
+
assert_nothing_raised do
|
36
|
+
with_form_for @decorated_user, :name
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
33
40
|
test 'builder input allows a block to configure input' do
|
34
41
|
with_form_for @user, :name do
|
35
42
|
text_field_tag :foo, :bar, id: :cool
|
@@ -49,7 +56,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
49
56
|
test 'builder does not override custom input mappings for custom collection' do
|
50
57
|
swap SimpleForm, input_mappings: { /gender$/ => :check_boxes } do
|
51
58
|
with_concat_form_for @user do |f|
|
52
|
-
f.input :gender, collection: [
|
59
|
+
f.input :gender, collection: %i[male female]
|
53
60
|
end
|
54
61
|
|
55
62
|
assert_no_select 'select option', 'Male'
|
@@ -58,7 +65,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
58
65
|
end
|
59
66
|
|
60
67
|
test 'builder allows to skip input_type class' do
|
61
|
-
swap SimpleForm, generate_additional_classes_for: [
|
68
|
+
swap SimpleForm, generate_additional_classes_for: %i[label wrapper] do
|
62
69
|
with_form_for @user, :post_count
|
63
70
|
assert_no_select "form input#user_post_count.integer"
|
64
71
|
assert_select "form input#user_post_count"
|
@@ -119,9 +126,40 @@ class FormBuilderTest < ActionView::TestCase
|
|
119
126
|
|
120
127
|
test 'builder generates text areas for text columns' do
|
121
128
|
with_form_for @user, :description
|
129
|
+
assert_no_select 'form input#user_description.string'
|
122
130
|
assert_select 'form textarea#user_description.text'
|
123
131
|
end
|
124
132
|
|
133
|
+
test 'builder generates text areas for text columns when hinted' do
|
134
|
+
with_form_for @user, :description, as: :text
|
135
|
+
assert_no_select 'form input#user_description.string'
|
136
|
+
assert_select 'form textarea#user_description.text'
|
137
|
+
end
|
138
|
+
|
139
|
+
test 'builder generates text field for text columns when hinted' do
|
140
|
+
with_form_for @user, :description, as: :string
|
141
|
+
assert_no_select 'form textarea#user_description.text'
|
142
|
+
assert_select 'form input#user_description.string'
|
143
|
+
end
|
144
|
+
|
145
|
+
test 'builder generates text areas for hstore columns' do
|
146
|
+
with_form_for @user, :hstore
|
147
|
+
assert_no_select 'form input#user_hstore.string'
|
148
|
+
assert_select 'form textarea#user_hstore.text'
|
149
|
+
end
|
150
|
+
|
151
|
+
test 'builder generates text areas for json columns' do
|
152
|
+
with_form_for @user, :json
|
153
|
+
assert_no_select 'form input#user_json.string'
|
154
|
+
assert_select 'form textarea#user_json.text'
|
155
|
+
end
|
156
|
+
|
157
|
+
test 'builder generates text areas for jsonb columns' do
|
158
|
+
with_form_for @user, :jsonb
|
159
|
+
assert_no_select 'form input#user_jsonb.string'
|
160
|
+
assert_select 'form textarea#user_jsonb.text'
|
161
|
+
end
|
162
|
+
|
125
163
|
test 'builder generates a checkbox for boolean columns' do
|
126
164
|
with_form_for @user, :active
|
127
165
|
assert_select 'form input[type=checkbox]#user_active.boolean'
|
@@ -146,6 +184,11 @@ class FormBuilderTest < ActionView::TestCase
|
|
146
184
|
end
|
147
185
|
end
|
148
186
|
|
187
|
+
test 'builder generates string fields for citext columns' do
|
188
|
+
with_form_for @user, :citext
|
189
|
+
assert_select 'form input#user_citext.string'
|
190
|
+
end
|
191
|
+
|
149
192
|
test 'builder generates password fields for columns that matches password' do
|
150
193
|
with_form_for @user, :password
|
151
194
|
assert_select 'form input#user_password.password'
|
@@ -199,6 +242,16 @@ class FormBuilderTest < ActionView::TestCase
|
|
199
242
|
test 'builder generates file for file columns' do
|
200
243
|
@user.avatar = MiniTest::Mock.new
|
201
244
|
@user.avatar.expect(:public_filename, true)
|
245
|
+
@user.avatar.expect(:!, false)
|
246
|
+
|
247
|
+
with_form_for @user, :avatar
|
248
|
+
assert_select 'form input#user_avatar.file'
|
249
|
+
end
|
250
|
+
|
251
|
+
test 'builder generates file for activestorage entries' do
|
252
|
+
@user.avatar = MiniTest::Mock.new
|
253
|
+
@user.avatar.expect(:attached?, false)
|
254
|
+
@user.avatar.expect(:!, false)
|
202
255
|
|
203
256
|
with_form_for @user, :avatar
|
204
257
|
assert_select 'form input#user_avatar.file'
|
@@ -207,6 +260,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
207
260
|
test 'builder generates file for attributes that are real db columns but have file methods' do
|
208
261
|
@user.home_picture = MiniTest::Mock.new
|
209
262
|
@user.home_picture.expect(:mounted_as, true)
|
263
|
+
@user.home_picture.expect(:!, false)
|
210
264
|
|
211
265
|
with_form_for @user, :home_picture
|
212
266
|
assert_select 'form input#user_home_picture.file'
|
@@ -217,15 +271,25 @@ class FormBuilderTest < ActionView::TestCase
|
|
217
271
|
assert_select 'form select#user_age.select'
|
218
272
|
end
|
219
273
|
|
274
|
+
test 'builder does not generate url fields for columns that contain only the letters url' do
|
275
|
+
with_form_for @user, :hourly
|
276
|
+
assert_no_select 'form input#user_url.string.url'
|
277
|
+
assert_select 'form input#user_hourly.string'
|
278
|
+
end
|
279
|
+
|
220
280
|
test 'builder allows overriding default input type for text' do
|
221
281
|
with_form_for @user, :name, as: :text
|
222
282
|
assert_no_select 'form input#user_name'
|
223
283
|
assert_select 'form textarea#user_name.text'
|
284
|
+
end
|
224
285
|
|
286
|
+
test 'builder allows overriding default input type for radio_buttons' do
|
225
287
|
with_form_for @user, :active, as: :radio_buttons
|
226
288
|
assert_no_select 'form input[type=checkbox]'
|
227
289
|
assert_select 'form input.radio_buttons[type=radio]', count: 2
|
290
|
+
end
|
228
291
|
|
292
|
+
test 'builder allows overriding default input type for string' do
|
229
293
|
with_form_for @user, :born_at, as: :string
|
230
294
|
assert_no_select 'form select'
|
231
295
|
assert_select 'form input#user_born_at.string'
|
@@ -365,7 +429,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
365
429
|
end
|
366
430
|
|
367
431
|
# DEFAULT OPTIONS
|
368
|
-
[
|
432
|
+
%i[input input_field].each do |method|
|
369
433
|
test "builder receives a default argument and pass it to the inputs when calling '#{method}'" do
|
370
434
|
with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
|
371
435
|
f.public_send(method, :name)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'test_helper'
|
2
3
|
|
3
4
|
# Tests for f.hint
|
@@ -18,6 +19,11 @@ class HintTest < ActionView::TestCase
|
|
18
19
|
assert_select 'span.hint', 'Use with care...'
|
19
20
|
end
|
20
21
|
|
22
|
+
test 'hint is generated with decorated object responsive to #to_model' do
|
23
|
+
with_hint_for @decorated_user, :name, hint: 'Use with care...'
|
24
|
+
assert_select 'span.hint', 'Use with care...'
|
25
|
+
end
|
26
|
+
|
21
27
|
test 'hint does not modify the options hash' do
|
22
28
|
options = { hint: 'Use with care...' }
|
23
29
|
with_hint_for @user, :name, options
|