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.

Files changed (103) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +97 -198
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +572 -296
  5. data/lib/generators/simple_form/install_generator.rb +17 -7
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/_form.html.erb +1 -0
  8. data/lib/generators/simple_form/templates/_form.html.haml +1 -0
  9. data/lib/generators/simple_form/templates/config/initializers/{simple_form.rb.tt → simple_form.rb} +57 -63
  10. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +155 -0
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +111 -0
  12. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +14 -7
  13. data/lib/simple_form/action_view_extensions/builder.rb +5 -305
  14. data/lib/simple_form/action_view_extensions/form_helper.rb +18 -20
  15. data/lib/simple_form/components/errors.rb +30 -3
  16. data/lib/simple_form/components/hints.rb +10 -3
  17. data/lib/simple_form/components/html5.rb +17 -3
  18. data/lib/simple_form/components/label_input.rb +21 -2
  19. data/lib/simple_form/components/labels.rb +16 -11
  20. data/lib/simple_form/components/maxlength.rb +19 -12
  21. data/lib/simple_form/components/min_max.rb +4 -2
  22. data/lib/simple_form/components/minlength.rb +48 -0
  23. data/lib/simple_form/components/pattern.rb +5 -4
  24. data/lib/simple_form/components/placeholders.rb +3 -2
  25. data/lib/simple_form/components/readonly.rb +3 -2
  26. data/lib/simple_form/components.rb +15 -11
  27. data/lib/simple_form/error_notification.rb +4 -3
  28. data/lib/simple_form/form_builder.rb +283 -105
  29. data/lib/simple_form/helpers/autofocus.rb +1 -0
  30. data/lib/simple_form/helpers/disabled.rb +1 -0
  31. data/lib/simple_form/helpers/readonly.rb +1 -0
  32. data/lib/simple_form/helpers/required.rb +1 -0
  33. data/lib/simple_form/helpers/validators.rb +4 -3
  34. data/lib/simple_form/helpers.rb +7 -6
  35. data/lib/simple_form/i18n_cache.rb +1 -0
  36. data/lib/simple_form/inputs/base.rb +76 -23
  37. data/lib/simple_form/inputs/block_input.rb +3 -2
  38. data/lib/simple_form/inputs/boolean_input.rb +55 -16
  39. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -1
  40. data/lib/simple_form/inputs/collection_input.rb +41 -18
  41. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +11 -19
  42. data/lib/simple_form/inputs/collection_select_input.rb +5 -2
  43. data/lib/simple_form/inputs/date_time_input.rb +23 -12
  44. data/lib/simple_form/inputs/file_input.rb +5 -2
  45. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  46. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  47. data/lib/simple_form/inputs/numeric_input.rb +4 -8
  48. data/lib/simple_form/inputs/password_input.rb +6 -4
  49. data/lib/simple_form/inputs/priority_input.rb +5 -2
  50. data/lib/simple_form/inputs/range_input.rb +2 -1
  51. data/lib/simple_form/inputs/string_input.rb +6 -4
  52. data/lib/simple_form/inputs/text_input.rb +6 -3
  53. data/lib/simple_form/inputs.rb +20 -17
  54. data/lib/simple_form/map_type.rb +1 -0
  55. data/lib/simple_form/railtie.rb +15 -0
  56. data/lib/simple_form/tags.rb +69 -0
  57. data/lib/simple_form/version.rb +2 -1
  58. data/lib/simple_form/wrappers/builder.rb +12 -35
  59. data/lib/simple_form/wrappers/leaf.rb +29 -0
  60. data/lib/simple_form/wrappers/many.rb +12 -7
  61. data/lib/simple_form/wrappers/root.rb +7 -4
  62. data/lib/simple_form/wrappers/single.rb +12 -3
  63. data/lib/simple_form/wrappers.rb +3 -1
  64. data/lib/simple_form.rb +118 -63
  65. data/test/action_view_extensions/builder_test.rb +230 -164
  66. data/test/action_view_extensions/form_helper_test.rb +107 -39
  67. data/test/components/label_test.rb +105 -87
  68. data/test/form_builder/association_test.rb +131 -62
  69. data/test/form_builder/button_test.rb +15 -14
  70. data/test/form_builder/error_notification_test.rb +11 -10
  71. data/test/form_builder/error_test.rb +188 -34
  72. data/test/form_builder/general_test.rb +247 -102
  73. data/test/form_builder/hint_test.rb +59 -32
  74. data/test/form_builder/input_field_test.rb +138 -25
  75. data/test/form_builder/label_test.rb +84 -13
  76. data/test/form_builder/wrapper_test.rb +236 -33
  77. data/test/generators/simple_form_generator_test.rb +15 -4
  78. data/test/inputs/boolean_input_test.rb +147 -13
  79. data/test/inputs/collection_check_boxes_input_test.rb +166 -71
  80. data/test/inputs/collection_radio_buttons_input_test.rb +229 -113
  81. data/test/inputs/collection_select_input_test.rb +222 -85
  82. data/test/inputs/datetime_input_test.rb +134 -47
  83. data/test/inputs/disabled_test.rb +62 -21
  84. data/test/inputs/discovery_test.rb +70 -10
  85. data/test/inputs/file_input_test.rb +4 -3
  86. data/test/inputs/general_test.rb +90 -26
  87. data/test/inputs/grouped_collection_select_input_test.rb +88 -23
  88. data/test/inputs/hidden_input_test.rb +7 -5
  89. data/test/inputs/numeric_input_test.rb +56 -46
  90. data/test/inputs/priority_input_test.rb +31 -16
  91. data/test/inputs/readonly_test.rb +68 -27
  92. data/test/inputs/required_test.rb +63 -18
  93. data/test/inputs/string_input_test.rb +76 -51
  94. data/test/inputs/text_input_test.rb +21 -8
  95. data/test/simple_form_test.rb +9 -0
  96. data/test/support/discovery_inputs.rb +39 -2
  97. data/test/support/misc_helpers.rb +176 -20
  98. data/test/support/mock_controller.rb +13 -7
  99. data/test/support/models.rb +187 -71
  100. data/test/test_helper.rb +38 -39
  101. metadata +53 -39
  102. data/lib/simple_form/core_ext/hash.rb +0 -16
  103. 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.error and f.full_error
@@ -14,100 +15,152 @@ 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
- swap SimpleForm, :error_method => :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
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
46
- swap SimpleForm, :error_method => :to_sentence do
51
+ test 'error generates messages for attribute with several errors when using to_sentence' do
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
53
- with_error_for @user, :name, :id => 'error', :class => 'yay'
58
+ test 'error is able to pass html options' do
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
58
- options = { :id => 'error', :class => 'yay' }
63
+ test 'error does not modify the options hash' do
64
+ options = { id: 'error', class: 'yay' }
59
65
  with_error_for @user, :name, options
60
66
  assert_select 'span#error.error.yay'
61
- assert_equal({ :id => 'error', :class => 'yay' }, options)
67
+ assert_equal({ id: 'error', class: 'yay' }, options)
62
68
  end
63
69
 
64
- test 'error should find errors on attribute and association' do
65
- with_error_for @user, :company_id, :as => :select,
66
- :error_method => :to_sentence, :reflection => Association.new(Company, :company, {})
70
+ test 'error finds errors on attribute and association' do
71
+ with_error_for @user, :company_id, as: :select,
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
76
- with_error_for @user, :name, :error_tag => :p, :error_prefix => 'Name', :error_method => :first
81
+ test 'error generates an error tag with a clean HTML when errors options are present' do
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]'
79
85
  assert_no_select 'p.error[error_prefix]'
80
86
  assert_no_select 'p.error[error_method]'
81
87
  end
82
88
 
83
- test 'error should generate an error message with raw HTML tags' do
84
- with_error_for @user, :name, :error_prefix => '<b>Name</b>'
85
- assert_select 'span.error', "Name can't be blank"
89
+ test 'error escapes error prefix text' do
90
+ with_error_for @user, :name, error_prefix: '<b>Name</b>'
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'
101
+ end
102
+
103
+ test 'error generates an error message with raw HTML tags' do
104
+ with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
105
+ assert_select 'span.error', "Name cannot be blank"
86
106
  assert_select 'span.error b', "Name"
87
107
  end
88
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
+
89
133
  # FULL ERRORS
90
134
 
91
- 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
92
136
  with_full_error_for @user, :name
93
- assert_select 'span.error', "Super User Name! can't be blank"
137
+ assert_select 'span.error', "Super User Name! cannot be blank"
94
138
  end
95
139
 
96
- 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
97
141
  with_full_error_for @user, :name
98
142
  assert_no_select 'span.error[error_html]'
99
143
  end
100
144
 
101
- test 'full error should allow passing options to full error tag' do
102
- with_full_error_for @user, :name, :id => 'name_error', :error_prefix => "Your name"
103
- assert_select 'span.error#name_error', "Your name can't be blank"
145
+ test 'full error allows passing options to full error tag' do
146
+ with_full_error_for @user, :name, id: 'name_error', error_prefix: "Your name"
147
+ assert_select 'span.error#name_error', "Your name cannot be blank"
104
148
  end
105
149
 
106
- test 'full error should not modify the options hash' do
107
- options = { :id => 'name_error' }
150
+ test 'full error does not modify the options hash' do
151
+ options = { id: 'name_error' }
108
152
  with_full_error_for @user, :name, options
109
- assert_select 'span.error#name_error', "Super User Name! can't be blank"
110
- assert_equal({ :id => 'name_error' }, options)
153
+ assert_select 'span.error#name_error', "Super User Name! cannot be blank"
154
+ assert_equal({ id: 'name_error' }, options)
155
+ end
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'
111
164
  end
112
165
 
113
166
  # CUSTOM WRAPPERS
@@ -115,7 +168,108 @@ class ErrorTest < ActionView::TestCase
115
168
  test 'error with custom wrappers works' do
116
169
  swap_wrapper do
117
170
  with_error_for @user, :name
118
- 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'
119
273
  end
120
274
  end
121
275
  end