simple_form 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +22 -32
- data/README.md +161 -119
- data/lib/generators/simple_form/install_generator.rb +3 -3
- data/lib/generators/simple_form/templates/README +1 -1
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +16 -13
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +14 -14
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +3 -3
- data/lib/simple_form/action_view_extensions/builder.rb +1 -319
- data/lib/simple_form/action_view_extensions/form_helper.rb +2 -9
- data/lib/simple_form/components/html5.rb +5 -2
- data/lib/simple_form/components/labels.rb +3 -3
- data/lib/simple_form/components/maxlength.rb +1 -8
- data/lib/simple_form/components/pattern.rb +2 -2
- data/lib/simple_form/components.rb +1 -1
- data/lib/simple_form/error_notification.rb +2 -2
- data/lib/simple_form/form_builder.rb +155 -51
- data/lib/simple_form/helpers.rb +1 -1
- data/lib/simple_form/inputs/base.rb +6 -6
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +6 -4
- data/lib/simple_form/inputs/collection_input.rb +6 -6
- data/lib/simple_form/inputs/date_time_input.rb +1 -1
- data/lib/simple_form/inputs/numeric_input.rb +0 -6
- data/lib/simple_form/inputs/password_input.rb +0 -1
- data/lib/simple_form/inputs/string_input.rb +0 -1
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +62 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers/builder.rb +5 -29
- data/lib/simple_form/wrappers/many.rb +1 -1
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers.rb +1 -1
- data/lib/simple_form.rb +43 -47
- data/test/action_view_extensions/builder_test.rb +78 -92
- data/test/action_view_extensions/form_helper_test.rb +25 -16
- data/test/components/label_test.rb +46 -46
- data/test/form_builder/association_test.rb +47 -29
- data/test/form_builder/button_test.rb +4 -4
- data/test/form_builder/error_notification_test.rb +8 -8
- data/test/form_builder/error_test.rb +12 -12
- data/test/form_builder/general_test.rb +71 -52
- data/test/form_builder/hint_test.rb +22 -22
- data/test/form_builder/input_field_test.rb +29 -12
- data/test/form_builder/label_test.rb +7 -7
- data/test/form_builder/wrapper_test.rb +21 -21
- data/test/inputs/boolean_input_test.rb +35 -23
- data/test/inputs/collection_check_boxes_input_test.rb +66 -55
- data/test/inputs/collection_radio_buttons_input_test.rb +81 -79
- data/test/inputs/collection_select_input_test.rb +76 -45
- data/test/inputs/datetime_input_test.rb +17 -11
- data/test/inputs/disabled_test.rb +10 -10
- data/test/inputs/discovery_test.rb +4 -4
- data/test/inputs/file_input_test.rb +1 -1
- data/test/inputs/general_test.rb +28 -12
- data/test/inputs/grouped_collection_select_input_test.rb +33 -20
- data/test/inputs/hidden_input_test.rb +3 -2
- data/test/inputs/numeric_input_test.rb +3 -3
- data/test/inputs/priority_input_test.rb +9 -3
- data/test/inputs/readonly_test.rb +12 -12
- data/test/inputs/required_test.rb +5 -5
- data/test/inputs/string_input_test.rb +15 -25
- data/test/inputs/text_input_test.rb +1 -1
- data/test/support/misc_helpers.rb +46 -24
- data/test/support/mock_controller.rb +6 -6
- data/test/support/models.rb +80 -62
- data/test/test_helper.rb +17 -34
- metadata +31 -29
- data/lib/simple_form/core_ext/hash.rb +0 -16
@@ -4,8 +4,8 @@ require 'test_helper'
|
|
4
4
|
class GroupedCollectionSelectInputTest < ActionView::TestCase
|
5
5
|
test 'grouped collection accepts array collection form' do
|
6
6
|
with_input_for @user, :tag_ids, :grouped_select,
|
7
|
-
:
|
8
|
-
:
|
7
|
+
collection: [['Authors', ['Jose', 'Carlos']], ['General', ['Bob', 'John']]],
|
8
|
+
group_method: :last
|
9
9
|
|
10
10
|
assert_select 'select.grouped_select#user_tag_ids' do
|
11
11
|
assert_select 'optgroup[label=Authors]' do
|
@@ -22,8 +22,8 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
22
22
|
|
23
23
|
test 'grouped collection accepts empty array collection form' do
|
24
24
|
with_input_for @user, :tag_ids, :grouped_select,
|
25
|
-
:
|
26
|
-
:
|
25
|
+
collection: [],
|
26
|
+
group_method: :last
|
27
27
|
|
28
28
|
assert_select 'select.grouped_select#user_tag_ids'
|
29
29
|
end
|
@@ -31,8 +31,8 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
31
31
|
|
32
32
|
test 'grouped collection accepts proc as collection' do
|
33
33
|
with_input_for @user, :tag_ids, :grouped_select,
|
34
|
-
:
|
35
|
-
:
|
34
|
+
collection: Proc.new { [['Authors', ['Jose', 'Carlos']], ['General', ['Bob', 'John']]] },
|
35
|
+
group_method: :last
|
36
36
|
|
37
37
|
assert_select 'select.grouped_select#user_tag_ids' do
|
38
38
|
assert_select 'optgroup[label=Authors]' do
|
@@ -49,8 +49,8 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
49
49
|
|
50
50
|
test 'grouped collection accepts hash collection form' do
|
51
51
|
with_input_for @user, :tag_ids, :grouped_select,
|
52
|
-
:
|
53
|
-
:
|
52
|
+
collection: { 'Authors' => ['Jose', 'Carlos'], 'General' => ['Bob', 'John'] },
|
53
|
+
group_method: :last
|
54
54
|
|
55
55
|
assert_select 'select.grouped_select#user_tag_ids' do
|
56
56
|
assert_select 'optgroup[label=Authors]' do
|
@@ -67,9 +67,9 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
67
67
|
|
68
68
|
test 'grouped collection accepts group_label_method option' do
|
69
69
|
with_input_for @user, :tag_ids, :grouped_select,
|
70
|
-
:
|
71
|
-
:
|
72
|
-
:
|
70
|
+
collection: { ['Jose', 'Carlos'] => 'Authors' },
|
71
|
+
group_method: :first,
|
72
|
+
group_label_method: :last
|
73
73
|
|
74
74
|
assert_select 'select.grouped_select#user_tag_ids' do
|
75
75
|
assert_select 'optgroup[label=Authors]' do
|
@@ -81,10 +81,10 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
81
81
|
|
82
82
|
test 'grouped collection accepts label and value methods options' do
|
83
83
|
with_input_for @user, :tag_ids, :grouped_select,
|
84
|
-
:
|
85
|
-
:
|
86
|
-
:
|
87
|
-
:
|
84
|
+
collection: { 'Authors' => ['Jose', 'Carlos'] },
|
85
|
+
group_method: :last,
|
86
|
+
label_method: :upcase,
|
87
|
+
value_method: :downcase
|
88
88
|
|
89
89
|
assert_select 'select.grouped_select#user_tag_ids' do
|
90
90
|
assert_select 'optgroup[label=Authors]' do
|
@@ -96,10 +96,10 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
96
96
|
|
97
97
|
test 'grouped collection should allow overriding label and value methods using a lambda' do
|
98
98
|
with_input_for @user, :tag_ids, :grouped_select,
|
99
|
-
:
|
100
|
-
:
|
101
|
-
:
|
102
|
-
:
|
99
|
+
collection: { 'Authors' => ['Jose', 'Carlos'] },
|
100
|
+
group_method: :last,
|
101
|
+
label_method: lambda { |i| i.upcase },
|
102
|
+
value_method: lambda { |i| i.downcase }
|
103
103
|
|
104
104
|
assert_select 'select.grouped_select#user_tag_ids' do
|
105
105
|
assert_select 'optgroup[label=Authors]' do
|
@@ -116,7 +116,7 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
116
116
|
]
|
117
117
|
|
118
118
|
with_input_for @user, :tag_ids, :grouped_select,
|
119
|
-
:
|
119
|
+
collection: tag_groups, group_method: :tags
|
120
120
|
|
121
121
|
assert_select 'select.grouped_select#user_tag_ids' do
|
122
122
|
assert_select 'optgroup[label=Group of Tags]' do
|
@@ -130,4 +130,17 @@ class GroupedCollectionSelectInputTest < ActionView::TestCase
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
end
|
133
|
+
|
134
|
+
test 'grouped collection should accept html options as the last element of collection' do
|
135
|
+
with_input_for @user, :tag_ids, :grouped_select,
|
136
|
+
collection: [['Authors', [['Jose', 'jose', class: 'foo'], ['Carlos', 'carlos', class: 'bar']]]],
|
137
|
+
group_method: :last
|
138
|
+
|
139
|
+
assert_select 'select.grouped_select#user_tag_ids' do
|
140
|
+
assert_select 'optgroup[label=Authors]' do
|
141
|
+
assert_select 'option.foo', 'Jose'
|
142
|
+
assert_select 'option.bar', 'Carlos'
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
133
146
|
end
|
@@ -9,7 +9,7 @@ class HiddenInputTest < ActionView::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
test 'hint should not be generated for hidden fields' do
|
12
|
-
store_translations(:en, :
|
12
|
+
store_translations(:en, simple_form: { hints: { user: { name: "text" } } }) do
|
13
13
|
with_input_for @user, :name, :hidden
|
14
14
|
assert_no_select 'span.hint'
|
15
15
|
end
|
@@ -20,10 +20,11 @@ class HiddenInputTest < ActionView::TestCase
|
|
20
20
|
assert_no_select 'label'
|
21
21
|
end
|
22
22
|
|
23
|
-
test 'required/optional options should not be generated for hidden inputs' do
|
23
|
+
test 'required/aria-required/optional options should not be generated for hidden inputs' do
|
24
24
|
with_input_for @user, :name, :hidden
|
25
25
|
assert_no_select 'input.required'
|
26
26
|
assert_no_select 'input[required]'
|
27
|
+
assert_no_select 'input[aria-required]'
|
27
28
|
assert_no_select 'input.optional'
|
28
29
|
assert_select 'input.hidden#user_name'
|
29
30
|
end
|
@@ -121,13 +121,13 @@ class NumericInputTest < ActionView::TestCase
|
|
121
121
|
end
|
122
122
|
|
123
123
|
test 'numeric input should accept the placeholder option' do
|
124
|
-
with_input_for @user, :age, :integer, :
|
124
|
+
with_input_for @user, :age, :integer, placeholder: 'Put in your age'
|
125
125
|
assert_select 'input.integer[placeholder=Put in your age]'
|
126
126
|
end
|
127
127
|
|
128
128
|
test 'numeric input should use i18n to translate placeholder text' do
|
129
|
-
store_translations(:en, :
|
130
|
-
:
|
129
|
+
store_translations(:en, simple_form: { placeholders: { user: {
|
130
|
+
age: 'Age goes here'
|
131
131
|
} } }) do
|
132
132
|
with_input_for @user, :age, :integer
|
133
133
|
assert_select 'input.integer[placeholder=Age goes here]'
|
@@ -10,7 +10,7 @@ class PriorityInputTest < ActionView::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
test 'input should generate a country select with SimpleForm default' do
|
13
|
-
swap SimpleForm, :
|
13
|
+
swap SimpleForm, country_priority: [ 'Brazil' ] do
|
14
14
|
with_input_for @user, :country, :country
|
15
15
|
assert_select 'select option[value=][disabled=disabled]'
|
16
16
|
end
|
@@ -24,13 +24,13 @@ class PriorityInputTest < ActionView::TestCase
|
|
24
24
|
end
|
25
25
|
|
26
26
|
test 'input should generate a time zone select field with default' do
|
27
|
-
with_input_for @user, :time_zone, :time_zone, :
|
27
|
+
with_input_for @user, :time_zone, :time_zone, default: 'Brasilia'
|
28
28
|
assert_select 'select option[value=Brasilia][selected=selected]'
|
29
29
|
assert_no_select 'select option[value=]'
|
30
30
|
end
|
31
31
|
|
32
32
|
test 'input should generate a time zone select using options priority' do
|
33
|
-
with_input_for @user, :time_zone, :time_zone, :
|
33
|
+
with_input_for @user, :time_zone, :time_zone, priority: /Brasilia/
|
34
34
|
assert_select 'select option[value=][disabled=disabled]'
|
35
35
|
assert_no_select 'select option[value=]', /^$/
|
36
36
|
end
|
@@ -40,4 +40,10 @@ class PriorityInputTest < ActionView::TestCase
|
|
40
40
|
assert_select 'select.required'
|
41
41
|
assert_no_select 'select[required]'
|
42
42
|
end
|
43
|
+
|
44
|
+
test 'priority input should not generate invalid aria-required html attribute' do
|
45
|
+
with_input_for @user, :country, :country
|
46
|
+
assert_select 'select.required'
|
47
|
+
assert_no_select 'select[aria-required]'
|
48
|
+
end
|
43
49
|
end
|
@@ -2,52 +2,52 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class ReadonlyTest < ActionView::TestCase
|
4
4
|
test 'string input should generate readonly elements when readonly option is true' do
|
5
|
-
with_input_for @user, :name, :string, :
|
5
|
+
with_input_for @user, :name, :string, readonly: true
|
6
6
|
assert_select 'input.string.readonly[readonly]'
|
7
7
|
end
|
8
8
|
|
9
9
|
test 'text input should generate readonly elements when readonly option is true' do
|
10
|
-
with_input_for @user, :description, :text, :
|
10
|
+
with_input_for @user, :description, :text, readonly: true
|
11
11
|
assert_select 'textarea.text.readonly[readonly]'
|
12
12
|
end
|
13
13
|
|
14
14
|
test 'numeric input should generate readonly elements when readonly option is true' do
|
15
|
-
with_input_for @user, :age, :integer, :
|
15
|
+
with_input_for @user, :age, :integer, readonly: true
|
16
16
|
assert_select 'input.integer.readonly[readonly]'
|
17
17
|
end
|
18
18
|
|
19
19
|
test 'date input should generate readonly elements when readonly option is true' do
|
20
|
-
with_input_for @user, :born_at, :date, :
|
20
|
+
with_input_for @user, :born_at, :date, readonly: true
|
21
21
|
assert_select 'select.date.readonly[readonly]'
|
22
22
|
end
|
23
23
|
|
24
24
|
test 'datetime input should generate readonly elements when readonly option is true' do
|
25
|
-
with_input_for @user, :created_at, :datetime, :
|
25
|
+
with_input_for @user, :created_at, :datetime, readonly: true
|
26
26
|
assert_select 'select.datetime.readonly[readonly]'
|
27
27
|
end
|
28
28
|
|
29
29
|
test 'string input should generate readonly elements when readonly option is false' do
|
30
|
-
with_input_for @user, :name, :string, :
|
30
|
+
with_input_for @user, :name, :string, readonly: false
|
31
31
|
assert_no_select 'input.string.readonly[readonly]'
|
32
32
|
end
|
33
33
|
|
34
34
|
test 'text input should generate readonly elements when readonly option is false' do
|
35
|
-
with_input_for @user, :description, :text, :
|
35
|
+
with_input_for @user, :description, :text, readonly: false
|
36
36
|
assert_no_select 'textarea.text.readonly[readonly]'
|
37
37
|
end
|
38
38
|
|
39
39
|
test 'numeric input should generate readonly elements when readonly option is false' do
|
40
|
-
with_input_for @user, :age, :integer, :
|
40
|
+
with_input_for @user, :age, :integer, readonly: false
|
41
41
|
assert_no_select 'input.integer.readonly[readonly]'
|
42
42
|
end
|
43
43
|
|
44
44
|
test 'date input should generate readonly elements when readonly option is false' do
|
45
|
-
with_input_for @user, :born_at, :date, :
|
45
|
+
with_input_for @user, :born_at, :date, readonly: false
|
46
46
|
assert_no_select 'select.date.readonly[readonly]'
|
47
47
|
end
|
48
48
|
|
49
49
|
test 'datetime input should generate readonly elements when readonly option is false' do
|
50
|
-
with_input_for @user, :created_at, :datetime, :
|
50
|
+
with_input_for @user, :created_at, :datetime, readonly: false
|
51
51
|
assert_no_select 'select.datetime.readonly[readonly]'
|
52
52
|
end
|
53
53
|
|
@@ -77,13 +77,13 @@ class ReadonlyTest < ActionView::TestCase
|
|
77
77
|
end
|
78
78
|
|
79
79
|
test 'input should generate readonly attribute when the field is readonly and the object is persisted' do
|
80
|
-
with_input_for @user, :credit_card, :string, :
|
80
|
+
with_input_for @user, :credit_card, :string, readonly: :lookup
|
81
81
|
assert_select 'input.string.readonly[readonly]'
|
82
82
|
end
|
83
83
|
|
84
84
|
test 'input should not generate readonly attribute when the field is readonly and the object is not persisted' do
|
85
85
|
@user.new_record!
|
86
|
-
with_input_for @user, :credit_card, :string, :
|
86
|
+
with_input_for @user, :credit_card, :string, readonly: :lookup
|
87
87
|
assert_no_select 'input.string.readonly[readonly]'
|
88
88
|
end
|
89
89
|
|
@@ -10,9 +10,9 @@ class RequiredTest < ActionView::TestCase
|
|
10
10
|
end
|
11
11
|
|
12
12
|
test 'builder input should allow overriding required when ActiveModel::Validations is included' do
|
13
|
-
with_form_for @validating_user, :name, :
|
13
|
+
with_form_for @validating_user, :name, required: false
|
14
14
|
assert_select 'input.optional#validating_user_name'
|
15
|
-
with_form_for @validating_user, :status, :
|
15
|
+
with_form_for @validating_user, :status, required: true
|
16
16
|
assert_select 'input.required[required]#validating_user_status'
|
17
17
|
end
|
18
18
|
|
@@ -22,7 +22,7 @@ class RequiredTest < ActionView::TestCase
|
|
22
22
|
end
|
23
23
|
|
24
24
|
test 'builder input should not be required by default when ActiveModel::Validations is not included if option is set to false' do
|
25
|
-
swap SimpleForm, :
|
25
|
+
swap SimpleForm, required_by_default: false do
|
26
26
|
with_form_for @user, :name
|
27
27
|
assert_select 'input.optional#user_name'
|
28
28
|
assert_no_select 'input[required]'
|
@@ -30,7 +30,7 @@ class RequiredTest < ActionView::TestCase
|
|
30
30
|
end
|
31
31
|
|
32
32
|
test 'when not using browser validations, input should not generate required html attribute' do
|
33
|
-
swap SimpleForm, :
|
33
|
+
swap SimpleForm, browser_validations: false do
|
34
34
|
with_input_for @user, :name, :string
|
35
35
|
assert_select 'input[type=text].required'
|
36
36
|
assert_no_select 'input[type=text][required]'
|
@@ -38,7 +38,7 @@ class RequiredTest < ActionView::TestCase
|
|
38
38
|
end
|
39
39
|
|
40
40
|
test 'builder input should allow disabling required when ActiveModel::Validations is not included' do
|
41
|
-
with_form_for @user, :name, :
|
41
|
+
with_form_for @user, :name, required: false
|
42
42
|
assert_no_select 'input.required'
|
43
43
|
assert_no_select 'input[required]'
|
44
44
|
assert_select 'input.optional#user_name'
|
@@ -12,11 +12,6 @@ class StringInputTest < ActionView::TestCase
|
|
12
12
|
assert_select "input#user_password.password[type=password][name='user[password]']"
|
13
13
|
end
|
14
14
|
|
15
|
-
test 'input should not use size attribute for decimal attributes' do
|
16
|
-
with_input_for @user, :credit_limit, :decimal
|
17
|
-
assert_no_select 'input.decimal[size]'
|
18
|
-
end
|
19
|
-
|
20
15
|
test 'input should get maxlength from column definition for string attributes' do
|
21
16
|
with_input_for @user, :name, :string
|
22
17
|
assert_select 'input.string[maxlength=100]'
|
@@ -27,16 +22,6 @@ class StringInputTest < ActionView::TestCase
|
|
27
22
|
assert_no_select 'input.string[maxlength]'
|
28
23
|
end
|
29
24
|
|
30
|
-
test 'input should get size from column definition for string attributes respecting maximum value' do
|
31
|
-
with_input_for @user, :name, :string
|
32
|
-
assert_select 'input.string[size=50]'
|
33
|
-
end
|
34
|
-
|
35
|
-
test 'input should use default text size for password attributes' do
|
36
|
-
with_input_for @user, :password, :password
|
37
|
-
assert_select 'input.password[type=password][size=50]'
|
38
|
-
end
|
39
|
-
|
40
25
|
test 'input should get maxlength from column definition for password attributes' do
|
41
26
|
with_input_for @user, :password, :password
|
42
27
|
assert_select 'input.password[type=password][maxlength=100]'
|
@@ -57,10 +42,10 @@ class StringInputTest < ActionView::TestCase
|
|
57
42
|
assert_select 'input.string[maxlength=12]'
|
58
43
|
end
|
59
44
|
|
60
|
-
test 'input
|
45
|
+
test 'input maxlength should be the column limit plus one to make room for decimal point' do
|
61
46
|
with_input_for @user, :credit_limit, :string
|
62
47
|
|
63
|
-
assert_select "input.string[maxlength=16]
|
48
|
+
assert_select "input.string[maxlength=16]"
|
64
49
|
end
|
65
50
|
|
66
51
|
test 'input should not generate placeholder by default' do
|
@@ -69,12 +54,12 @@ class StringInputTest < ActionView::TestCase
|
|
69
54
|
end
|
70
55
|
|
71
56
|
test 'input should accept the placeholder option' do
|
72
|
-
with_input_for @user, :name, :string, :
|
57
|
+
with_input_for @user, :name, :string, placeholder: 'Put in some text'
|
73
58
|
assert_select 'input.string[placeholder=Put in some text]'
|
74
59
|
end
|
75
60
|
|
76
61
|
test 'input should generate a password field for password attributes that accept placeholder' do
|
77
|
-
with_input_for @user, :password, :password, :
|
62
|
+
with_input_for @user, :password, :password, placeholder: 'Password Confirmation'
|
78
63
|
assert_select 'input[type=password].password[placeholder=Password Confirmation]#user_password'
|
79
64
|
end
|
80
65
|
|
@@ -84,12 +69,12 @@ class StringInputTest < ActionView::TestCase
|
|
84
69
|
end
|
85
70
|
|
86
71
|
test 'input should infer pattern from attributes' do
|
87
|
-
with_input_for @other_validating_user, :country, :string, :
|
72
|
+
with_input_for @other_validating_user, :country, :string, pattern: true
|
88
73
|
assert_select 'input[pattern="\w+"]'
|
89
74
|
end
|
90
75
|
|
91
76
|
test 'input should infer pattern from attributes using proc' do
|
92
|
-
with_input_for @other_validating_user, :name, :string, :
|
77
|
+
with_input_for @other_validating_user, :name, :string, pattern: true
|
93
78
|
assert_select 'input[pattern="\w+"]'
|
94
79
|
end
|
95
80
|
|
@@ -101,13 +86,18 @@ class StringInputTest < ActionView::TestCase
|
|
101
86
|
end
|
102
87
|
|
103
88
|
test 'input should use given pattern from attributes' do
|
104
|
-
with_input_for @other_validating_user, :country, :string, :
|
89
|
+
with_input_for @other_validating_user, :country, :string, input_html: { pattern: "\\d+" }
|
105
90
|
assert_select 'input[pattern="\d+"]'
|
106
91
|
end
|
107
92
|
|
93
|
+
test 'input should not use pattern if model has :without validation option' do
|
94
|
+
with_input_for @other_validating_user, :description, :string, pattern: true
|
95
|
+
assert_no_select 'input[pattern="\d+"]'
|
96
|
+
end
|
97
|
+
|
108
98
|
test 'input should use i18n to translate placeholder text' do
|
109
|
-
store_translations(:en, :
|
110
|
-
:
|
99
|
+
store_translations(:en, simple_form: { placeholders: { user: {
|
100
|
+
name: 'Name goes here'
|
111
101
|
} } }) do
|
112
102
|
with_input_for @user, :name, :string
|
113
103
|
assert_select 'input.string[placeholder=Name goes here]'
|
@@ -138,7 +128,7 @@ class StringInputTest < ActionView::TestCase
|
|
138
128
|
end
|
139
129
|
|
140
130
|
test 'input strips extra spaces from class html attribute when giving a custom class' do
|
141
|
-
with_input_for @user, :name, :string, :
|
131
|
+
with_input_for @user, :name, :string, input_html: { class: "my_input" }
|
142
132
|
assert_select "input[class='string required my_input']"
|
143
133
|
assert_no_select "input[class='string required my_input ']"
|
144
134
|
assert_no_select "input[class=' string required my_input']"
|
@@ -8,7 +8,7 @@ class TextInputTest < ActionView::TestCase
|
|
8
8
|
end
|
9
9
|
|
10
10
|
test 'input should generate a text area for text attributes that accept placeholder' do
|
11
|
-
with_input_for @user, :description, :text, :
|
11
|
+
with_input_for @user, :description, :text, placeholder: 'Put in some text'
|
12
12
|
assert_select 'textarea.text[placeholder=Put in some text]'
|
13
13
|
end
|
14
14
|
|
@@ -8,7 +8,7 @@ module MiscHelpers
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def assert_no_select(selector, value = nil)
|
11
|
-
assert_select(selector, :
|
11
|
+
assert_select(selector, text: value, count: 0)
|
12
12
|
end
|
13
13
|
|
14
14
|
def swap(object, new_values)
|
@@ -24,6 +24,28 @@ module MiscHelpers
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
def stub_any_instance(klass, method, value)
|
28
|
+
klass.class_eval do
|
29
|
+
alias_method :"new_#{method}", method
|
30
|
+
|
31
|
+
define_method(method) do
|
32
|
+
if value.respond_to?(:call)
|
33
|
+
value.call
|
34
|
+
else
|
35
|
+
value
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
yield
|
41
|
+
ensure
|
42
|
+
klass.class_eval do
|
43
|
+
undef_method method
|
44
|
+
alias_method method, :"new_#{method}"
|
45
|
+
undef_method :"new_#{method}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
27
49
|
def swap_wrapper(name=:default, wrapper=self.custom_wrapper)
|
28
50
|
old = SimpleForm.wrappers[name]
|
29
51
|
SimpleForm.wrappers[name] = wrapper
|
@@ -33,69 +55,69 @@ module MiscHelpers
|
|
33
55
|
end
|
34
56
|
|
35
57
|
def custom_wrapper
|
36
|
-
SimpleForm.build :
|
58
|
+
SimpleForm.build tag: :section, class: "custom_wrapper", pattern: false do |b|
|
37
59
|
b.use :pattern
|
38
|
-
b.wrapper :another, :
|
60
|
+
b.wrapper :another, class: "another_wrapper" do |ba|
|
39
61
|
ba.use :label
|
40
62
|
ba.use :input
|
41
63
|
end
|
42
|
-
b.wrapper :error_wrapper, :
|
43
|
-
be.use :error, :
|
64
|
+
b.wrapper :error_wrapper, tag: :div, class: "error_wrapper" do |be|
|
65
|
+
be.use :error, wrap_with: { tag: :span, class: "omg_error" }
|
44
66
|
end
|
45
|
-
b.use :hint, :
|
67
|
+
b.use :hint, wrap_with: { class: "omg_hint" }
|
46
68
|
end
|
47
69
|
end
|
48
70
|
|
49
71
|
def custom_wrapper_with_wrapped_input
|
50
|
-
SimpleForm.build :
|
51
|
-
b.wrapper :
|
72
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
73
|
+
b.wrapper tag: :div, class: 'elem' do |component|
|
52
74
|
component.use :label
|
53
|
-
component.use :input, :
|
75
|
+
component.use :input, wrap_with: { tag: :div, class: 'input' }
|
54
76
|
end
|
55
77
|
end
|
56
78
|
end
|
57
79
|
|
58
80
|
def custom_wrapper_with_wrapped_label
|
59
|
-
SimpleForm.build :
|
60
|
-
b.wrapper :
|
61
|
-
component.use :label, :
|
81
|
+
SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
|
82
|
+
b.wrapper tag: :div, class: 'elem' do |component|
|
83
|
+
component.use :label, wrap_with: { tag: :div, class: 'label' }
|
62
84
|
component.use :input
|
63
85
|
end
|
64
86
|
end
|
65
87
|
end
|
66
88
|
|
67
89
|
def custom_wrapper_without_top_level
|
68
|
-
SimpleForm.build :
|
90
|
+
SimpleForm.build tag: false, class: 'custom_wrapper_without_top_level' do |b|
|
69
91
|
b.use :label_input
|
70
|
-
b.use :hint, :
|
71
|
-
b.use :error, :
|
92
|
+
b.use :hint, wrap_with: { tag: :span, class: :hint }
|
93
|
+
b.use :error, wrap_with: { tag: :span, class: :error }
|
72
94
|
end
|
73
95
|
end
|
74
96
|
|
75
97
|
def custom_wrapper_without_class
|
76
|
-
SimpleForm.build :
|
98
|
+
SimpleForm.build tag: :div, wrapper_html: { id: 'custom_wrapper_without_class' } do |b|
|
77
99
|
b.use :label_input
|
78
100
|
end
|
79
101
|
end
|
80
102
|
|
81
103
|
def custom_wrapper_with_label_html_option
|
82
|
-
SimpleForm.build :
|
104
|
+
SimpleForm.build tag: :div, class: "custom_wrapper", label_html: { class: 'extra-label-class' } do |b|
|
83
105
|
b.use :label_input
|
84
106
|
end
|
85
107
|
end
|
86
108
|
|
87
109
|
def custom_wrapper_with_wrapped_label_input
|
88
|
-
SimpleForm.build :
|
89
|
-
b.use :label_input, :
|
110
|
+
SimpleForm.build tag: :section, class: "custom_wrapper", pattern: false do |b|
|
111
|
+
b.use :label_input, wrap_with: { tag: :div, class: :field }
|
90
112
|
end
|
91
113
|
end
|
92
114
|
|
93
115
|
def custom_form_for(object, *args, &block)
|
94
|
-
simple_form_for(object, *
|
116
|
+
simple_form_for(object, *args, { builder: CustomFormBuilder }, &block)
|
95
117
|
end
|
96
118
|
|
97
119
|
def custom_mapping_form_for(object, *args, &block)
|
98
|
-
simple_form_for(object, *
|
120
|
+
simple_form_for(object, *args, { builder: CustomMapTypeFormBuilder }, &block)
|
99
121
|
end
|
100
122
|
|
101
123
|
def with_concat_form_for(*args, &block)
|
@@ -122,17 +144,17 @@ module MiscHelpers
|
|
122
144
|
|
123
145
|
def with_input_for(object, attribute_name, type, options={})
|
124
146
|
with_concat_form_for(object) do |f|
|
125
|
-
f.input(attribute_name, options.merge(:
|
147
|
+
f.input(attribute_name, options.merge(as: type))
|
126
148
|
end
|
127
149
|
end
|
128
150
|
end
|
129
151
|
|
130
152
|
class CustomFormBuilder < SimpleForm::FormBuilder
|
131
153
|
def input(attribute_name, *args, &block)
|
132
|
-
super(attribute_name, *
|
154
|
+
super(attribute_name, *args, { input_html: { class: 'custom' } }, &block)
|
133
155
|
end
|
134
156
|
end
|
135
157
|
|
136
158
|
class CustomMapTypeFormBuilder < SimpleForm::FormBuilder
|
137
|
-
map_type :custom_type, :
|
159
|
+
map_type :custom_type, to: SimpleForm::Inputs::StringInput
|
138
160
|
end
|
@@ -13,12 +13,12 @@ class MockController
|
|
13
13
|
"http://example.com"
|
14
14
|
end
|
15
15
|
|
16
|
-
def
|
17
|
-
|
16
|
+
def url_options
|
17
|
+
{}
|
18
18
|
end
|
19
19
|
|
20
|
-
def hash_for_user_path(*
|
21
|
-
def hash_for_validating_user_path(*
|
22
|
-
def hash_for_other_validating_user_path(*
|
23
|
-
def hash_for_users_path(*
|
20
|
+
def hash_for_user_path(*); end
|
21
|
+
def hash_for_validating_user_path(*); end
|
22
|
+
def hash_for_other_validating_user_path(*); end
|
23
|
+
def hash_for_users_path(*); end
|
24
24
|
end
|