simple_form 2.0.0 → 3.5.1
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 +7 -0
- data/CHANGELOG.md +97 -198
- data/MIT-LICENSE +1 -1
- data/README.md +572 -296
- data/lib/generators/simple_form/install_generator.rb +17 -7
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/_form.html.erb +1 -0
- data/lib/generators/simple_form/templates/_form.html.haml +1 -0
- data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +57 -63
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +155 -0
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +111 -0
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +14 -7
- data/lib/simple_form/action_view_extensions/builder.rb +5 -305
- data/lib/simple_form/action_view_extensions/form_helper.rb +18 -20
- data/lib/simple_form/components/errors.rb +30 -3
- data/lib/simple_form/components/hints.rb +10 -3
- data/lib/simple_form/components/html5.rb +17 -3
- data/lib/simple_form/components/label_input.rb +21 -2
- data/lib/simple_form/components/labels.rb +16 -11
- data/lib/simple_form/components/maxlength.rb +19 -12
- data/lib/simple_form/components/min_max.rb +4 -2
- data/lib/simple_form/components/minlength.rb +48 -0
- data/lib/simple_form/components/pattern.rb +5 -4
- data/lib/simple_form/components/placeholders.rb +3 -2
- data/lib/simple_form/components/readonly.rb +3 -2
- data/lib/simple_form/components.rb +15 -11
- data/lib/simple_form/error_notification.rb +4 -3
- data/lib/simple_form/form_builder.rb +283 -105
- 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 +4 -3
- data/lib/simple_form/helpers.rb +7 -6
- data/lib/simple_form/i18n_cache.rb +1 -0
- data/lib/simple_form/inputs/base.rb +76 -23
- data/lib/simple_form/inputs/block_input.rb +3 -2
- data/lib/simple_form/inputs/boolean_input.rb +55 -16
- data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
- data/lib/simple_form/inputs/collection_input.rb +41 -18
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +11 -19
- data/lib/simple_form/inputs/collection_select_input.rb +5 -2
- data/lib/simple_form/inputs/date_time_input.rb +23 -12
- data/lib/simple_form/inputs/file_input.rb +5 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
- data/lib/simple_form/inputs/hidden_input.rb +5 -2
- data/lib/simple_form/inputs/numeric_input.rb +4 -8
- data/lib/simple_form/inputs/password_input.rb +6 -4
- data/lib/simple_form/inputs/priority_input.rb +5 -2
- data/lib/simple_form/inputs/range_input.rb +2 -1
- data/lib/simple_form/inputs/string_input.rb +6 -4
- data/lib/simple_form/inputs/text_input.rb +6 -3
- data/lib/simple_form/inputs.rb +20 -17
- data/lib/simple_form/map_type.rb +1 -0
- data/lib/simple_form/railtie.rb +15 -0
- data/lib/simple_form/tags.rb +69 -0
- data/lib/simple_form/version.rb +2 -1
- data/lib/simple_form/wrappers/builder.rb +12 -35
- data/lib/simple_form/wrappers/leaf.rb +29 -0
- data/lib/simple_form/wrappers/many.rb +12 -7
- data/lib/simple_form/wrappers/root.rb +7 -4
- data/lib/simple_form/wrappers/single.rb +12 -3
- data/lib/simple_form/wrappers.rb +3 -1
- data/lib/simple_form.rb +118 -63
- data/test/action_view_extensions/builder_test.rb +230 -164
- data/test/action_view_extensions/form_helper_test.rb +107 -39
- data/test/components/label_test.rb +105 -87
- data/test/form_builder/association_test.rb +131 -62
- data/test/form_builder/button_test.rb +15 -14
- data/test/form_builder/error_notification_test.rb +11 -10
- data/test/form_builder/error_test.rb +188 -34
- data/test/form_builder/general_test.rb +247 -102
- data/test/form_builder/hint_test.rb +59 -32
- data/test/form_builder/input_field_test.rb +138 -25
- data/test/form_builder/label_test.rb +84 -13
- data/test/form_builder/wrapper_test.rb +236 -33
- data/test/generators/simple_form_generator_test.rb +15 -4
- data/test/inputs/boolean_input_test.rb +147 -13
- data/test/inputs/collection_check_boxes_input_test.rb +166 -71
- data/test/inputs/collection_radio_buttons_input_test.rb +229 -113
- data/test/inputs/collection_select_input_test.rb +222 -85
- data/test/inputs/datetime_input_test.rb +134 -47
- data/test/inputs/disabled_test.rb +62 -21
- data/test/inputs/discovery_test.rb +70 -10
- data/test/inputs/file_input_test.rb +4 -3
- data/test/inputs/general_test.rb +90 -26
- data/test/inputs/grouped_collection_select_input_test.rb +88 -23
- data/test/inputs/hidden_input_test.rb +7 -5
- data/test/inputs/numeric_input_test.rb +56 -46
- data/test/inputs/priority_input_test.rb +31 -16
- data/test/inputs/readonly_test.rb +68 -27
- data/test/inputs/required_test.rb +63 -18
- data/test/inputs/string_input_test.rb +76 -51
- data/test/inputs/text_input_test.rb +21 -8
- data/test/simple_form_test.rb +9 -0
- data/test/support/discovery_inputs.rb +39 -2
- data/test/support/misc_helpers.rb +176 -20
- data/test/support/mock_controller.rb +13 -7
- data/test/support/models.rb +187 -71
- data/test/test_helper.rb +38 -39
- metadata +53 -39
- data/lib/simple_form/core_ext/hash.rb +0 -16
- data/test/support/mock_response.rb +0 -14
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
# Tests for f.hint
|
|
@@ -8,40 +9,56 @@ class HintTest < ActionView::TestCase
|
|
|
8
9
|
end
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
test 'hint
|
|
12
|
+
test 'hint does not be generated by default' do
|
|
12
13
|
with_hint_for @user, :name
|
|
13
14
|
assert_no_select 'span.hint'
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
test 'hint
|
|
17
|
-
with_hint_for @user, :name, :
|
|
17
|
+
test 'hint is generated with optional text' do
|
|
18
|
+
with_hint_for @user, :name, hint: 'Use with care...'
|
|
18
19
|
assert_select 'span.hint', 'Use with care...'
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
test 'hint
|
|
22
|
-
|
|
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
|
+
|
|
27
|
+
test 'hint does not modify the options hash' do
|
|
28
|
+
options = { hint: 'Use with care...' }
|
|
23
29
|
with_hint_for @user, :name, options
|
|
24
30
|
assert_select 'span.hint', 'Use with care...'
|
|
25
|
-
assert_equal({ :
|
|
31
|
+
assert_equal({ hint: 'Use with care...' }, options)
|
|
26
32
|
end
|
|
27
33
|
|
|
28
|
-
test 'hint
|
|
29
|
-
with_hint_for @user, :name, :
|
|
34
|
+
test 'hint is generated cleanly with optional text' do
|
|
35
|
+
with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :span
|
|
30
36
|
assert_no_select 'span.hint[hint]'
|
|
31
37
|
assert_no_select 'span.hint[hint_tag]'
|
|
32
38
|
assert_no_select 'span.hint[hint_html]'
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
test 'hint uses the current component tag set' do
|
|
36
|
-
with_hint_for @user, :name, :
|
|
42
|
+
with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :p
|
|
37
43
|
assert_select 'p.hint', 'Use with care...'
|
|
38
44
|
end
|
|
39
45
|
|
|
40
|
-
test 'hint
|
|
41
|
-
with_hint_for @user, :name, :
|
|
46
|
+
test 'hint is able to pass html options' do
|
|
47
|
+
with_hint_for @user, :name, hint: 'Yay!', id: 'hint', class: 'yay'
|
|
42
48
|
assert_select 'span#hint.hint.yay'
|
|
43
49
|
end
|
|
44
50
|
|
|
51
|
+
test 'hint is output as html_safe' do
|
|
52
|
+
with_hint_for @user, :name, hint: '<b>Bold</b> and not...'.html_safe
|
|
53
|
+
assert_select 'span.hint', 'Bold and not...'
|
|
54
|
+
assert_select 'span.hint b', 'Bold'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
test 'builder escapes hint text' do
|
|
58
|
+
with_hint_for @user, :name, hint: '<script>alert(1337)</script>'
|
|
59
|
+
assert_no_select 'span.hint script'
|
|
60
|
+
end
|
|
61
|
+
|
|
45
62
|
# Without attribute name
|
|
46
63
|
|
|
47
64
|
test 'hint without attribute name' do
|
|
@@ -49,66 +66,76 @@ class HintTest < ActionView::TestCase
|
|
|
49
66
|
assert_select 'span.hint', 'Hello World!'
|
|
50
67
|
end
|
|
51
68
|
|
|
52
|
-
test 'hint without attribute name
|
|
69
|
+
test 'hint without attribute name generates component tag with a clean HTML' do
|
|
53
70
|
with_hint_for @validating_user, 'Hello World!'
|
|
54
71
|
assert_no_select 'span.hint[hint]'
|
|
55
72
|
assert_no_select 'span.hint[hint_html]'
|
|
56
73
|
end
|
|
57
74
|
|
|
58
75
|
test 'hint without attribute name uses the current component tag set' do
|
|
59
|
-
with_hint_for @user, 'Hello World!', :
|
|
76
|
+
with_hint_for @user, 'Hello World!', hint_tag: :p
|
|
60
77
|
assert_no_select 'p.hint[hint]'
|
|
61
78
|
assert_no_select 'p.hint[hint_html]'
|
|
62
79
|
assert_no_select 'p.hint[hint_tag]'
|
|
63
80
|
end
|
|
64
81
|
|
|
65
|
-
test 'hint without attribute name
|
|
66
|
-
with_hint_for @user, 'Yay', :
|
|
82
|
+
test 'hint without attribute name is able to pass html options' do
|
|
83
|
+
with_hint_for @user, 'Yay', id: 'hint', class: 'yay'
|
|
67
84
|
assert_select 'span#hint.hint.yay', 'Yay'
|
|
68
85
|
end
|
|
69
86
|
|
|
70
87
|
# I18n
|
|
71
88
|
|
|
72
|
-
test 'hint
|
|
73
|
-
store_translations(:en, :
|
|
74
|
-
:
|
|
89
|
+
test 'hint uses i18n based on model, action, and attribute to lookup translation' do
|
|
90
|
+
store_translations(:en, simple_form: { hints: { user: {
|
|
91
|
+
edit: { name: 'Content of this input will be truncated...' }
|
|
75
92
|
} } }) do
|
|
76
93
|
with_hint_for @user, :name
|
|
77
94
|
assert_select 'span.hint', 'Content of this input will be truncated...'
|
|
78
95
|
end
|
|
79
96
|
end
|
|
80
97
|
|
|
81
|
-
test 'hint
|
|
82
|
-
store_translations(:en, :
|
|
83
|
-
:
|
|
98
|
+
test 'hint uses i18n with model and attribute to lookup translation' do
|
|
99
|
+
store_translations(:en, simple_form: { hints: { user: {
|
|
100
|
+
name: 'Content of this input will be capitalized...'
|
|
84
101
|
} } }) do
|
|
85
102
|
with_hint_for @user, :name
|
|
86
103
|
assert_select 'span.hint', 'Content of this input will be capitalized...'
|
|
87
104
|
end
|
|
88
105
|
end
|
|
89
106
|
|
|
90
|
-
test 'hint
|
|
91
|
-
store_translations(:en, :
|
|
92
|
-
:
|
|
107
|
+
test 'hint uses i18n under defaults namespace to lookup translation' do
|
|
108
|
+
store_translations(:en, simple_form: {
|
|
109
|
+
hints: { defaults: { name: 'Content of this input will be downcased...' } }
|
|
93
110
|
}) do
|
|
94
111
|
with_hint_for @user, :name
|
|
95
112
|
assert_select 'span.hint', 'Content of this input will be downcased...'
|
|
96
113
|
end
|
|
97
114
|
end
|
|
98
115
|
|
|
99
|
-
test 'hint
|
|
100
|
-
store_translations(:en, :
|
|
101
|
-
:
|
|
116
|
+
test 'hint uses i18n with lookup for association name' do
|
|
117
|
+
store_translations(:en, simple_form: { hints: {
|
|
118
|
+
user: { company: 'My company!' }
|
|
102
119
|
} } ) do
|
|
103
|
-
with_hint_for @user, :company_id, :
|
|
120
|
+
with_hint_for @user, :company_id, as: :string, reflection: Association.new(Company, :company, {})
|
|
104
121
|
assert_select 'span.hint', /My company!/
|
|
105
122
|
end
|
|
106
123
|
end
|
|
107
124
|
|
|
125
|
+
test 'hint outputs translations as html_safe' do
|
|
126
|
+
store_translations(:en, simple_form: { hints: { user: {
|
|
127
|
+
edit: { name: '<b>This is bold</b> and this is not...' }
|
|
128
|
+
} } }) do
|
|
129
|
+
with_hint_for @user, :name
|
|
130
|
+
assert_select 'span.hint', 'This is bold and this is not...'
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
|
|
108
135
|
# No object
|
|
109
136
|
|
|
110
|
-
test 'hint
|
|
111
|
-
with_hint_for :project, :name, :
|
|
137
|
+
test 'hint generates properly when object is not present' do
|
|
138
|
+
with_hint_for :project, :name, hint: 'Test without object'
|
|
112
139
|
assert_select 'span.hint', 'Test without object'
|
|
113
140
|
end
|
|
114
141
|
|
|
@@ -116,8 +143,8 @@ class HintTest < ActionView::TestCase
|
|
|
116
143
|
|
|
117
144
|
test 'hint with custom wrappers works' do
|
|
118
145
|
swap_wrapper do
|
|
119
|
-
with_hint_for @user, :name, :
|
|
120
|
-
assert_select 'div.omg_hint', "
|
|
146
|
+
with_hint_for @user, :name, hint: "cannot be blank"
|
|
147
|
+
assert_select 'div.omg_hint', "cannot be blank"
|
|
121
148
|
end
|
|
122
149
|
end
|
|
123
150
|
end
|
|
@@ -1,63 +1,176 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
require 'test_helper'
|
|
2
3
|
|
|
3
4
|
# Tests for f.input_field
|
|
4
5
|
class InputFieldTest < ActionView::TestCase
|
|
5
|
-
|
|
6
|
-
with_concat_form_for(
|
|
7
|
-
f.input_field
|
|
6
|
+
def with_input_field_for(object, *args)
|
|
7
|
+
with_concat_form_for(object) do |f|
|
|
8
|
+
f.input_field(*args)
|
|
8
9
|
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
test "builder input_field only renders the input tag, nothing else" do
|
|
13
|
+
with_input_field_for @user, :name
|
|
14
|
+
|
|
9
15
|
assert_select 'form > input.required.string'
|
|
10
16
|
assert_no_select 'div.string'
|
|
11
17
|
assert_no_select 'label'
|
|
12
18
|
assert_no_select '.hint'
|
|
13
19
|
end
|
|
14
20
|
|
|
15
|
-
test 'builder input_field
|
|
16
|
-
|
|
17
|
-
f.input_field :name, :as => :text
|
|
18
|
-
end
|
|
21
|
+
test 'builder input_field allows overriding default input type' do
|
|
22
|
+
with_input_field_for @user, :name, as: :text
|
|
19
23
|
|
|
20
24
|
assert_no_select 'input#user_name'
|
|
21
25
|
assert_select 'textarea#user_name.text'
|
|
22
26
|
end
|
|
23
27
|
|
|
24
|
-
test 'builder input_field
|
|
25
|
-
|
|
26
|
-
f.input_field :name, :id => 'name_input', :class => 'name'
|
|
27
|
-
end
|
|
28
|
+
test 'builder input_field generates input type based on column type' do
|
|
29
|
+
with_input_field_for @user, :age
|
|
28
30
|
|
|
29
|
-
assert_select 'input.
|
|
31
|
+
assert_select 'input[type=number].integer#user_age'
|
|
30
32
|
end
|
|
31
33
|
|
|
32
|
-
test 'builder input_field
|
|
33
|
-
|
|
34
|
+
test 'builder input_field is able to disable any component' do
|
|
35
|
+
with_input_field_for @user, :age, html5: false
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
assert_no_select 'input[html5=false]#user_age'
|
|
38
|
+
assert_select 'input[type=text].integer#user_age'
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test 'builder input_field allows passing options to input tag' do
|
|
42
|
+
with_input_field_for @user, :name, id: 'name_input', class: 'name'
|
|
38
43
|
|
|
39
44
|
assert_select 'input.string.name#name_input'
|
|
40
|
-
assert_equal({ :id => 'name_input', :class => 'name' }, options)
|
|
41
45
|
end
|
|
42
46
|
|
|
47
|
+
test 'builder input_field does not modify the options hash' do
|
|
48
|
+
options = { id: 'name_input', class: 'name' }
|
|
49
|
+
with_input_field_for @user, :name, options
|
|
43
50
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
51
|
+
assert_select 'input.string.name#name_input'
|
|
52
|
+
assert_equal({ id: 'name_input', class: 'name' }, options)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
test 'builder input_field generates an input tag with a clean HTML' do
|
|
57
|
+
with_input_field_for @user, :name, as: :integer, class: 'name'
|
|
48
58
|
|
|
49
59
|
assert_no_select 'input.integer[input_html]'
|
|
50
60
|
assert_no_select 'input.integer[as]'
|
|
51
61
|
end
|
|
52
62
|
|
|
53
|
-
test 'builder
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
test 'builder input_field uses i18n to translate placeholder text' do
|
|
64
|
+
store_translations(:en, simple_form: { placeholders: { user: {
|
|
65
|
+
name: 'Name goes here'
|
|
66
|
+
} } }) do
|
|
67
|
+
with_input_field_for @user, :name
|
|
68
|
+
|
|
69
|
+
assert_select 'input.string[placeholder="Name goes here"]'
|
|
56
70
|
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
test 'builder input_field uses min_max component' do
|
|
74
|
+
with_input_field_for @other_validating_user, :age, as: :integer
|
|
75
|
+
|
|
76
|
+
assert_select 'input[min="18"]'
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
test 'builder input_field does not use pattern component by default' do
|
|
80
|
+
with_input_field_for @other_validating_user, :country, as: :string
|
|
81
|
+
|
|
82
|
+
assert_no_select 'input[pattern="\w+"]'
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
test 'builder input_field infers pattern from attributes' do
|
|
86
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: true
|
|
87
|
+
|
|
88
|
+
assert_select 'input[pattern="\w+"]'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
test 'builder input_field accepts custom pattern' do
|
|
92
|
+
with_input_field_for @other_validating_user, :country, as: :string, pattern: '\d+'
|
|
93
|
+
|
|
94
|
+
assert_select 'input[pattern="\d+"]'
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
test 'builder input_field uses readonly component' do
|
|
98
|
+
with_input_field_for @other_validating_user, :age, as: :integer, readonly: true
|
|
99
|
+
|
|
100
|
+
assert_select 'input.integer.readonly[readonly]'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
test 'builder input_field uses maxlength component' do
|
|
104
|
+
with_input_field_for @validating_user, :name, as: :string
|
|
105
|
+
|
|
106
|
+
assert_select 'input.string[maxlength="25"]'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
test 'builder input_field uses minlength component' do
|
|
110
|
+
with_input_field_for @validating_user, :name, as: :string
|
|
111
|
+
|
|
112
|
+
assert_select 'input.string[minlength="5"]'
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
test 'builder collection input_field generates input tag with a clean HTML' do
|
|
116
|
+
with_input_field_for @user, :status, collection: %w[Open Closed],
|
|
117
|
+
class: 'status', label_method: :to_s, value_method: :to_s
|
|
57
118
|
|
|
58
119
|
assert_no_select 'select.status[input_html]'
|
|
59
120
|
assert_no_select 'select.status[collection]'
|
|
60
121
|
assert_no_select 'select.status[label_method]'
|
|
61
122
|
assert_no_select 'select.status[value_method]'
|
|
62
123
|
end
|
|
124
|
+
|
|
125
|
+
test 'build input_field does not treat "boolean_style" as a HTML attribute' do
|
|
126
|
+
with_input_field_for @user, :active, boolean_style: :nested
|
|
127
|
+
|
|
128
|
+
assert_no_select 'input.boolean[boolean_style]'
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
test 'build input_field does not treat "prompt" as a HTML attribute' do
|
|
132
|
+
with_input_field_for @user, :attempts, collection: [1,2,3,4,5], prompt: :translate
|
|
133
|
+
|
|
134
|
+
assert_no_select 'select[prompt]'
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
test 'build input_field without pattern component use the pattern string' do
|
|
138
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
|
139
|
+
with_input_field_for @user, :name, pattern: '\w+'
|
|
140
|
+
|
|
141
|
+
assert_select 'input[pattern="\w+"]'
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
test 'build input_field without placeholder component use the placeholder string' do
|
|
146
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
|
147
|
+
with_input_field_for @user, :name, placeholder: 'Placeholder'
|
|
148
|
+
|
|
149
|
+
assert_select 'input[placeholder="Placeholder"]'
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
test 'build input_field without maxlength component use the maxlength string' do
|
|
154
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
|
155
|
+
with_input_field_for @user, :name, maxlength: 5
|
|
156
|
+
|
|
157
|
+
assert_select 'input[maxlength="5"]'
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
test 'build input_field without minlength component use the minlength string' do
|
|
162
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
|
163
|
+
with_input_field_for @user, :name, minlength: 5
|
|
164
|
+
|
|
165
|
+
assert_select 'input[minlength="5"]'
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
test 'build input_field without readonly component use the readonly string' do
|
|
170
|
+
swap_wrapper :default, custom_wrapper_with_html5_components do
|
|
171
|
+
with_input_field_for @user, :name, readonly: true
|
|
172
|
+
|
|
173
|
+
assert_select 'input[readonly="readonly"]'
|
|
174
|
+
end
|
|
175
|
+
end
|
|
63
176
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
1
2
|
# encoding: UTF-8
|
|
2
3
|
require 'test_helper'
|
|
3
4
|
|
|
@@ -8,47 +9,78 @@ class LabelTest < ActionView::TestCase
|
|
|
8
9
|
end
|
|
9
10
|
end
|
|
10
11
|
|
|
11
|
-
test 'builder
|
|
12
|
+
test 'builder generates a label for the attribute' do
|
|
12
13
|
with_label_for @user, :name
|
|
13
14
|
assert_select 'label.string[for=user_name]', /Name/
|
|
14
15
|
end
|
|
15
16
|
|
|
16
|
-
test 'builder
|
|
17
|
+
test 'builder generates a label for the attribute with decorated object responsive to #to_model' do
|
|
18
|
+
with_label_for @decorated_user, :name
|
|
19
|
+
assert_select 'label.string[for=user_name]', /Name/
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
test 'builder generates a label for the boolean attrbiute' do
|
|
23
|
+
with_label_for @user, :name, as: :boolean
|
|
24
|
+
assert_select 'label.boolean[for=user_name]', /Name/
|
|
25
|
+
assert_no_select 'label[as=boolean]'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test 'builder generates a label component tag with a clean HTML' do
|
|
17
29
|
with_label_for @user, :name
|
|
18
30
|
assert_no_select 'label.string[label_html]'
|
|
19
31
|
end
|
|
20
32
|
|
|
21
|
-
test 'builder
|
|
33
|
+
test 'builder adds a required class to label if the attribute is required' do
|
|
22
34
|
with_label_for @validating_user, :name
|
|
23
35
|
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
|
24
36
|
end
|
|
25
37
|
|
|
26
|
-
test 'builder
|
|
27
|
-
with_label_for @
|
|
38
|
+
test 'builder adds a disabled class to label if the attribute is disabled' do
|
|
39
|
+
with_label_for @validating_user, :name, disabled: true
|
|
40
|
+
assert_select 'label.string.disabled[for=validating_user_name]', /Name/
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
test 'builder does not add a disabled class to label if the attribute is not disabled' do
|
|
44
|
+
with_label_for @validating_user, :name, disabled: false
|
|
45
|
+
assert_no_select 'label.string.disabled[for=validating_user_name]', /Name/
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
test 'builder escapes label text' do
|
|
49
|
+
with_label_for @user, :name, label: '<script>alert(1337)</script>', required: false
|
|
50
|
+
assert_no_select 'label.string script'
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
test 'builder does not escape label text if it is safe' do
|
|
54
|
+
with_label_for @user, :name, label: '<script>alert(1337)</script>'.html_safe, required: false
|
|
55
|
+
assert_select 'label.string script', "alert(1337)"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'builder allows passing options to label tag' do
|
|
59
|
+
with_label_for @user, :name, label: 'My label', id: 'name_label'
|
|
28
60
|
assert_select 'label.string#name_label', /My label/
|
|
29
61
|
end
|
|
30
62
|
|
|
31
|
-
test 'builder label
|
|
32
|
-
with_label_for @user, :name, :
|
|
63
|
+
test 'builder label generates label tag with clean HTML' do
|
|
64
|
+
with_label_for @user, :name, label: 'My label', required: true, id: 'name_label'
|
|
33
65
|
assert_select 'label.string#name_label', /My label/
|
|
34
66
|
assert_no_select 'label[label]'
|
|
35
67
|
assert_no_select 'label[required]'
|
|
36
68
|
end
|
|
37
69
|
|
|
38
|
-
test 'builder
|
|
39
|
-
options = { :
|
|
70
|
+
test 'builder does not modify the options hash' do
|
|
71
|
+
options = { label: 'My label', id: 'name_label' }
|
|
40
72
|
with_label_for @user, :name, options
|
|
41
73
|
assert_select 'label.string#name_label', /My label/
|
|
42
|
-
assert_equal({ :
|
|
74
|
+
assert_equal({ label: 'My label', id: 'name_label' }, options)
|
|
43
75
|
end
|
|
44
76
|
|
|
45
|
-
test 'builder
|
|
77
|
+
test 'builder fallbacks to default label when string is given' do
|
|
46
78
|
with_label_for @user, :name, 'Nome do usuário'
|
|
47
79
|
assert_select 'label', 'Nome do usuário'
|
|
48
80
|
assert_no_select 'label.string'
|
|
49
81
|
end
|
|
50
82
|
|
|
51
|
-
test 'builder
|
|
83
|
+
test 'builder fallbacks to default label when block is given' do
|
|
52
84
|
with_label_for @user, :name do
|
|
53
85
|
'Nome do usuário'
|
|
54
86
|
end
|
|
@@ -57,9 +89,48 @@ class LabelTest < ActionView::TestCase
|
|
|
57
89
|
end
|
|
58
90
|
|
|
59
91
|
test 'builder allows label order to be changed' do
|
|
60
|
-
swap SimpleForm, :
|
|
92
|
+
swap SimpleForm, label_text: proc { |l, r| "#{l}:" } do
|
|
61
93
|
with_label_for @user, :age
|
|
62
94
|
assert_select 'label.integer[for=user_age]', "Age:"
|
|
63
95
|
end
|
|
64
96
|
end
|
|
97
|
+
|
|
98
|
+
test 'configuration allow set label text for wrappers' do
|
|
99
|
+
swap_wrapper :default, custom_wrapper_with_label_text do
|
|
100
|
+
with_concat_form_for(@user) do |f|
|
|
101
|
+
concat f.input :age
|
|
102
|
+
end
|
|
103
|
+
assert_select "label.integer[for=user_age]", "**Age**"
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
test 'configuration allow set rewrited label tag for wrappers' do
|
|
108
|
+
swap_wrapper :default, custom_wrapper_with_custom_label_component do
|
|
109
|
+
with_concat_form_for(@user) do |f|
|
|
110
|
+
concat f.input :age
|
|
111
|
+
end
|
|
112
|
+
assert_select "span.integer.user_age", /Age/
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
test 'builder allows custom formatting when label is explicitly specified' do
|
|
117
|
+
swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : "#{l.titleize}:" } do
|
|
118
|
+
with_label_for @user, :time_zone, 'What is your home time zone?'
|
|
119
|
+
assert_select 'label[for=user_time_zone]', 'What is your home time zone?'
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
test 'builder allows custom formatting when label is generated' do
|
|
124
|
+
swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : "#{l.titleize}:" } do
|
|
125
|
+
with_label_for @user, :time_zone
|
|
126
|
+
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
test 'builder allows label specific `label_text` option' do
|
|
131
|
+
with_label_for @user, :time_zone, label_text: ->(l, _, _) { "#{l.titleize}:" }
|
|
132
|
+
|
|
133
|
+
assert_no_select 'label[label_text]'
|
|
134
|
+
assert_select 'label[for=user_time_zone]', 'Time Zone:'
|
|
135
|
+
end
|
|
65
136
|
end
|