simple_form 3.0.1 → 4.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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +149 -25
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +441 -107
  5. data/lib/generators/simple_form/install_generator.rb +4 -3
  6. data/lib/generators/simple_form/templates/README +4 -5
  7. data/lib/generators/simple_form/templates/_form.html.erb +2 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +2 -0
  9. data/lib/generators/simple_form/templates/_form.html.slim +1 -0
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +48 -11
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +417 -23
  12. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +101 -5
  13. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  14. data/lib/simple_form/action_view_extensions/builder.rb +2 -0
  15. data/lib/simple_form/action_view_extensions/form_helper.rb +10 -3
  16. data/lib/simple_form/components/errors.rb +38 -3
  17. data/lib/simple_form/components/hints.rb +3 -2
  18. data/lib/simple_form/components/html5.rb +16 -5
  19. data/lib/simple_form/components/label_input.rb +21 -2
  20. data/lib/simple_form/components/labels.rb +22 -11
  21. data/lib/simple_form/components/maxlength.rb +9 -5
  22. data/lib/simple_form/components/min_max.rb +2 -1
  23. data/lib/simple_form/components/minlength.rb +38 -0
  24. data/lib/simple_form/components/pattern.rb +2 -1
  25. data/lib/simple_form/components/placeholders.rb +4 -3
  26. data/lib/simple_form/components/readonly.rb +2 -1
  27. data/lib/simple_form/components.rb +2 -0
  28. data/lib/simple_form/error_notification.rb +1 -0
  29. data/lib/simple_form/form_builder.rb +193 -80
  30. data/lib/simple_form/helpers/autofocus.rb +1 -0
  31. data/lib/simple_form/helpers/disabled.rb +1 -0
  32. data/lib/simple_form/helpers/readonly.rb +1 -0
  33. data/lib/simple_form/helpers/required.rb +1 -0
  34. data/lib/simple_form/helpers/validators.rb +2 -1
  35. data/lib/simple_form/helpers.rb +6 -5
  36. data/lib/simple_form/i18n_cache.rb +1 -0
  37. data/lib/simple_form/inputs/base.rb +57 -14
  38. data/lib/simple_form/inputs/block_input.rb +2 -1
  39. data/lib/simple_form/inputs/boolean_input.rb +39 -16
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  41. data/lib/simple_form/inputs/collection_input.rb +37 -14
  42. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +9 -13
  43. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  44. data/lib/simple_form/inputs/date_time_input.rb +24 -9
  45. data/lib/simple_form/inputs/file_input.rb +5 -2
  46. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  47. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  48. data/lib/simple_form/inputs/numeric_input.rb +6 -4
  49. data/lib/simple_form/inputs/password_input.rb +6 -3
  50. data/lib/simple_form/inputs/priority_input.rb +5 -2
  51. data/lib/simple_form/inputs/range_input.rb +2 -1
  52. data/lib/simple_form/inputs/string_input.rb +6 -3
  53. data/lib/simple_form/inputs/text_input.rb +6 -3
  54. data/lib/simple_form/inputs.rb +1 -0
  55. data/lib/simple_form/map_type.rb +1 -0
  56. data/lib/simple_form/railtie.rb +8 -0
  57. data/lib/simple_form/tags.rb +7 -0
  58. data/lib/simple_form/version.rb +2 -1
  59. data/lib/simple_form/wrappers/builder.rb +7 -6
  60. data/lib/simple_form/wrappers/leaf.rb +29 -0
  61. data/lib/simple_form/wrappers/many.rb +7 -6
  62. data/lib/simple_form/wrappers/root.rb +3 -1
  63. data/lib/simple_form/wrappers/single.rb +7 -4
  64. data/lib/simple_form/wrappers.rb +2 -0
  65. data/lib/simple_form.rb +117 -18
  66. data/test/action_view_extensions/builder_test.rb +42 -41
  67. data/test/action_view_extensions/form_helper_test.rb +36 -16
  68. data/test/components/custom_components_test.rb +62 -0
  69. data/test/components/label_test.rb +70 -41
  70. data/test/form_builder/association_test.rb +79 -37
  71. data/test/form_builder/button_test.rb +11 -10
  72. data/test/form_builder/error_notification_test.rb +2 -1
  73. data/test/form_builder/error_test.rb +173 -24
  74. data/test/form_builder/general_test.rb +171 -73
  75. data/test/form_builder/hint_test.rb +24 -18
  76. data/test/form_builder/input_field_test.rb +132 -56
  77. data/test/form_builder/label_test.rb +68 -13
  78. data/test/form_builder/wrapper_test.rb +190 -22
  79. data/test/generators/simple_form_generator_test.rb +8 -7
  80. data/test/inputs/boolean_input_test.rb +89 -6
  81. data/test/inputs/collection_check_boxes_input_test.rb +109 -25
  82. data/test/inputs/collection_radio_buttons_input_test.rb +168 -54
  83. data/test/inputs/collection_select_input_test.rb +183 -77
  84. data/test/inputs/datetime_input_test.rb +131 -50
  85. data/test/inputs/disabled_test.rb +16 -15
  86. data/test/inputs/discovery_test.rb +58 -6
  87. data/test/inputs/file_input_test.rb +3 -2
  88. data/test/inputs/general_test.rb +23 -22
  89. data/test/inputs/grouped_collection_select_input_test.rb +54 -17
  90. data/test/inputs/hidden_input_test.rb +5 -4
  91. data/test/inputs/numeric_input_test.rb +48 -44
  92. data/test/inputs/priority_input_test.rb +23 -14
  93. data/test/inputs/readonly_test.rb +20 -19
  94. data/test/inputs/required_test.rb +58 -13
  95. data/test/inputs/string_input_test.rb +62 -33
  96. data/test/inputs/text_input_test.rb +20 -7
  97. data/test/simple_form_test.rb +9 -0
  98. data/test/support/discovery_inputs.rb +33 -2
  99. data/test/support/misc_helpers.rb +113 -5
  100. data/test/support/mock_controller.rb +7 -1
  101. data/test/support/models.rb +137 -37
  102. data/test/test_helper.rb +15 -1
  103. metadata +25 -33
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -8,12 +9,18 @@ class AssociationTest < ActionView::TestCase
8
9
  end
9
10
  end
10
11
 
11
- test 'builder should not allow creating an association input when no object exists' do
12
+ test 'builder does not allow creating an association input when no object exists' do
12
13
  assert_raise ArgumentError do
13
14
  with_association_for :post, :author
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|
@@ -46,9 +53,9 @@ class AssociationTest < ActionView::TestCase
46
53
 
47
54
  with_association_for @user, :tags
48
55
  assert_select 'form select.select#user_tag_ids'
49
- assert_select 'form select option[value=1]', 'Tag 1'
50
- assert_select 'form select option[value=2]', 'Tag 2'
51
- assert_select 'form select option[value=3]', 'Tag 3'
56
+ assert_select 'form select option[value="1"]', 'Tag 1'
57
+ assert_select 'form select option[value="2"]', 'Tag 2'
58
+ assert_select 'form select option[value="3"]', 'Tag 3'
52
59
 
53
60
  value.verify
54
61
  end
@@ -59,9 +66,9 @@ class AssociationTest < ActionView::TestCase
59
66
 
60
67
  with_association_for @user, :tags, preload: false
61
68
  assert_select 'form select.select#user_tag_ids'
62
- assert_select 'form select option[value=1]', 'Tag 1'
63
- assert_select 'form select option[value=2]', 'Tag 2'
64
- assert_select 'form select option[value=3]', 'Tag 3'
69
+ assert_select 'form select option[value="1"]', 'Tag 1'
70
+ assert_select 'form select option[value="2"]', 'Tag 2'
71
+ assert_select 'form select option[value="3"]', 'Tag 3'
65
72
 
66
73
  assert_raises MockExpectationError do
67
74
  value.verify
@@ -74,9 +81,9 @@ class AssociationTest < ActionView::TestCase
74
81
 
75
82
  with_association_for @user, :company
76
83
  assert_select 'form select.select#user_company_id'
77
- assert_select 'form select option[value=1]', 'Company 1'
78
- assert_select 'form select option[value=2]', 'Company 2'
79
- assert_select 'form select option[value=3]', 'Company 3'
84
+ assert_select 'form select option[value="1"]', 'Company 1'
85
+ assert_select 'form select option[value="2"]', 'Company 2'
86
+ assert_select 'form select option[value="3"]', 'Company 3'
80
87
 
81
88
  assert_raises MockExpectationError do
82
89
  value.verify
@@ -87,15 +94,15 @@ class AssociationTest < ActionView::TestCase
87
94
  test 'builder creates a select for belongs_to associations' do
88
95
  with_association_for @user, :company
89
96
  assert_select 'form select.select#user_company_id'
90
- assert_select 'form select option[value=1]', 'Company 1'
91
- assert_select 'form select option[value=2]', 'Company 2'
92
- assert_select 'form select option[value=3]', 'Company 3'
97
+ assert_select 'form select option[value="1"]', 'Company 1'
98
+ assert_select 'form select option[value="2"]', 'Company 2'
99
+ assert_select 'form select option[value="3"]', 'Company 3'
93
100
  end
94
101
 
95
102
  test 'builder creates blank select if collection is nil' do
96
103
  with_association_for @user, :company, collection: nil
97
104
  assert_select 'form select.select#user_company_id'
98
- assert_no_select 'form select option[value=1]', 'Company 1'
105
+ assert_no_select 'form select option[value="1"]', 'Company 1'
99
106
  end
100
107
 
101
108
  test 'builder allows collection radio for belongs_to associations' do
@@ -108,9 +115,26 @@ class AssociationTest < ActionView::TestCase
108
115
  test 'builder allows collection to have a proc as a condition' do
109
116
  with_association_for @user, :extra_special_company
110
117
  assert_select 'form select.select#user_extra_special_company_id'
111
- assert_select 'form select option[value=1]'
112
- assert_no_select 'form select option[value=2]'
113
- assert_no_select 'form select option[value=3]'
118
+ assert_select 'form select option[value="1"]'
119
+ assert_no_select 'form select option[value="2"]'
120
+ assert_no_select 'form select option[value="3"]'
121
+ end
122
+
123
+ test 'builder allows collection to have a scope' do
124
+ with_association_for @user, :special_pictures
125
+ assert_select 'form select.select#user_special_picture_ids'
126
+ assert_select 'form select option[value="3"]', '3'
127
+ assert_no_select 'form select option[value="1"]'
128
+ assert_no_select 'form select option[value="2"]'
129
+ end
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"]'
114
138
  end
115
139
 
116
140
  test 'builder marks the record which already belongs to the user' do
@@ -122,20 +146,20 @@ class AssociationTest < ActionView::TestCase
122
146
  end
123
147
 
124
148
  # ASSOCIATIONS - FINDERS
125
- test 'builder should use reflection conditions to find collection' do
149
+ test 'builder uses reflection conditions to find collection' do
126
150
  with_association_for @user, :special_company
127
151
  assert_select 'form select.select#user_special_company_id'
128
- assert_select 'form select option[value=1]'
129
- assert_no_select 'form select option[value=2]'
130
- assert_no_select 'form select option[value=3]'
152
+ assert_select 'form select option[value="1"]'
153
+ assert_no_select 'form select option[value="2"]'
154
+ assert_no_select 'form select option[value="3"]'
131
155
  end
132
156
 
133
- test 'builder should allow overriding collection to association input' do
157
+ test 'builder allows overriding collection to association input' do
134
158
  with_association_for @user, :company, include_blank: false,
135
159
  collection: [Company.new(999, 'Teste')]
136
160
  assert_select 'form select.select#user_company_id'
137
- assert_no_select 'form select option[value=1]'
138
- assert_select 'form select option[value=999]', 'Teste'
161
+ assert_no_select 'form select option[value="1"]'
162
+ assert_select 'form select option[value="999"]', 'Teste'
139
163
  assert_select 'form select option', count: 1
140
164
  end
141
165
 
@@ -146,26 +170,44 @@ class AssociationTest < ActionView::TestCase
146
170
  end
147
171
  end
148
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
+
182
+ test 'builder does not call order if the given association does not respond to it' do
183
+ with_association_for @user, :pictures
184
+ assert_select 'form select.select#user_picture_ids'
185
+ assert_select 'form select[multiple=multiple]'
186
+ assert_select 'form select option[value="1"]', 'Picture 1'
187
+ assert_select 'form select option[value="2"]', 'Picture 2'
188
+ assert_select 'form select option[value="3"]', 'Picture 3'
189
+ end
190
+
149
191
  test 'builder creates a select with multiple options for collection associations' do
150
192
  with_association_for @user, :tags
151
193
  assert_select 'form select.select#user_tag_ids'
152
194
  assert_select 'form select[multiple=multiple]'
153
- assert_select 'form select option[value=1]', 'Tag 1'
154
- assert_select 'form select option[value=2]', 'Tag 2'
155
- assert_select 'form select option[value=3]', 'Tag 3'
195
+ assert_select 'form select option[value="1"]', 'Tag 1'
196
+ assert_select 'form select option[value="2"]', 'Tag 2'
197
+ assert_select 'form select option[value="3"]', 'Tag 3'
156
198
  end
157
199
 
158
200
  test 'builder allows size to be overwritten for collection associations' do
159
201
  with_association_for @user, :tags, input_html: { size: 10 }
160
- assert_select 'form select[multiple=multiple][size=10]'
202
+ assert_select 'form select[multiple=multiple][size="10"]'
161
203
  end
162
204
 
163
205
  test 'builder marks all selected records which already belongs to user' do
164
206
  @user.tag_ids = [1, 2]
165
207
  with_association_for @user, :tags
166
- assert_select 'form select option[value=1][selected=selected]'
167
- assert_select 'form select option[value=2][selected=selected]'
168
- assert_no_select 'form select option[value=3][selected=selected]'
208
+ assert_select 'form select option[value="1"][selected=selected]'
209
+ assert_select 'form select option[value="2"][selected=selected]'
210
+ assert_no_select 'form select option[value="3"][selected=selected]'
169
211
  end
170
212
 
171
213
  test 'builder allows a collection of check boxes for collection associations' do
@@ -179,9 +221,9 @@ class AssociationTest < ActionView::TestCase
179
221
  test 'builder marks all selected records for collection boxes' do
180
222
  @user.tag_ids = [1, 2]
181
223
  with_association_for @user, :tags, as: :check_boxes
182
- assert_select 'form input[type=checkbox][value=1][checked=checked]'
183
- assert_select 'form input[type=checkbox][value=2][checked=checked]'
184
- assert_no_select 'form input[type=checkbox][value=3][checked=checked]'
224
+ assert_select 'form input[type=checkbox][value="1"][checked=checked]'
225
+ assert_select 'form input[type=checkbox][value="2"][checked=checked]'
226
+ assert_no_select 'form input[type=checkbox][value="3"][checked=checked]'
185
227
  end
186
228
 
187
229
  test 'builder with collection support giving collection and item wrapper tags' do
@@ -192,13 +234,13 @@ class AssociationTest < ActionView::TestCase
192
234
  assert_select 'form ul li', count: 3
193
235
  end
194
236
 
195
- test 'builder with collection support should not change the options hash' do
196
- options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li}
237
+ test 'builder with collection support does not change the options hash' do
238
+ options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li }
197
239
  with_association_for @user, :tags, options
198
240
 
199
241
  assert_select 'form ul', count: 1
200
242
  assert_select 'form ul li', count: 3
201
- 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 },
202
244
  options)
203
245
  end
204
246
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
@@ -8,33 +9,33 @@ class ButtonTest < ActionView::TestCase
8
9
  end
9
10
  end
10
11
 
11
- test 'builder should create buttons' do
12
+ test 'builder creates buttons' do
12
13
  with_button_for :post, :submit
13
- assert_select 'form input.button[type=submit][value=Save Post]'
14
+ assert_select 'form input.button[type=submit][value="Save Post"]'
14
15
  end
15
16
 
16
- test 'builder should create buttons with options' do
17
+ test 'builder creates buttons with options' do
17
18
  with_button_for :post, :submit, class: 'my_button'
18
- assert_select 'form input.button.my_button[type=submit][value=Save Post]'
19
+ assert_select 'form input.button.my_button[type=submit][value="Save Post"]'
19
20
  end
20
21
 
21
- test 'builder should not modify the options hash' do
22
+ test 'builder does not modify the options hash' do
22
23
  options = { class: 'my_button' }
23
24
  with_button_for :post, :submit, options
24
- assert_select 'form input.button.my_button[type=submit][value=Save Post]'
25
+ assert_select 'form input.button.my_button[type=submit][value="Save Post"]'
25
26
  assert_equal({ class: 'my_button' }, options)
26
27
  end
27
28
 
28
- test 'builder should create buttons for records' do
29
+ test 'builder creates buttons for records' do
29
30
  @user.new_record!
30
31
  with_button_for @user, :submit
31
- assert_select 'form input.button[type=submit][value=Create User]'
32
+ assert_select 'form input.button[type=submit][value="Create User"]'
32
33
  end
33
34
 
34
- test "builder should use the default class from the configuration" do
35
+ test "builder uses the default class from the configuration" do
35
36
  swap SimpleForm, button_class: 'btn' do
36
37
  with_button_for :post, :submit
37
- assert_select 'form input.btn[type=submit][value=Save Post]'
38
+ assert_select 'form input.btn[type=submit][value="Save Post"]'
38
39
  end
39
40
  end
40
41
 
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
4
5
  # Tests for f.error_notification
5
6
  class ErrorNotificationTest < ActionView::TestCase
6
- def with_error_notification_for(object, options={}, &block)
7
+ def with_error_notification_for(object, options = {}, &block)
7
8
  with_concat_form_for(object) do |f|
8
9
  f.error_notification(options)
9
10
  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
@@ -14,65 +15,70 @@ class ErrorTest < ActionView::TestCase
14
15
  end
15
16
  end
16
17
 
17
- test 'error should not generate content for attribute without errors' do
18
+ test 'error does not generate content for attribute without errors' do
18
19
  with_error_for @user, :active
19
20
  assert_no_select 'span.error'
20
21
  end
21
22
 
22
- test 'error should not generate messages when object is not present' do
23
+ test 'error does not generate messages when object is not present' do
23
24
  with_error_for :project, :name
24
25
  assert_no_select 'span.error'
25
26
  end
26
27
 
27
- test "error should not generate messages when object doesn't respond to errors method" do
28
+ test "error does not generate messages when object doesn't respond to errors method" do
28
29
  @user.instance_eval { undef errors }
29
30
  with_error_for @user, :name
30
31
  assert_no_select 'span.error'
31
32
  end
32
33
 
33
- test 'error should generate messages for attribute with single error' do
34
+ test 'error generates messages for attribute with single error' do
34
35
  with_error_for @user, :name
35
- assert_select 'span.error', "can't be blank"
36
+ assert_select 'span.error', "cannot be blank"
36
37
  end
37
38
 
38
- test 'error should generate messages for attribute with one error when using first' do
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
+
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
41
47
  assert_select 'span.error', 'is not a number'
42
48
  end
43
49
  end
44
50
 
45
- test 'error should generate messages for attribute with several errors when using to_sentence' do
51
+ test 'error generates messages for attribute with several errors when using to_sentence' do
46
52
  swap SimpleForm, error_method: :to_sentence do
47
53
  with_error_for @user, :age
48
54
  assert_select 'span.error', 'is not a number and must be greater than 18'
49
55
  end
50
56
  end
51
57
 
52
- test 'error should be able to pass html options' do
58
+ test 'error is able to pass html options' do
53
59
  with_error_for @user, :name, id: 'error', class: 'yay'
54
60
  assert_select 'span#error.error.yay'
55
61
  end
56
62
 
57
- test 'error should not modify the options hash' do
63
+ test 'error does not modify the options hash' do
58
64
  options = { id: 'error', class: 'yay' }
59
65
  with_error_for @user, :name, options
60
66
  assert_select 'span#error.error.yay'
61
67
  assert_equal({ id: 'error', class: 'yay' }, options)
62
68
  end
63
69
 
64
- test 'error should find errors on attribute and association' do
70
+ test 'error finds errors on attribute and association' do
65
71
  with_error_for @user, :company_id, as: :select,
66
72
  error_method: :to_sentence, reflection: Association.new(Company, :company, {})
67
73
  assert_select 'span.error', 'must be valid and company must be present'
68
74
  end
69
75
 
70
- test 'error should generate an error tag with a clean HTML' do
76
+ test 'error generates an error tag with a clean HTML' do
71
77
  with_error_for @user, :name
72
78
  assert_no_select 'span.error[error_html]'
73
79
  end
74
80
 
75
- test 'error should generate an error tag with a clean HTML when errors options are present' do
81
+ test 'error generates an error tag with a clean HTML when errors options are present' do
76
82
  with_error_for @user, :name, error_tag: :p, error_prefix: 'Name', error_method: :first
77
83
  assert_no_select 'p.error[error_html]'
78
84
  assert_no_select 'p.error[error_tag]'
@@ -80,47 +86,190 @@ class ErrorTest < ActionView::TestCase
80
86
  assert_no_select 'p.error[error_method]'
81
87
  end
82
88
 
83
- test 'error should escape error prefix text' do
89
+ test 'error escapes error prefix text' do
84
90
  with_error_for @user, :name, error_prefix: '<b>Name</b>'
85
- assert_select 'span.error', "&lt;b&gt;Name&lt;/b&gt; can't be blank"
91
+ assert_no_select 'span.error b'
92
+ end
93
+
94
+ test 'error escapes error text' do
95
+ @user.errors.add(:action, 'must not contain <b>markup</b>')
96
+
97
+ with_error_for @user, :action
98
+
99
+ assert_select 'span.error'
100
+ assert_no_select 'span.error b', 'markup'
86
101
  end
87
102
 
88
- test 'error should generate an error message with raw HTML tags' do
103
+ test 'error generates an error message with raw HTML tags' do
89
104
  with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
90
- assert_select 'span.error', "Name can't be blank"
105
+ assert_select 'span.error', "Name cannot be blank"
91
106
  assert_select 'span.error b', "Name"
92
107
  end
93
108
 
109
+ test 'error adds aria-invalid attribute to inputs' do
110
+ with_form_for @user, :name, error: true
111
+ assert_select "input#user_name[name='user[name]'][aria-invalid='true']"
112
+
113
+ with_form_for @user, :name, as: :text, error: true
114
+ assert_select "textarea#user_name[name='user[name]'][aria-invalid='true']"
115
+
116
+ @user.errors.add(:active, 'must select one')
117
+ with_form_for @user, :active, as: :radio_buttons
118
+ assert_select "input#user_active_true[type=radio][name='user[active]'][aria-invalid='true']"
119
+ assert_select "input#user_active_false[type=radio][name='user[active]'][aria-invalid='true']"
120
+
121
+ with_form_for @user, :active, as: :check_boxes
122
+ assert_select "input#user_active_true[type=checkbox][aria-invalid='true']"
123
+ assert_select "input#user_active_false[type=checkbox][aria-invalid='true']"
124
+
125
+ with_form_for @user, :company_id, as: :select, error: true
126
+ assert_select "select#user_company_id[aria-invalid='true']"
127
+
128
+ @user.errors.add(:password, 'must not be blank')
129
+ with_form_for @user, :password
130
+ assert_select "input#user_password[type=password][aria-invalid='true']"
131
+ end
132
+
94
133
  # FULL ERRORS
95
134
 
96
- test 'full error should generate an full error tag for the attribute' do
135
+ test 'full error generates a full error tag for the attribute' do
97
136
  with_full_error_for @user, :name
98
- assert_select 'span.error', "Super User Name! can't be blank"
137
+ assert_select 'span.error', "Super User Name! cannot be blank"
99
138
  end
100
139
 
101
- test 'full error should generate an full error tag with a clean HTML' do
140
+ test 'full error generates a full error tag with a clean HTML' do
102
141
  with_full_error_for @user, :name
103
142
  assert_no_select 'span.error[error_html]'
104
143
  end
105
144
 
106
- test 'full error should allow passing options to full error tag' do
145
+ test 'full error allows passing options to full error tag' do
107
146
  with_full_error_for @user, :name, id: 'name_error', error_prefix: "Your name"
108
- assert_select 'span.error#name_error', "Your name can't be blank"
147
+ assert_select 'span.error#name_error', "Your name cannot be blank"
109
148
  end
110
149
 
111
- test 'full error should not modify the options hash' do
150
+ test 'full error does not modify the options hash' do
112
151
  options = { id: 'name_error' }
113
152
  with_full_error_for @user, :name, options
114
- assert_select 'span.error#name_error', "Super User Name! can't be blank"
153
+ assert_select 'span.error#name_error', "Super User Name! cannot be blank"
115
154
  assert_equal({ id: 'name_error' }, options)
116
155
  end
117
156
 
157
+ test 'full error escapes error text' do
158
+ @user.errors.add(:action, 'must not contain <b>markup</b>')
159
+
160
+ with_full_error_for @user, :action
161
+
162
+ assert_select 'span.error'
163
+ assert_no_select 'span.error b', 'markup'
164
+ end
165
+
118
166
  # CUSTOM WRAPPERS
119
167
 
120
168
  test 'error with custom wrappers works' do
121
169
  swap_wrapper do
122
170
  with_error_for @user, :name
123
- assert_select 'span.omg_error', "can't be blank"
171
+ assert_select 'span.omg_error', "cannot be blank"
172
+ end
173
+ end
174
+
175
+ # FULL_ERROR_WRAPPER
176
+
177
+ test 'full error finds errors on association' do
178
+ swap_wrapper :default, custom_wrapper_with_full_error do
179
+ with_form_for @user, :company_id, as: :select
180
+ assert_select 'span.error', 'Company must be valid'
181
+ end
182
+ end
183
+
184
+ test 'full error finds errors on association with reflection' do
185
+ swap_wrapper :default, custom_wrapper_with_full_error do
186
+ with_form_for @user, :company_id, as: :select,
187
+ reflection: Association.new(Company, :company, {})
188
+ assert_select 'span.error', 'Company must be valid'
189
+ end
190
+ end
191
+
192
+ test 'full error can be disabled' do
193
+ swap_wrapper :default, custom_wrapper_with_full_error do
194
+ with_form_for @user, :company_id, as: :select, full_error: false
195
+ assert_no_select 'span.error'
196
+ end
197
+ end
198
+
199
+ test 'full error can be disabled setting error to false' do
200
+ swap_wrapper :default, custom_wrapper_with_full_error do
201
+ with_form_for @user, :company_id, as: :select, error: false
202
+ assert_no_select 'span.error'
203
+ end
204
+ end
205
+
206
+ # CUSTOM ERRORS
207
+
208
+ test 'input with custom error works' do
209
+ error_text = "Super User Name! cannot be blank"
210
+ with_form_for @user, :name, error: error_text
211
+
212
+ assert_select 'span.error', error_text
213
+ end
214
+
215
+ test 'input with error option as true does not use custom error' do
216
+ with_form_for @user, :name, error: true
217
+
218
+ assert_select 'span.error', "cannot be blank"
219
+ end
220
+
221
+ test 'input with custom error does not generate the error if there is no error on the attribute' do
222
+ with_form_for @user, :active, error: "Super User Active! cannot be blank"
223
+
224
+ assert_no_select 'span.error'
225
+ end
226
+
227
+ test 'input with custom error works when using full_error component' do
228
+ swap_wrapper :default, custom_wrapper_with_full_error do
229
+ error_text = "Super User Name! cannot be blank"
230
+ with_form_for @user, :name, error: error_text
231
+
232
+ assert_select 'span.error', error_text
233
+ end
234
+ end
235
+
236
+ test 'input with custom error escapes the error text' do
237
+ with_form_for @user, :name, error: 'error must not contain <b>markup</b>'
238
+
239
+ assert_select 'span.error'
240
+ assert_no_select 'span.error b', 'markup'
241
+ end
242
+
243
+ test 'input with custom error does not escape the error text if it is safe' do
244
+ with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe
245
+
246
+ assert_select 'span.error'
247
+ assert_select 'span.error b', 'markup'
248
+ end
249
+
250
+ test 'input with custom error escapes the error text using full_error component' do
251
+ swap_wrapper :default, custom_wrapper_with_full_error do
252
+ with_form_for @user, :name, error: 'error must not contain <b>markup</b>'
253
+
254
+ assert_select 'span.error'
255
+ assert_no_select 'span.error b', 'markup'
256
+ end
257
+ end
258
+
259
+ test 'input with custom error does not escape the error text if it is safe using full_error component' do
260
+ swap_wrapper :default, custom_wrapper_with_full_error do
261
+ with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe
262
+
263
+ assert_select 'span.error'
264
+ assert_select 'span.error b', 'markup'
265
+ end
266
+ end
267
+
268
+ test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do
269
+ swap_wrapper :default, custom_wrapper_with_full_error do
270
+ with_form_for @user, :active, error: "Super User Active! can't be blank"
271
+
272
+ assert_no_select 'span.error'
124
273
  end
125
274
  end
126
275
  end