simple_form 3.4.0 → 4.1.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.
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
|