simple_form 3.0.4 → 5.0.3

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 (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +199 -33
  3. data/MIT-LICENSE +2 -1
  4. data/README.md +453 -128
  5. data/lib/generators/simple_form/install_generator.rb +4 -3
  6. data/lib/generators/simple_form/templates/README +3 -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 +47 -16
  11. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +418 -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 +39 -6
  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 +220 -89
  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 +62 -16
  38. data/lib/simple_form/inputs/block_input.rb +2 -1
  39. data/lib/simple_form/inputs/boolean_input.rb +40 -16
  40. data/lib/simple_form/inputs/collection_check_boxes_input.rb +3 -2
  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/color_input.rb +14 -0
  45. data/lib/simple_form/inputs/date_time_input.rb +24 -9
  46. data/lib/simple_form/inputs/file_input.rb +5 -2
  47. data/lib/simple_form/inputs/grouped_collection_select_input.rb +16 -3
  48. data/lib/simple_form/inputs/hidden_input.rb +5 -2
  49. data/lib/simple_form/inputs/numeric_input.rb +6 -4
  50. data/lib/simple_form/inputs/password_input.rb +6 -3
  51. data/lib/simple_form/inputs/priority_input.rb +5 -6
  52. data/lib/simple_form/inputs/range_input.rb +2 -1
  53. data/lib/simple_form/inputs/rich_text_area_input.rb +12 -0
  54. data/lib/simple_form/inputs/string_input.rb +7 -4
  55. data/lib/simple_form/inputs/text_input.rb +6 -3
  56. data/lib/simple_form/inputs.rb +3 -0
  57. data/lib/simple_form/map_type.rb +1 -0
  58. data/lib/simple_form/railtie.rb +8 -0
  59. data/lib/simple_form/tags.rb +13 -2
  60. data/lib/simple_form/version.rb +2 -1
  61. data/lib/simple_form/wrappers/builder.rb +7 -6
  62. data/lib/simple_form/wrappers/leaf.rb +29 -0
  63. data/lib/simple_form/wrappers/many.rb +7 -6
  64. data/lib/simple_form/wrappers/root.rb +10 -3
  65. data/lib/simple_form/wrappers/single.rb +7 -4
  66. data/lib/simple_form/wrappers.rb +2 -0
  67. data/lib/simple_form.rb +137 -21
  68. data/test/action_view_extensions/builder_test.rb +64 -45
  69. data/test/action_view_extensions/form_helper_test.rb +36 -16
  70. data/test/components/custom_components_test.rb +62 -0
  71. data/test/components/label_test.rb +70 -41
  72. data/test/form_builder/association_test.rb +85 -37
  73. data/test/form_builder/button_test.rb +11 -10
  74. data/test/form_builder/error_notification_test.rb +2 -1
  75. data/test/form_builder/error_test.rb +146 -33
  76. data/test/form_builder/general_test.rb +183 -81
  77. data/test/form_builder/hint_test.rb +24 -18
  78. data/test/form_builder/input_field_test.rb +105 -75
  79. data/test/form_builder/label_test.rb +68 -13
  80. data/test/form_builder/wrapper_test.rb +197 -22
  81. data/test/generators/simple_form_generator_test.rb +8 -7
  82. data/test/inputs/boolean_input_test.rb +97 -6
  83. data/test/inputs/collection_check_boxes_input_test.rb +117 -25
  84. data/test/inputs/collection_radio_buttons_input_test.rb +176 -54
  85. data/test/inputs/collection_select_input_test.rb +189 -77
  86. data/test/inputs/color_input_test.rb +10 -0
  87. data/test/inputs/datetime_input_test.rb +121 -50
  88. data/test/inputs/disabled_test.rb +29 -15
  89. data/test/inputs/discovery_test.rb +79 -6
  90. data/test/inputs/file_input_test.rb +3 -2
  91. data/test/inputs/general_test.rb +23 -22
  92. data/test/inputs/grouped_collection_select_input_test.rb +54 -17
  93. data/test/inputs/hidden_input_test.rb +5 -4
  94. data/test/inputs/numeric_input_test.rb +48 -44
  95. data/test/inputs/priority_input_test.rb +17 -16
  96. data/test/inputs/readonly_test.rb +20 -19
  97. data/test/inputs/required_test.rb +58 -13
  98. data/test/inputs/rich_text_area_input_test.rb +15 -0
  99. data/test/inputs/string_input_test.rb +58 -36
  100. data/test/inputs/text_input_test.rb +20 -7
  101. data/test/simple_form_test.rb +9 -0
  102. data/test/support/discovery_inputs.rb +40 -2
  103. data/test/support/misc_helpers.rb +113 -5
  104. data/test/support/mock_controller.rb +7 -1
  105. data/test/support/models.rb +162 -39
  106. data/test/test_helper.rb +19 -4
  107. metadata +51 -43
@@ -1,27 +1,28 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class RequiredTest < ActionView::TestCase
4
5
  # REQUIRED AND PRESENCE VALIDATION
5
- test 'builder input should obtain required from ActiveModel::Validations when it is included' do
6
+ test 'builder input obtains required from ActiveModel::Validations when it is included' do
6
7
  with_form_for @validating_user, :name
7
8
  assert_select 'input.required[required]#validating_user_name'
8
9
  with_form_for @validating_user, :status
9
10
  assert_select 'input.optional#validating_user_status'
10
11
  end
11
12
 
12
- test 'builder input should allow overriding required when ActiveModel::Validations is included' do
13
+ test 'builder input allows overriding required when ActiveModel::Validations is included' do
13
14
  with_form_for @validating_user, :name, required: false
14
15
  assert_select 'input.optional#validating_user_name'
15
16
  with_form_for @validating_user, :status, required: true
16
17
  assert_select 'input.required[required]#validating_user_status'
17
18
  end
18
19
 
19
- test 'builder input should be required by default when ActiveModel::Validations is not included' do
20
+ test 'builder input is required by default when ActiveModel::Validations is not included' do
20
21
  with_form_for @user, :name
21
22
  assert_select 'input.required[required]#user_name'
22
23
  end
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
+ test 'builder input does not be required by default when ActiveModel::Validations is not included if option is set to false' do
25
26
  swap SimpleForm, required_by_default: false do
26
27
  with_form_for @user, :name
27
28
  assert_select 'input.optional#user_name'
@@ -29,15 +30,47 @@ class RequiredTest < ActionView::TestCase
29
30
  end
30
31
  end
31
32
 
32
- test 'when not using browser validations, input should not generate required html attribute' do
33
+ test 'when not using browser validations, input does not generate required html attribute' do
33
34
  swap SimpleForm, browser_validations: false do
34
35
  with_input_for @user, :name, :string
35
36
  assert_select 'input[type=text].required'
36
37
  assert_no_select 'input[type=text][required]'
38
+ assert_no_select 'input[type=text][aria-required]'
37
39
  end
38
40
  end
39
41
 
40
- test 'builder input should allow disabling required when ActiveModel::Validations is not included' do
42
+ test 'when not using browser validations, when required option is set to false, input does not generate required html attribute' do
43
+ swap SimpleForm, browser_validations: false do
44
+ with_input_for @user, :name, :string, required: false
45
+ assert_no_select 'input[type=text].required'
46
+ assert_no_select 'input[type=text][required]'
47
+ assert_no_select 'input[type=text][aria-required]'
48
+ end
49
+ end
50
+
51
+ test 'when not using browser validations, when required option is set to true, input generates required html attribute' do
52
+ swap SimpleForm, browser_validations: false do
53
+ with_input_for @user, :name, :string, required: true
54
+ assert_select 'input[type=text].required'
55
+ assert_select 'input[type=text][required]'
56
+ assert_select 'input[type=text][aria-required]'
57
+ end
58
+ end
59
+
60
+ test 'when not using browser validations, when required option is true in the wrapper, input does not generate required html attribute' do
61
+ swap SimpleForm, browser_validations: false do
62
+ swap_wrapper :default, self.custom_wrapper_with_required_input do
63
+ with_concat_form_for(@user) do |f|
64
+ concat f.input :name
65
+ end
66
+ assert_select 'input[type=text].required'
67
+ assert_no_select 'input[type=text][required]'
68
+ assert_no_select 'input[type=text][aria-required]'
69
+ end
70
+ end
71
+ end
72
+
73
+ test 'builder input allows disabling required when ActiveModel::Validations is not included' do
41
74
  with_form_for @user, :name, required: false
42
75
  assert_no_select 'input.required'
43
76
  assert_no_select 'input[required]'
@@ -53,14 +86,14 @@ class RequiredTest < ActionView::TestCase
53
86
  end
54
87
 
55
88
  # VALIDATORS :if :unless
56
- test 'builder input should not be required when ActiveModel::Validations is included and if option is present' do
89
+ test 'builder input does not be required when ActiveModel::Validations is included and if option is present' do
57
90
  with_form_for @validating_user, :age
58
91
  assert_no_select 'input.required'
59
92
  assert_no_select 'input[required]'
60
93
  assert_select 'input.optional#validating_user_age'
61
94
  end
62
95
 
63
- test 'builder input should not be required when ActiveModel::Validations is included and unless option is present' do
96
+ test 'builder input does not be required when ActiveModel::Validations is included and unless option is present' do
64
97
  with_form_for @validating_user, :amount
65
98
  assert_no_select 'input.required'
66
99
  assert_no_select 'input[required]'
@@ -68,7 +101,7 @@ class RequiredTest < ActionView::TestCase
68
101
  end
69
102
 
70
103
  # VALIDATORS :on
71
- test 'builder input should be required when validation is on create and is not persisted' do
104
+ test 'builder input is required when validation is on create and is not persisted' do
72
105
  @validating_user.new_record!
73
106
  with_form_for @validating_user, :action
74
107
  assert_select 'input.required'
@@ -76,14 +109,14 @@ class RequiredTest < ActionView::TestCase
76
109
  assert_select 'input.required[required]#validating_user_action'
77
110
  end
78
111
 
79
- test 'builder input should not be required when validation is on create and is persisted' do
112
+ test 'builder input does not be required when validation is on create and is persisted' do
80
113
  with_form_for @validating_user, :action
81
114
  assert_no_select 'input.required'
82
115
  assert_no_select 'input[required]'
83
116
  assert_select 'input.optional#validating_user_action'
84
117
  end
85
118
 
86
- test 'builder input should be required when validation is on save' do
119
+ test 'builder input is required when validation is on save' do
87
120
  with_form_for @validating_user, :credit_limit
88
121
  assert_select 'input.required'
89
122
  assert_select 'input[required]'
@@ -96,18 +129,30 @@ class RequiredTest < ActionView::TestCase
96
129
  assert_select 'input.required[required]#validating_user_credit_limit'
97
130
  end
98
131
 
99
- test 'builder input should be required when validation is on update and is persisted' do
132
+ test 'builder input is required when validation is on update and is persisted' do
100
133
  with_form_for @validating_user, :phone_number
101
134
  assert_select 'input.required'
102
135
  assert_select 'input[required]'
103
136
  assert_select 'input.required[required]#validating_user_phone_number'
104
137
  end
105
138
 
106
- test 'builder input should not be required when validation is on update and is not persisted' do
139
+ test 'builder input does not be required when validation is on update and is not persisted' do
107
140
  @validating_user.new_record!
108
141
  with_form_for @validating_user, :phone_number
109
142
  assert_no_select 'input.required'
110
143
  assert_no_select 'input[required]'
111
144
  assert_select 'input.optional#validating_user_phone_number'
112
145
  end
146
+
147
+ test 'builder input does not generate required html attribute when option is set to false when it is set to true in wrapper' do
148
+ swap SimpleForm, browser_validations: true do
149
+ swap_wrapper :default, self.custom_wrapper_with_required_input do
150
+ with_concat_form_for(@user) do |f|
151
+ concat f.input :name, required: false
152
+ end
153
+ assert_no_select 'input[type=text][required]'
154
+ assert_no_select 'input[type=text][aria-required]'
155
+ end
156
+ end
157
+ end
113
158
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+ # encoding: UTF-8
3
+ require 'test_helper'
4
+
5
+ class RichTextAreaInputTest < ActionView::TestCase
6
+ test 'input generates a text area for text attributes' do
7
+ with_input_for @user, :description, :text
8
+ assert_select 'textarea.text#user_description'
9
+ end
10
+
11
+ test 'input generates a text area for text attributes that accept placeholder' do
12
+ with_input_for @user, :description, :text, placeholder: 'Put in some text'
13
+ assert_select 'textarea.text[placeholder="Put in some text"]'
14
+ end
15
+ end
@@ -1,117 +1,139 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
4
5
  class StringInputTest < ActionView::TestCase
5
- test 'input should map text field to string attribute' do
6
+ test 'input maps text field to string attribute' do
6
7
  with_input_for @user, :name, :string
7
- assert_select "input#user_name[type=text][name='user[name]'][value=New in SimpleForm!]"
8
+ assert_select "input#user_name[type=text][name='user[name]'][value='New in SimpleForm!']"
8
9
  end
9
10
 
10
- test 'input should generate a password field for password attributes' do
11
+ test 'input maps text field to citext attribute' do
12
+ with_input_for @user, :name, :citext
13
+ assert_select "input#user_name[type=text][name='user[name]'][value='New in SimpleForm!']"
14
+ end
15
+
16
+ test 'input generates a password field for password attributes' do
11
17
  with_input_for @user, :password, :password
12
18
  assert_select "input#user_password.password[type=password][name='user[password]']"
13
19
  end
14
20
 
15
- test 'input should get maxlength from column definition for string attributes' do
21
+ test 'input gets maxlength from column definition for string attributes' do
16
22
  with_input_for @user, :name, :string
17
- assert_select 'input.string[maxlength=100]'
23
+ assert_select 'input.string[maxlength="100"]'
18
24
  end
19
25
 
20
- test 'input should not get maxlength from column without size definition for string attributes' do
26
+ test 'input does not get maxlength from column without size definition for string attributes' do
21
27
  with_input_for @user, :action, :string
22
28
  assert_no_select 'input.string[maxlength]'
23
29
  end
24
30
 
25
- test 'input should get maxlength from column definition for password attributes' do
31
+ test 'input gets maxlength from column definition for password attributes' do
26
32
  with_input_for @user, :password, :password
27
- assert_select 'input.password[type=password][maxlength=100]'
33
+ assert_select 'input.password[type=password][maxlength="100"]'
28
34
  end
29
35
 
30
- test 'input should infer maxlength column definition from validation when present' do
36
+ test 'input infers maxlength column definition from validation when present' do
31
37
  with_input_for @validating_user, :name, :string
32
- assert_select 'input.string[maxlength=25]'
38
+ assert_select 'input.string[maxlength="25"]'
33
39
  end
34
40
 
35
- test 'input should not get maxlength from validation when tokenizer present' do
36
- with_input_for @validating_user, :action, :string
37
- assert_no_select 'input.string[maxlength]'
41
+ test 'input infers minlength column definition from validation when present' do
42
+ with_input_for @validating_user, :name, :string
43
+ assert_select 'input.string[minlength="5"]'
44
+ end
45
+
46
+ test 'input gets maxlength from validation when :is option present' do
47
+ with_input_for @validating_user, :home_picture, :string
48
+ assert_select 'input.string[maxlength="12"]'
38
49
  end
39
50
 
40
- test 'input should get maxlength from validation when :is option present' do
51
+ test 'input gets minlength from validation when :is option present' do
41
52
  with_input_for @validating_user, :home_picture, :string
42
- assert_select 'input.string[maxlength=12]'
53
+ assert_select 'input.string[minlength="12"]'
43
54
  end
44
55
 
45
- test 'input maxlength should be the column limit plus one to make room for decimal point' do
56
+ test 'input maxlength is the column limit plus one to make room for decimal point' do
46
57
  with_input_for @user, :credit_limit, :string
47
58
 
48
- assert_select "input.string[maxlength=16]"
59
+ assert_select 'input.string[maxlength="16"]'
49
60
  end
50
61
 
51
- test 'input should not generate placeholder by default' do
62
+ test 'input does not generate placeholder by default' do
52
63
  with_input_for @user, :name, :string
53
64
  assert_no_select 'input[placeholder]'
54
65
  end
55
66
 
56
- test 'input should accept the placeholder option' do
67
+ test 'input accepts the placeholder option' do
57
68
  with_input_for @user, :name, :string, placeholder: 'Put in some text'
58
- assert_select 'input.string[placeholder=Put in some text]'
69
+ assert_select 'input.string[placeholder="Put in some text"]'
59
70
  end
60
71
 
61
- test 'input should generate a password field for password attributes that accept placeholder' do
72
+ test 'input generates a password field for password attributes that accept placeholder' do
62
73
  with_input_for @user, :password, :password, placeholder: 'Password Confirmation'
63
- assert_select 'input[type=password].password[placeholder=Password Confirmation]#user_password'
74
+ assert_select 'input[type=password].password[placeholder="Password Confirmation"]#user_password'
64
75
  end
65
76
 
66
- test 'input should not infer pattern from attributes by default' do
77
+ test 'input does not infer pattern from attributes by default' do
67
78
  with_input_for @other_validating_user, :country, :string
68
79
  assert_no_select 'input[pattern="\w+"]'
69
80
  end
70
81
 
71
- test 'input should infer pattern from attributes' do
82
+ test 'input infers pattern from attributes' do
72
83
  with_input_for @other_validating_user, :country, :string, pattern: true
73
- assert_select 'input[pattern="\w+"]'
84
+ assert_select "input:match('pattern', ?)", /\w+/
74
85
  end
75
86
 
76
- test 'input should infer pattern from attributes using proc' do
87
+ test 'input infers pattern from attributes using proc' do
77
88
  with_input_for @other_validating_user, :name, :string, pattern: true
78
- assert_select 'input[pattern="\w+"]'
89
+ assert_select "input:match('pattern', ?)", /\w+/
79
90
  end
80
91
 
81
- test 'input should not infer pattern from attributes if root default is false' do
92
+ test 'input does not infer pattern from attributes if root default is false' do
82
93
  swap_wrapper do
83
94
  with_input_for @other_validating_user, :country, :string
84
95
  assert_no_select 'input[pattern="\w+"]'
85
96
  end
86
97
  end
87
98
 
88
- test 'input should use given pattern from attributes' do
99
+ test 'input uses given pattern from attributes' do
89
100
  with_input_for @other_validating_user, :country, :string, input_html: { pattern: "\\d+" }
90
- assert_select 'input[pattern="\d+"]'
101
+ assert_select "input:match('pattern', ?)", /\\d+/
91
102
  end
92
103
 
93
- test 'input should not use pattern if model has :without validation option' do
104
+ test 'input does not use pattern if model has :without validation option' do
94
105
  with_input_for @other_validating_user, :description, :string, pattern: true
95
106
  assert_no_select 'input[pattern="\d+"]'
96
107
  end
97
108
 
98
- test 'input should use i18n to translate placeholder text' do
109
+ test 'input uses i18n to translate placeholder text' do
99
110
  store_translations(:en, simple_form: { placeholders: { user: {
100
111
  name: 'Name goes here'
101
112
  } } }) do
102
113
  with_input_for @user, :name, :string
103
- assert_select 'input.string[placeholder=Name goes here]'
114
+ assert_select 'input.string[placeholder="Name goes here"]'
115
+ end
116
+ end
117
+
118
+ test 'input uses custom i18n scope to translate placeholder text' do
119
+ store_translations(:en, my_scope: { placeholders: { user: {
120
+ name: 'Name goes here'
121
+ } } }) do
122
+ swap SimpleForm, i18n_scope: :my_scope do
123
+ with_input_for @user, :name, :string
124
+ assert_select 'input.string[placeholder="Name goes here"]'
125
+ end
104
126
  end
105
127
  end
106
128
 
107
- [:email, :url, :search, :tel].each do |type|
108
- test "input should allow type #{type}" do
129
+ %i[email url search tel].each do |type|
130
+ test "input allows type #{type}" do
109
131
  with_input_for @user, :name, type
110
132
  assert_select "input.string.#{type}"
111
133
  assert_select "input[type=#{type}]"
112
134
  end
113
135
 
114
- test "input should not allow type #{type} if HTML5 compatibility is disabled" do
136
+ test "input does not allow type #{type} if HTML5 compatibility is disabled" do
115
137
  swap_wrapper do
116
138
  with_input_for @user, :name, type
117
139
  assert_select "input[type=text]"
@@ -1,24 +1,37 @@
1
+ # frozen_string_literal: true
1
2
  # encoding: UTF-8
2
3
  require 'test_helper'
3
4
 
4
5
  class TextInputTest < ActionView::TestCase
5
- test 'input should generate a text area for text attributes' do
6
+ test 'input generates a text area for text attributes' do
6
7
  with_input_for @user, :description, :text
7
8
  assert_select 'textarea.text#user_description'
8
9
  end
9
10
 
10
- test 'input should generate a text area for text attributes that accept placeholder' do
11
+ test 'input generates a text area for text attributes that accept placeholder' do
11
12
  with_input_for @user, :description, :text, placeholder: 'Put in some text'
12
- assert_select 'textarea.text[placeholder=Put in some text]'
13
+ assert_select 'textarea.text[placeholder="Put in some text"]'
13
14
  end
14
15
 
15
- test 'input should get maxlength from column definition for text attributes' do
16
+ test 'input generates a placeholder from the translations' do
17
+ store_translations(:en, simple_form: { placeholders: { user: { name: "placeholder from i18n en.simple_form.placeholders.user.name" } } }) do
18
+ with_input_for @user, :name, :text
19
+ assert_select 'textarea.text[placeholder="placeholder from i18n en.simple_form.placeholders.user.name"]'
20
+ end
21
+ end
22
+
23
+ test 'input gets maxlength from column definition for text attributes' do
16
24
  with_input_for @user, :description, :text
17
- assert_select 'textarea.text[maxlength=200]'
25
+ assert_select 'textarea.text[maxlength="200"]'
26
+ end
27
+
28
+ test 'input infers maxlength column definition from validation when present for text attributes' do
29
+ with_input_for @validating_user, :description, :text
30
+ assert_select 'textarea.text[maxlength="50"]'
18
31
  end
19
32
 
20
- test 'input should infer maxlength column definition from validation when present for text attributes' do
33
+ test 'input infers minlength column definition from validation when present for text attributes' do
21
34
  with_input_for @validating_user, :description, :text
22
- assert_select 'textarea.text[maxlength=50]'
35
+ assert_select 'textarea.text[minlength="15"]'
23
36
  end
24
37
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'test_helper'
2
3
 
3
4
  class SimpleFormTest < ActiveSupport::TestCase
@@ -6,4 +7,12 @@ class SimpleFormTest < ActiveSupport::TestCase
6
7
  assert_equal SimpleForm, config
7
8
  end
8
9
  end
10
+
11
+ test 'setup block configure Simple Form' do
12
+ SimpleForm.setup do |config|
13
+ assert_equal SimpleForm, config
14
+ end
15
+
16
+ assert_equal true, SimpleForm.configured?
17
+ end
9
18
  end
@@ -1,16 +1,27 @@
1
+ # frozen_string_literal: true
1
2
  class StringInput < SimpleForm::Inputs::StringInput
2
- def input
3
+ def input(wrapper_options = nil)
3
4
  "<section>#{super}</section>".html_safe
4
5
  end
5
6
  end
6
7
 
7
8
  class NumericInput < SimpleForm::Inputs::NumericInput
8
- def input
9
+ def input(wrapper_options = nil)
9
10
  "<section>#{super}</section>".html_safe
10
11
  end
11
12
  end
12
13
 
13
14
  class CustomizedInput < SimpleForm::Inputs::StringInput
15
+ def input(wrapper_options = nil)
16
+ "<section>#{super}</section>".html_safe
17
+ end
18
+
19
+ def input_method
20
+ :text_field
21
+ end
22
+ end
23
+
24
+ class DeprecatedInput < SimpleForm::Inputs::StringInput
14
25
  def input
15
26
  "<section>#{super}</section>".html_safe
16
27
  end
@@ -25,3 +36,30 @@ class CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
25
36
  super.push('chosen')
26
37
  end
27
38
  end
39
+
40
+ class FileInput < SimpleForm::Inputs::FileInput
41
+ def input_html_classes
42
+ super.delete_if { |html_class| html_class == :file }
43
+ super.push('file-upload')
44
+ end
45
+ end
46
+
47
+ module CustomInputs
48
+ class CustomizedInput < SimpleForm::Inputs::StringInput
49
+ def input_html_classes
50
+ super.push('customized-namespace-custom-input')
51
+ end
52
+ end
53
+
54
+ class PasswordInput < SimpleForm::Inputs::PasswordInput
55
+ def input_html_classes
56
+ super.push('password-custom-input')
57
+ end
58
+ end
59
+
60
+ class NumericInput < SimpleForm::Inputs::PasswordInput
61
+ def input_html_classes
62
+ super.push('numeric-custom-input')
63
+ end
64
+ end
65
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module MiscHelpers
2
3
  def store_translations(locale, translations, &block)
3
4
  I18n.backend.store_translations locale, translations
@@ -46,12 +47,12 @@ module MiscHelpers
46
47
  end
47
48
  end
48
49
 
49
- def swap_wrapper(name=:default, wrapper=self.custom_wrapper)
50
- old = SimpleForm.wrappers[name]
51
- SimpleForm.wrappers[name] = wrapper
50
+ def swap_wrapper(name = :default, wrapper = custom_wrapper)
51
+ old = SimpleForm.wrappers[name.to_s]
52
+ SimpleForm.wrappers[name.to_s] = wrapper
52
53
  yield
53
54
  ensure
54
- SimpleForm.wrappers[name] = old
55
+ SimpleForm.wrappers[name.to_s] = old
55
56
  end
56
57
 
57
58
  def custom_wrapper
@@ -68,6 +69,62 @@ module MiscHelpers
68
69
  end
69
70
  end
70
71
 
72
+ def custom_wrapper_with_wrapped_optional_component
73
+ SimpleForm.build tag: :section, class: "custom_wrapper" do |b|
74
+ b.wrapper tag: :div, class: 'no_output_wrapper' do |ba|
75
+ ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }
76
+ end
77
+ end
78
+ end
79
+
80
+ def custom_wrapper_with_unless_blank
81
+ SimpleForm.build tag: :section, class: "custom_wrapper" do |b|
82
+ b.wrapper tag: :div, class: 'no_output_wrapper', unless_blank: true do |ba|
83
+ ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }
84
+ end
85
+ end
86
+ end
87
+
88
+ def custom_wrapper_with_input_class
89
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
90
+ b.use :label
91
+ b.use :input, class: 'inline-class'
92
+ end
93
+ end
94
+
95
+ def custom_wrapper_with_input_data_modal
96
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
97
+ b.use :label
98
+ b.use :input, data: { modal: 'data-modal', wrapper: 'data-wrapper' }
99
+ end
100
+ end
101
+
102
+ def custom_wrapper_with_input_aria_modal
103
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
104
+ b.use :label
105
+ b.use :input, aria: { modal: 'aria-modal', wrapper: 'aria-wrapper' }
106
+ end
107
+ end
108
+
109
+ def custom_wrapper_with_label_class
110
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
111
+ b.use :label, class: 'inline-class'
112
+ b.use :input
113
+ end
114
+ end
115
+
116
+ def custom_wrapper_with_input_attributes
117
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
118
+ b.use :input, data: { modal: true }
119
+ end
120
+ end
121
+
122
+ def custom_wrapper_with_label_input_class
123
+ SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
124
+ b.use :label_input, class: 'inline-class'
125
+ end
126
+ end
127
+
71
128
  def custom_wrapper_with_wrapped_input
72
129
  SimpleForm.build tag: :div, class: "custom_wrapper" do |b|
73
130
  b.wrapper tag: :div, class: 'elem' do |component|
@@ -112,12 +169,57 @@ module MiscHelpers
112
169
  end
113
170
  end
114
171
 
172
+ def custom_wrapper_with_additional_attributes
173
+ SimpleForm.build tag: :div, class: 'custom_wrapper', html: { data: { wrapper: :test }, title: 'some title' } do |b|
174
+ b.use :label_input
175
+ end
176
+ end
177
+
178
+ def custom_wrapper_with_full_error
179
+ SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|
180
+ b.use :full_error, wrap_with: { tag: :span, class: :error }
181
+ end
182
+ end
183
+
184
+ def custom_wrapper_with_label_text
185
+ SimpleForm.build label_text: proc { |label, required| "**#{label}**" } do |b|
186
+ b.use :label_input
187
+ end
188
+ end
189
+
190
+ def custom_wrapper_with_custom_label_component
191
+ SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
192
+ b.use :label_text
193
+ end
194
+ end
195
+
115
196
  def custom_wrapper_with_html5_components
116
197
  SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
117
198
  b.use :label_text
118
199
  end
119
200
  end
120
201
 
202
+ def custom_wrapper_with_required_input
203
+ SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|
204
+ b.use :html5
205
+ b.use :input, required: true
206
+ end
207
+ end
208
+
209
+ def custom_wrapper_with_input_error_class
210
+ SimpleForm.build tag: :div, class: "custom_wrapper", error_class: :field_with_errors do |b|
211
+ b.use :label
212
+ b.use :input, class: 'inline-class', error_class: 'is-invalid'
213
+ end
214
+ end
215
+
216
+ def custom_wrapper_with_input_valid_class(valid_class: :field_without_errors)
217
+ SimpleForm.build tag: :div, class: "custom_wrapper", valid_class: valid_class do |b|
218
+ b.use :label
219
+ b.use :input, class: 'inline-class', valid_class: 'is-valid'
220
+ end
221
+ end
222
+
121
223
  def custom_form_for(object, *args, &block)
122
224
  simple_form_for(object, *args, { builder: CustomFormBuilder }, &block)
123
225
  end
@@ -148,11 +250,17 @@ module MiscHelpers
148
250
  end
149
251
  end
150
252
 
151
- def with_input_for(object, attribute_name, type, options={})
253
+ def with_input_for(object, attribute_name, type, options = {})
152
254
  with_concat_form_for(object) do |f|
153
255
  f.input(attribute_name, options.merge(as: type))
154
256
  end
155
257
  end
258
+
259
+ def with_input_field_for(object, *args)
260
+ with_concat_form_for(object) do |f|
261
+ f.input_field(*args)
262
+ end
263
+ end
156
264
  end
157
265
 
158
266
  class CustomFormBuilder < SimpleForm::FormBuilder
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  class MockController
2
3
  attr_writer :action_name
3
4
 
@@ -9,7 +10,7 @@ class MockController
9
10
  defined?(@action_name) ? @action_name : "edit"
10
11
  end
11
12
 
12
- def url_for(*args)
13
+ def url_for(*)
13
14
  "http://example.com"
14
15
  end
15
16
 
@@ -17,8 +18,13 @@ class MockController
17
18
  {}
18
19
  end
19
20
 
21
+ def polymorphic_mappings(*); {}; end
22
+
20
23
  def hash_for_user_path(*); end
24
+
21
25
  def hash_for_validating_user_path(*); end
26
+
22
27
  def hash_for_other_validating_user_path(*); end
28
+
23
29
  def hash_for_users_path(*); end
24
30
  end