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
| @@ -22,16 +22,24 @@ class FormBuilderTest < ActionView::TestCase | |
| 22 22 | 
             
                end
         | 
| 23 23 | 
             
              end
         | 
| 24 24 |  | 
| 25 | 
            +
              test 'builder should work without controller' do
         | 
| 26 | 
            +
                stub_any_instance ActionView::TestCase, :controller, nil do
         | 
| 27 | 
            +
                  simple_form_for @user do |f|
         | 
| 28 | 
            +
                    assert f.input(:name)
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 25 33 | 
             
              test 'builder input should allow a block to configure input' do
         | 
| 26 34 | 
             
                with_form_for @user, :name do
         | 
| 27 | 
            -
                  text_field_tag :foo, :bar, : | 
| 35 | 
            +
                  text_field_tag :foo, :bar, id: :cool
         | 
| 28 36 | 
             
                end
         | 
| 29 37 | 
             
                assert_no_select 'input.string'
         | 
| 30 38 | 
             
                assert_select 'input#cool'
         | 
| 31 39 | 
             
              end
         | 
| 32 40 |  | 
| 33 41 | 
             
              test 'builder should allow adding custom input mappings for default input types' do
         | 
| 34 | 
            -
                swap SimpleForm, : | 
| 42 | 
            +
                swap SimpleForm, input_mappings: { /count$/ => :integer } do
         | 
| 35 43 | 
             
                  with_form_for @user, :post_count
         | 
| 36 44 | 
             
                  assert_no_select 'form input#user_post_count.string'
         | 
| 37 45 | 
             
                  assert_select 'form input#user_post_count.numeric.integer'
         | 
| @@ -39,7 +47,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 39 47 | 
             
              end
         | 
| 40 48 |  | 
| 41 49 | 
             
              test 'builder should allow to skip input_type class' do
         | 
| 42 | 
            -
                swap SimpleForm, : | 
| 50 | 
            +
                swap SimpleForm, generate_additional_classes_for: [:label, :wrapper] do
         | 
| 43 51 | 
             
                  with_form_for @user, :post_count
         | 
| 44 52 | 
             
                  assert_no_select "form input#user_post_count.integer"
         | 
| 45 53 | 
             
                  assert_select "form input#user_post_count"
         | 
| @@ -47,7 +55,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 47 55 | 
             
              end
         | 
| 48 56 |  | 
| 49 57 | 
             
              test 'builder should allow to add additional classes only for wrapper' do
         | 
| 50 | 
            -
                swap SimpleForm, : | 
| 58 | 
            +
                swap SimpleForm, generate_additional_classes_for: [:wrapper] do
         | 
| 51 59 | 
             
                  with_form_for @user, :post_count
         | 
| 52 60 | 
             
                  assert_no_select "form input#user_post_count.string"
         | 
| 53 61 | 
             
                  assert_no_select "form label#user_post_count.string"
         | 
| @@ -56,7 +64,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 56 64 | 
             
              end
         | 
| 57 65 |  | 
| 58 66 | 
             
              test 'builder should allow adding custom input mappings for integer input types' do
         | 
| 59 | 
            -
                swap SimpleForm, : | 
| 67 | 
            +
                swap SimpleForm, input_mappings: { /lock_version/ => :hidden } do
         | 
| 60 68 | 
             
                  with_form_for @user, :lock_version
         | 
| 61 69 | 
             
                  assert_no_select 'form input#user_lock_version.integer'
         | 
| 62 70 | 
             
                  assert_select 'form input#user_lock_version.hidden'
         | 
| @@ -64,7 +72,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 64 72 | 
             
              end
         | 
| 65 73 |  | 
| 66 74 | 
             
              test 'builder uses the first matching custom input map when more than one matches' do
         | 
| 67 | 
            -
                swap SimpleForm, : | 
| 75 | 
            +
                swap SimpleForm, input_mappings: { /count$/ => :integer, /^post_/ => :password } do
         | 
| 68 76 | 
             
                  with_form_for @user, :post_count
         | 
| 69 77 | 
             
                  assert_no_select 'form input#user_post_count.password'
         | 
| 70 78 | 
             
                  assert_select 'form input#user_post_count.numeric.integer'
         | 
| @@ -72,13 +80,26 @@ class FormBuilderTest < ActionView::TestCase | |
| 72 80 | 
             
              end
         | 
| 73 81 |  | 
| 74 82 | 
             
              test 'builder uses the custom map only for matched attributes' do
         | 
| 75 | 
            -
                swap SimpleForm, : | 
| 83 | 
            +
                swap SimpleForm, input_mappings: { /lock_version/ => :hidden } do
         | 
| 76 84 | 
             
                  with_form_for @user, :post_count
         | 
| 77 85 | 
             
                  assert_no_select 'form input#user_post_count.hidden'
         | 
| 78 86 | 
             
                  assert_select 'form input#user_post_count.string'
         | 
| 79 87 | 
             
                end
         | 
| 80 88 | 
             
              end
         | 
| 81 89 |  | 
| 90 | 
            +
              test 'builder allow to use numbers in the model name' do
         | 
| 91 | 
            +
                user = UserNumber1And2.build(tags: [Tag.new(nil, 'Tag1')])
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                with_concat_form_for(user, url: '/') do |f|
         | 
| 94 | 
            +
                  f.simple_fields_for(:tags) do |tags|
         | 
| 95 | 
            +
                    tags.input :name
         | 
| 96 | 
            +
                  end
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                assert_select 'form .user_number1_and2_tags_name'
         | 
| 100 | 
            +
                assert_no_select 'form .user_number1_and2_tags_1_name'
         | 
| 101 | 
            +
              end
         | 
| 102 | 
            +
             | 
| 82 103 | 
             
              # INPUT TYPES
         | 
| 83 104 | 
             
              test 'builder should generate text fields for string columns' do
         | 
| 84 105 | 
             
                with_form_for @user, :name
         | 
| @@ -156,64 +177,62 @@ class FormBuilderTest < ActionView::TestCase | |
| 156 177 | 
             
              end
         | 
| 157 178 |  | 
| 158 179 | 
             
              test 'builder should generate file for file columns' do
         | 
| 159 | 
            -
                @user.avatar =  | 
| 160 | 
            -
                @user.avatar. | 
| 161 | 
            -
                @user.avatar.expects(:respond_to?).with(:file?).returns(false)
         | 
| 162 | 
            -
                @user.avatar.expects(:respond_to?).with(:public_filename).returns(true)
         | 
| 180 | 
            +
                @user.avatar = MiniTest::Mock.new
         | 
| 181 | 
            +
                @user.avatar.expect(:public_filename, true)
         | 
| 163 182 |  | 
| 164 183 | 
             
                with_form_for @user, :avatar
         | 
| 165 184 | 
             
                assert_select 'form input#user_avatar.file'
         | 
| 166 185 | 
             
              end
         | 
| 167 186 |  | 
| 168 187 | 
             
              test 'builder should generate file for attributes that are real db columns but have file methods' do
         | 
| 169 | 
            -
                @user.home_picture =  | 
| 170 | 
            -
                @user.home_picture. | 
| 188 | 
            +
                @user.home_picture = MiniTest::Mock.new
         | 
| 189 | 
            +
                @user.home_picture.expect(:mounted_as, true)
         | 
| 171 190 |  | 
| 172 191 | 
             
                with_form_for @user, :home_picture
         | 
| 173 192 | 
             
                assert_select 'form input#user_home_picture.file'
         | 
| 174 193 | 
             
              end
         | 
| 175 194 |  | 
| 176 195 | 
             
              test 'build should generate select if a collection is given' do
         | 
| 177 | 
            -
                with_form_for @user, :age, : | 
| 196 | 
            +
                with_form_for @user, :age, collection: 1..60
         | 
| 178 197 | 
             
                assert_select 'form select#user_age.select'
         | 
| 179 198 | 
             
              end
         | 
| 180 199 |  | 
| 181 200 | 
             
              test 'builder should allow overriding default input type for text' do
         | 
| 182 | 
            -
                with_form_for @user, :name, : | 
| 201 | 
            +
                with_form_for @user, :name, as: :text
         | 
| 183 202 | 
             
                assert_no_select 'form input#user_name'
         | 
| 184 203 | 
             
                assert_select 'form textarea#user_name.text'
         | 
| 185 204 |  | 
| 186 | 
            -
                with_form_for @user, :active, : | 
| 205 | 
            +
                with_form_for @user, :active, as: :radio_buttons
         | 
| 187 206 | 
             
                assert_no_select 'form input[type=checkbox]'
         | 
| 188 | 
            -
                assert_select 'form input.radio_buttons[type=radio]', : | 
| 207 | 
            +
                assert_select 'form input.radio_buttons[type=radio]', count: 2
         | 
| 189 208 |  | 
| 190 | 
            -
                with_form_for @user, :born_at, : | 
| 209 | 
            +
                with_form_for @user, :born_at, as: :string
         | 
| 191 210 | 
             
                assert_no_select 'form select'
         | 
| 192 211 | 
             
                assert_select 'form input#user_born_at.string'
         | 
| 193 212 | 
             
              end
         | 
| 194 213 |  | 
| 195 214 | 
             
              # COMMON OPTIONS
         | 
| 196 215 | 
             
              test 'builder should add chosen form class' do
         | 
| 197 | 
            -
                swap SimpleForm, : | 
| 216 | 
            +
                swap SimpleForm, form_class: :my_custom_class do
         | 
| 198 217 | 
             
                  with_form_for @user, :name
         | 
| 199 218 | 
             
                  assert_select 'form.my_custom_class'
         | 
| 200 219 | 
             
                end
         | 
| 201 220 | 
             
              end
         | 
| 202 221 |  | 
| 203 222 | 
             
              test 'builder should allow passing options to input' do
         | 
| 204 | 
            -
                with_form_for @user, :name, : | 
| 223 | 
            +
                with_form_for @user, :name, input_html: { class: 'my_input', id: 'my_input' }
         | 
| 205 224 | 
             
                assert_select 'form input#my_input.my_input.string'
         | 
| 206 225 | 
             
              end
         | 
| 207 226 |  | 
| 208 227 | 
             
              test 'builder should not propagate input options to wrapper' do
         | 
| 209 | 
            -
                with_form_for @user, :name, : | 
| 228 | 
            +
                with_form_for @user, :name, input_html: { class: 'my_input', id: 'my_input' }
         | 
| 210 229 | 
             
                assert_no_select 'form div.input.my_input.string'
         | 
| 211 230 | 
             
                assert_select 'form input#my_input.my_input.string'
         | 
| 212 231 | 
             
              end
         | 
| 213 232 |  | 
| 214 233 | 
             
              test 'builder should not propagate input options to wrapper with custom wrapper' do
         | 
| 215 234 | 
             
                swap_wrapper :default, self.custom_wrapper_with_wrapped_input do
         | 
| 216 | 
            -
                  with_form_for @user, :name, : | 
| 235 | 
            +
                  with_form_for @user, :name, input_html: { class: 'my_input' }
         | 
| 217 236 | 
             
                  assert_no_select 'form div.input.my_input'
         | 
| 218 237 | 
             
                  assert_select 'form input.my_input.string'
         | 
| 219 238 | 
             
                end
         | 
| @@ -221,7 +240,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 221 240 |  | 
| 222 241 | 
             
              test 'builder should not propagate label options to wrapper with custom wrapper' do
         | 
| 223 242 | 
             
                swap_wrapper :default, self.custom_wrapper_with_wrapped_label do
         | 
| 224 | 
            -
                  with_form_for @user, :name, : | 
| 243 | 
            +
                  with_form_for @user, :name, label_html: { class: 'my_label' }
         | 
| 225 244 | 
             
                  assert_no_select 'form div.label.my_label'
         | 
| 226 245 | 
             
                  assert_select 'form label.my_label.string'
         | 
| 227 246 | 
             
                end
         | 
| @@ -233,22 +252,22 @@ class FormBuilderTest < ActionView::TestCase | |
| 233 252 | 
             
              end
         | 
| 234 253 |  | 
| 235 254 | 
             
              test 'builder should be able to disable the label for a input' do
         | 
| 236 | 
            -
                with_form_for @user, :name, : | 
| 255 | 
            +
                with_form_for @user, :name, label: false
         | 
| 237 256 | 
             
                assert_no_select 'form label'
         | 
| 238 257 | 
             
              end
         | 
| 239 258 |  | 
| 240 259 | 
             
              test 'builder should be able to disable the label for an input and return a html safe string' do
         | 
| 241 | 
            -
                with_form_for @user, :name, : | 
| 260 | 
            +
                with_form_for @user, :name, label: false, wrapper: custom_wrapper_with_wrapped_label_input
         | 
| 242 261 | 
             
                assert_select 'form input#user_name'
         | 
| 243 262 | 
             
              end
         | 
| 244 263 |  | 
| 245 264 | 
             
              test 'builder should use custom label' do
         | 
| 246 | 
            -
                with_form_for @user, :name, : | 
| 265 | 
            +
                with_form_for @user, :name, label: 'Yay!'
         | 
| 247 266 | 
             
                assert_select 'form label', /Yay!/
         | 
| 248 267 | 
             
              end
         | 
| 249 268 |  | 
| 250 269 | 
             
              test 'builder should pass options to label' do
         | 
| 251 | 
            -
                with_form_for @user, :name, : | 
| 270 | 
            +
                with_form_for @user, :name, label_html: { id: "cool" }
         | 
| 252 271 | 
             
                assert_select 'form label#cool', /Name/
         | 
| 253 272 | 
             
              end
         | 
| 254 273 |  | 
| @@ -258,21 +277,21 @@ class FormBuilderTest < ActionView::TestCase | |
| 258 277 | 
             
              end
         | 
| 259 278 |  | 
| 260 279 | 
             
              test 'builder should be able to add a hint for a input' do
         | 
| 261 | 
            -
                with_form_for @user, :name, : | 
| 280 | 
            +
                with_form_for @user, :name, hint: 'test'
         | 
| 262 281 | 
             
                assert_select 'span.hint', 'test'
         | 
| 263 282 | 
             
              end
         | 
| 264 283 |  | 
| 265 284 | 
             
              test 'builder should be able to disable a hint even if it exists in i18n' do
         | 
| 266 | 
            -
                store_translations(:en, : | 
| 267 | 
            -
                  SimpleForm::Inputs::Base | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
                   | 
| 285 | 
            +
                store_translations(:en, simple_form: { hints: { name: 'Hint test' } }) do
         | 
| 286 | 
            +
                  stub_any_instance(SimpleForm::Inputs::Base, :hint, -> { raise 'Never' }) do
         | 
| 287 | 
            +
                    with_form_for @user, :name, hint: false
         | 
| 288 | 
            +
                    assert_no_select 'span.hint'
         | 
| 289 | 
            +
                  end
         | 
| 271 290 | 
             
                end
         | 
| 272 291 | 
             
              end
         | 
| 273 292 |  | 
| 274 293 | 
             
              test 'builder should pass options to hint' do
         | 
| 275 | 
            -
                with_form_for @user, :name, : | 
| 294 | 
            +
                with_form_for @user, :name, hint: 'test', hint_html: { id: "cool" }
         | 
| 276 295 | 
             
                assert_select 'span.hint#cool', 'test'
         | 
| 277 296 | 
             
              end
         | 
| 278 297 |  | 
| @@ -287,20 +306,20 @@ class FormBuilderTest < ActionView::TestCase | |
| 287 306 | 
             
              end
         | 
| 288 307 |  | 
| 289 308 | 
             
              test 'builder should be able to disable showing errors for a input' do
         | 
| 290 | 
            -
                with_form_for @user, :name, : | 
| 309 | 
            +
                with_form_for @user, :name, error: false
         | 
| 291 310 | 
             
                assert_no_select 'span.error'
         | 
| 292 311 | 
             
              end
         | 
| 293 312 |  | 
| 294 313 | 
             
              test 'builder should pass options to errors' do
         | 
| 295 | 
            -
                with_form_for @user, :name, : | 
| 314 | 
            +
                with_form_for @user, :name, error_html: { id: "cool" }
         | 
| 296 315 | 
             
                assert_select 'span.error#cool', "can't be blank"
         | 
| 297 316 | 
             
              end
         | 
| 298 317 |  | 
| 299 318 | 
             
              test 'placeholder should not be generated when set to false' do
         | 
| 300 | 
            -
                store_translations(:en, : | 
| 301 | 
            -
                  : | 
| 319 | 
            +
                store_translations(:en, simple_form: { placeholders: { user: {
         | 
| 320 | 
            +
                  name: 'Name goes here'
         | 
| 302 321 | 
             
                } } }) do
         | 
| 303 | 
            -
                  with_form_for @user, :name, : | 
| 322 | 
            +
                  with_form_for @user, :name, placeholder: false
         | 
| 304 323 | 
             
                  assert_no_select 'input[placeholder]'
         | 
| 305 324 | 
             
                end
         | 
| 306 325 | 
             
              end
         | 
| @@ -308,14 +327,14 @@ class FormBuilderTest < ActionView::TestCase | |
| 308 327 | 
             
              # DEFAULT OPTIONS
         | 
| 309 328 | 
             
              [:input, :input_field].each do |method|
         | 
| 310 329 | 
             
                test "builder should receive a default argument and pass it to the inputs when calling '#{method}'" do
         | 
| 311 | 
            -
                  with_concat_form_for @user, : | 
| 330 | 
            +
                  with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
         | 
| 312 331 | 
             
                    f.send(method, :name)
         | 
| 313 332 | 
             
                  end
         | 
| 314 333 | 
             
                  assert_select 'input.default_class'
         | 
| 315 334 | 
             
                end
         | 
| 316 335 |  | 
| 317 336 | 
             
                test "builder should receive a default argument and pass it to the inputs without changing the defaults when calling '#{method}'" do
         | 
| 318 | 
            -
                  with_concat_form_for @user, : | 
| 337 | 
            +
                  with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|
         | 
| 319 338 | 
             
                    concat(f.send(method, :name))
         | 
| 320 339 | 
             
                    concat(f.send(method, :credit_limit))
         | 
| 321 340 | 
             
                  end
         | 
| @@ -327,7 +346,7 @@ class FormBuilderTest < ActionView::TestCase | |
| 327 346 | 
             
                test "builder should receive a default argument and pass it to the inputs and nested form when calling '#{method}'" do
         | 
| 328 347 | 
             
                  @user.company = Company.new(1, 'Empresa')
         | 
| 329 348 |  | 
| 330 | 
            -
                  with_concat_form_for @user, : | 
| 349 | 
            +
                  with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
         | 
| 331 350 | 
             
                    concat(f.send(method, :name))
         | 
| 332 351 | 
             
                    concat(f.simple_fields_for(:company) do |company_form|
         | 
| 333 352 | 
             
                      concat(company_form.send(method, :name))
         | 
| @@ -340,29 +359,29 @@ class FormBuilderTest < ActionView::TestCase | |
| 340 359 | 
             
              end
         | 
| 341 360 |  | 
| 342 361 | 
             
              test "builder should receive a default argument and pass it to the inputs when calling 'input', respecting the specific options" do
         | 
| 343 | 
            -
                with_concat_form_for @user, : | 
| 344 | 
            -
                  f.input :name, : | 
| 362 | 
            +
                with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
         | 
| 363 | 
            +
                  f.input :name, input_html: { id: 'specific_id' }
         | 
| 345 364 | 
             
                end
         | 
| 346 365 | 
             
                assert_select 'input.default_class#specific_id'
         | 
| 347 366 | 
             
              end
         | 
| 348 367 |  | 
| 349 368 | 
             
              test "builder should receive a default argument and pass it to the inputs when calling 'input_field', respecting the specific options" do
         | 
| 350 | 
            -
                with_concat_form_for @user, : | 
| 351 | 
            -
                  f.input_field :name, : | 
| 369 | 
            +
                with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|
         | 
| 370 | 
            +
                  f.input_field :name, id: 'specific_id'
         | 
| 352 371 | 
             
                end
         | 
| 353 372 | 
             
                assert_select 'input.default_class#specific_id'
         | 
| 354 373 | 
             
              end
         | 
| 355 374 |  | 
| 356 375 | 
             
              test "builder should receive a default argument and pass it to the inputs when calling 'input', overwriting the defaults with specific options" do
         | 
| 357 | 
            -
                with_concat_form_for @user, : | 
| 358 | 
            -
                  f.input :name, : | 
| 376 | 
            +
                with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|
         | 
| 377 | 
            +
                  f.input :name, input_html: { id: 'specific_id' }
         | 
| 359 378 | 
             
                end
         | 
| 360 379 | 
             
                assert_select 'input.default_class#specific_id'
         | 
| 361 380 | 
             
              end
         | 
| 362 381 |  | 
| 363 382 | 
             
              test "builder should receive a default argument and pass it to the inputs when calling 'input_field', overwriting the defaults with specific options" do
         | 
| 364 | 
            -
                with_concat_form_for @user, : | 
| 365 | 
            -
                  f.input_field :name, : | 
| 383 | 
            +
                with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|
         | 
| 384 | 
            +
                  f.input_field :name, id: 'specific_id'
         | 
| 366 385 | 
             
                end
         | 
| 367 386 | 
             
                assert_select 'input.default_class#specific_id'
         | 
| 368 387 | 
             
              end
         | 
| @@ -386,9 +405,9 @@ class FormBuilderTest < ActionView::TestCase | |
| 386 405 | 
             
              end
         | 
| 387 406 |  | 
| 388 407 | 
             
              test 'builder should allow overriding input type when object is not present' do
         | 
| 389 | 
            -
                with_form_for :project, :created_at, : | 
| 408 | 
            +
                with_form_for :project, :created_at, as: :datetime
         | 
| 390 409 | 
             
                assert_select 'form select.datetime#project_created_at_1i'
         | 
| 391 | 
            -
                with_form_for :project, :budget, : | 
| 410 | 
            +
                with_form_for :project, :budget, as: :decimal
         | 
| 392 411 | 
             
                assert_select 'form input.decimal#project_budget'
         | 
| 393 412 | 
             
              end
         | 
| 394 413 |  | 
| @@ -14,36 +14,36 @@ class HintTest < ActionView::TestCase | |
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 16 | 
             
              test 'hint should be generated with optional text' do
         | 
| 17 | 
            -
                with_hint_for @user, :name, : | 
| 17 | 
            +
                with_hint_for @user, :name, hint: 'Use with care...'
         | 
| 18 18 | 
             
                assert_select 'span.hint', 'Use with care...'
         | 
| 19 19 | 
             
              end
         | 
| 20 20 |  | 
| 21 21 | 
             
              test 'hint should not modify the options hash' do
         | 
| 22 | 
            -
                options = { : | 
| 22 | 
            +
                options = { hint: 'Use with care...' }
         | 
| 23 23 | 
             
                with_hint_for @user, :name, options
         | 
| 24 24 | 
             
                assert_select 'span.hint', 'Use with care...'
         | 
| 25 | 
            -
                assert_equal({ : | 
| 25 | 
            +
                assert_equal({ hint: 'Use with care...' }, options)
         | 
| 26 26 | 
             
              end
         | 
| 27 27 |  | 
| 28 28 | 
             
              test 'hint should be generated cleanly with optional text' do
         | 
| 29 | 
            -
                with_hint_for @user, :name, : | 
| 29 | 
            +
                with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :span
         | 
| 30 30 | 
             
                assert_no_select 'span.hint[hint]'
         | 
| 31 31 | 
             
                assert_no_select 'span.hint[hint_tag]'
         | 
| 32 32 | 
             
                assert_no_select 'span.hint[hint_html]'
         | 
| 33 33 | 
             
              end
         | 
| 34 34 |  | 
| 35 35 | 
             
              test 'hint uses the current component tag set' do
         | 
| 36 | 
            -
                with_hint_for @user, :name, : | 
| 36 | 
            +
                with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :p
         | 
| 37 37 | 
             
                assert_select 'p.hint', 'Use with care...'
         | 
| 38 38 | 
             
              end
         | 
| 39 39 |  | 
| 40 40 | 
             
              test 'hint should be able to pass html options' do
         | 
| 41 | 
            -
                with_hint_for @user, :name, : | 
| 41 | 
            +
                with_hint_for @user, :name, hint: 'Yay!', id: 'hint', class: 'yay'
         | 
| 42 42 | 
             
                assert_select 'span#hint.hint.yay'
         | 
| 43 43 | 
             
              end
         | 
| 44 44 |  | 
| 45 45 | 
             
              test 'hint should be output as html_safe' do
         | 
| 46 | 
            -
                with_hint_for @user, :name, : | 
| 46 | 
            +
                with_hint_for @user, :name, hint: '<b>Bold</b> and not...'
         | 
| 47 47 | 
             
                assert_select 'span.hint', 'Bold and not...'
         | 
| 48 48 | 
             
              end
         | 
| 49 49 |  | 
| @@ -61,22 +61,22 @@ class HintTest < ActionView::TestCase | |
| 61 61 | 
             
              end
         | 
| 62 62 |  | 
| 63 63 | 
             
              test 'hint without attribute name uses the current component tag set' do
         | 
| 64 | 
            -
                with_hint_for @user, 'Hello World!', : | 
| 64 | 
            +
                with_hint_for @user, 'Hello World!', hint_tag: :p
         | 
| 65 65 | 
             
                assert_no_select 'p.hint[hint]'
         | 
| 66 66 | 
             
                assert_no_select 'p.hint[hint_html]'
         | 
| 67 67 | 
             
                assert_no_select 'p.hint[hint_tag]'
         | 
| 68 68 | 
             
              end
         | 
| 69 69 |  | 
| 70 70 | 
             
              test 'hint without attribute name should be able to pass html options' do
         | 
| 71 | 
            -
                with_hint_for @user, 'Yay', : | 
| 71 | 
            +
                with_hint_for @user, 'Yay', id: 'hint', class: 'yay'
         | 
| 72 72 | 
             
                assert_select 'span#hint.hint.yay', 'Yay'
         | 
| 73 73 | 
             
              end
         | 
| 74 74 |  | 
| 75 75 | 
             
              # I18n
         | 
| 76 76 |  | 
| 77 77 | 
             
              test 'hint should use i18n based on model, action, and attribute to lookup translation' do
         | 
| 78 | 
            -
                store_translations(:en, : | 
| 79 | 
            -
                  : | 
| 78 | 
            +
                store_translations(:en, simple_form: { hints: { user: {
         | 
| 79 | 
            +
                  edit: { name: 'Content of this input will be truncated...' }
         | 
| 80 80 | 
             
                } } }) do
         | 
| 81 81 | 
             
                  with_hint_for @user, :name
         | 
| 82 82 | 
             
                  assert_select 'span.hint', 'Content of this input will be truncated...'
         | 
| @@ -84,8 +84,8 @@ class HintTest < ActionView::TestCase | |
| 84 84 | 
             
              end
         | 
| 85 85 |  | 
| 86 86 | 
             
              test 'hint should use i18n with model and attribute to lookup translation' do
         | 
| 87 | 
            -
                store_translations(:en, : | 
| 88 | 
            -
                  : | 
| 87 | 
            +
                store_translations(:en, simple_form: { hints: { user: {
         | 
| 88 | 
            +
                  name: 'Content of this input will be capitalized...'
         | 
| 89 89 | 
             
                } } }) do
         | 
| 90 90 | 
             
                  with_hint_for @user, :name
         | 
| 91 91 | 
             
                  assert_select 'span.hint', 'Content of this input will be capitalized...'
         | 
| @@ -93,8 +93,8 @@ class HintTest < ActionView::TestCase | |
| 93 93 | 
             
              end
         | 
| 94 94 |  | 
| 95 95 | 
             
              test 'hint should use i18n under defaults namespace to lookup translation' do
         | 
| 96 | 
            -
                store_translations(:en, : | 
| 97 | 
            -
                  : | 
| 96 | 
            +
                store_translations(:en, simple_form: {
         | 
| 97 | 
            +
                  hints: { defaults: { name: 'Content of this input will be downcased...' } }
         | 
| 98 98 | 
             
                }) do
         | 
| 99 99 | 
             
                  with_hint_for @user, :name
         | 
| 100 100 | 
             
                  assert_select 'span.hint', 'Content of this input will be downcased...'
         | 
| @@ -102,17 +102,17 @@ class HintTest < ActionView::TestCase | |
| 102 102 | 
             
              end
         | 
| 103 103 |  | 
| 104 104 | 
             
              test 'hint should use i18n with lookup for association name' do
         | 
| 105 | 
            -
                store_translations(:en, : | 
| 106 | 
            -
                  : | 
| 105 | 
            +
                store_translations(:en, simple_form: { hints: {
         | 
| 106 | 
            +
                  user: { company: 'My company!' }
         | 
| 107 107 | 
             
                } } ) do
         | 
| 108 | 
            -
                  with_hint_for @user, :company_id, : | 
| 108 | 
            +
                  with_hint_for @user, :company_id, as: :string, reflection: Association.new(Company, :company, {})
         | 
| 109 109 | 
             
                  assert_select 'span.hint', /My company!/
         | 
| 110 110 | 
             
                end
         | 
| 111 111 | 
             
              end
         | 
| 112 112 |  | 
| 113 113 | 
             
              test 'hint should output translations as html_safe' do
         | 
| 114 | 
            -
                store_translations(:en, : | 
| 115 | 
            -
                  : | 
| 114 | 
            +
                store_translations(:en, simple_form: { hints: { user: {
         | 
| 115 | 
            +
                  edit: { name: '<b>This is bold</b> and this is not...' }
         | 
| 116 116 | 
             
                } } }) do
         | 
| 117 117 | 
             
                  with_hint_for @user, :name
         | 
| 118 118 | 
             
                  assert_select 'span.hint', 'This is bold and this is not...'
         | 
| @@ -123,7 +123,7 @@ class HintTest < ActionView::TestCase | |
| 123 123 | 
             
              # No object
         | 
| 124 124 |  | 
| 125 125 | 
             
              test 'hint should generate properly when object is not present' do
         | 
| 126 | 
            -
                with_hint_for :project, :name, : | 
| 126 | 
            +
                with_hint_for :project, :name, hint: 'Test without object'
         | 
| 127 127 | 
             
                assert_select 'span.hint', 'Test without object'
         | 
| 128 128 | 
             
              end
         | 
| 129 129 |  | 
| @@ -131,7 +131,7 @@ class HintTest < ActionView::TestCase | |
| 131 131 |  | 
| 132 132 | 
             
              test 'hint with custom wrappers works' do
         | 
| 133 133 | 
             
                swap_wrapper do
         | 
| 134 | 
            -
                  with_hint_for @user, :name, : | 
| 134 | 
            +
                  with_hint_for @user, :name, hint: "can't be blank"
         | 
| 135 135 | 
             
                  assert_select 'div.omg_hint', "can't be blank"
         | 
| 136 136 | 
             
                end
         | 
| 137 137 | 
             
              end
         | 
| @@ -14,36 +14,53 @@ class InputFieldTest < ActionView::TestCase | |
| 14 14 |  | 
| 15 15 | 
             
              test 'builder input_field should allow overriding default input type' do
         | 
| 16 16 | 
             
                with_concat_form_for(@user) do |f|
         | 
| 17 | 
            -
                  f.input_field :name, : | 
| 17 | 
            +
                  f.input_field :name, as: :text
         | 
| 18 18 | 
             
                end
         | 
| 19 19 |  | 
| 20 20 | 
             
                assert_no_select 'input#user_name'
         | 
| 21 21 | 
             
                assert_select 'textarea#user_name.text'
         | 
| 22 22 | 
             
              end
         | 
| 23 23 |  | 
| 24 | 
            +
              test 'builder input_field should generate input type based on column type' do
         | 
| 25 | 
            +
                with_concat_form_for(@user) do |f|
         | 
| 26 | 
            +
                  f.input_field :age
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                assert_select 'input[type=number].integer#user_age'
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              test 'builder input_field should be able to disable any component' do
         | 
| 33 | 
            +
                with_concat_form_for(@user) do |f|
         | 
| 34 | 
            +
                  f.input_field :age, html5: false
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                assert_no_select 'input[html5=false]#user_age'
         | 
| 38 | 
            +
                assert_select 'input[type=text].integer#user_age'
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 24 41 | 
             
              test 'builder input_field should allow passing options to input tag' do
         | 
| 25 42 | 
             
                with_concat_form_for(@user) do |f|
         | 
| 26 | 
            -
                  f.input_field :name, : | 
| 43 | 
            +
                  f.input_field :name, id: 'name_input', class: 'name'
         | 
| 27 44 | 
             
                end
         | 
| 28 45 |  | 
| 29 46 | 
             
                assert_select 'input.string.name#name_input'
         | 
| 30 47 | 
             
              end
         | 
| 31 48 |  | 
| 32 49 | 
             
              test 'builder input_field should not modify the options hash' do
         | 
| 33 | 
            -
                options = { : | 
| 50 | 
            +
                options = { id: 'name_input', class: 'name' }
         | 
| 34 51 |  | 
| 35 52 | 
             
                with_concat_form_for(@user) do |f|
         | 
| 36 53 | 
             
                  f.input_field :name, options
         | 
| 37 54 | 
             
                end
         | 
| 38 55 |  | 
| 39 56 | 
             
                assert_select 'input.string.name#name_input'
         | 
| 40 | 
            -
                assert_equal({ : | 
| 57 | 
            +
                assert_equal({ id: 'name_input', class: 'name' }, options)
         | 
| 41 58 | 
             
              end
         | 
| 42 59 |  | 
| 43 60 |  | 
| 44 61 | 
             
              test 'builder input_field should generate an input tag with a clean HTML' do
         | 
| 45 62 | 
             
                with_concat_form_for(@user) do |f|
         | 
| 46 | 
            -
                  f.input_field :name, : | 
| 63 | 
            +
                  f.input_field :name, as: :integer, class: 'name'
         | 
| 47 64 | 
             
                end
         | 
| 48 65 |  | 
| 49 66 | 
             
                assert_no_select 'input.integer[input_html]'
         | 
| @@ -51,8 +68,8 @@ class InputFieldTest < ActionView::TestCase | |
| 51 68 | 
             
              end
         | 
| 52 69 |  | 
| 53 70 | 
             
              test 'builder input_field should use i18n to translate placeholder text' do
         | 
| 54 | 
            -
                store_translations(:en, : | 
| 55 | 
            -
                  : | 
| 71 | 
            +
                store_translations(:en, simple_form: { placeholders: { user: {
         | 
| 72 | 
            +
                  name: 'Name goes here'
         | 
| 56 73 | 
             
                } } }) do
         | 
| 57 74 |  | 
| 58 75 | 
             
                  with_concat_form_for(@user) do |f|
         | 
| @@ -65,7 +82,7 @@ class InputFieldTest < ActionView::TestCase | |
| 65 82 |  | 
| 66 83 | 
             
              test 'builder input_field should use min_max component' do
         | 
| 67 84 | 
             
                with_concat_form_for(@other_validating_user) do |f|
         | 
| 68 | 
            -
                  f.input_field :age, : | 
| 85 | 
            +
                  f.input_field :age, as: :integer
         | 
| 69 86 | 
             
                end
         | 
| 70 87 |  | 
| 71 88 | 
             
                assert_select 'input[min=18]'
         | 
| @@ -73,7 +90,7 @@ class InputFieldTest < ActionView::TestCase | |
| 73 90 |  | 
| 74 91 | 
             
              test 'builder input_field should use pattern component' do
         | 
| 75 92 | 
             
                with_concat_form_for(@other_validating_user) do |f|
         | 
| 76 | 
            -
                  f.input_field :country, : | 
| 93 | 
            +
                  f.input_field :country, as: :string
         | 
| 77 94 | 
             
                end
         | 
| 78 95 |  | 
| 79 96 | 
             
                assert_select 'input[pattern="\w+"]'
         | 
| @@ -81,7 +98,7 @@ class InputFieldTest < ActionView::TestCase | |
| 81 98 |  | 
| 82 99 | 
             
              test 'builder input_field should use readonly component' do
         | 
| 83 100 | 
             
                with_concat_form_for(@other_validating_user) do |f|
         | 
| 84 | 
            -
                  f.input_field :age, : | 
| 101 | 
            +
                  f.input_field :age, as: :integer, readonly: true
         | 
| 85 102 | 
             
                end
         | 
| 86 103 |  | 
| 87 104 | 
             
                assert_select 'input.integer.readonly[readonly]'
         | 
| @@ -89,7 +106,7 @@ class InputFieldTest < ActionView::TestCase | |
| 89 106 |  | 
| 90 107 | 
             
              test 'builder input_field should use maxlength component' do
         | 
| 91 108 | 
             
                with_concat_form_for(@validating_user) do |f|
         | 
| 92 | 
            -
                  f.input_field :name, : | 
| 109 | 
            +
                  f.input_field :name, as: :string
         | 
| 93 110 | 
             
                end
         | 
| 94 111 |  | 
| 95 112 | 
             
                assert_select 'input.string[maxlength=25]'
         | 
| @@ -97,7 +114,7 @@ class InputFieldTest < ActionView::TestCase | |
| 97 114 |  | 
| 98 115 | 
             
              test 'builder collection input_field should generate input tag with a clean HTML' do
         | 
| 99 116 | 
             
                with_concat_form_for(@user) do |f|
         | 
| 100 | 
            -
                  f.input_field :status, : | 
| 117 | 
            +
                  f.input_field :status, collection: ['Open', 'Closed'], class: 'status', label_method: :to_s, value_method: :to_s
         | 
| 101 118 | 
             
                end
         | 
| 102 119 |  | 
| 103 120 | 
             
                assert_no_select 'select.status[input_html]'
         | 
| @@ -14,12 +14,12 @@ class LabelTest < ActionView::TestCase | |
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 16 | 
             
              test 'builder should generate a label for the boolean attrbiute' do
         | 
| 17 | 
            -
                with_label_for @user, :name, : | 
| 17 | 
            +
                with_label_for @user, :name, as: :boolean
         | 
| 18 18 | 
             
                assert_select 'label.boolean[for=user_name]', /Name/
         | 
| 19 19 | 
             
                assert_no_select 'label[as=boolean]'
         | 
| 20 20 | 
             
              end
         | 
| 21 21 |  | 
| 22 | 
            -
              test 'builder should generate a label  | 
| 22 | 
            +
              test 'builder should generate a label component tag with a clean HTML' do
         | 
| 23 23 | 
             
                with_label_for @user, :name
         | 
| 24 24 | 
             
                assert_no_select 'label.string[label_html]'
         | 
| 25 25 | 
             
              end
         | 
| @@ -30,22 +30,22 @@ class LabelTest < ActionView::TestCase | |
| 30 30 | 
             
              end
         | 
| 31 31 |  | 
| 32 32 | 
             
              test 'builder should allow passing options to label tag' do
         | 
| 33 | 
            -
                with_label_for @user, :name, : | 
| 33 | 
            +
                with_label_for @user, :name, label: 'My label', id: 'name_label'
         | 
| 34 34 | 
             
                assert_select 'label.string#name_label', /My label/
         | 
| 35 35 | 
             
              end
         | 
| 36 36 |  | 
| 37 37 | 
             
              test 'builder label should generate label tag with clean HTML' do
         | 
| 38 | 
            -
                with_label_for @user, :name, : | 
| 38 | 
            +
                with_label_for @user, :name, label: 'My label', required: true, id: 'name_label'
         | 
| 39 39 | 
             
                assert_select 'label.string#name_label', /My label/
         | 
| 40 40 | 
             
                assert_no_select 'label[label]'
         | 
| 41 41 | 
             
                assert_no_select 'label[required]'
         | 
| 42 42 | 
             
              end
         | 
| 43 43 |  | 
| 44 44 | 
             
              test 'builder should not modify the options hash' do
         | 
| 45 | 
            -
                options = { : | 
| 45 | 
            +
                options = { label: 'My label', id: 'name_label' }
         | 
| 46 46 | 
             
                with_label_for @user, :name, options
         | 
| 47 47 | 
             
                assert_select 'label.string#name_label', /My label/
         | 
| 48 | 
            -
                assert_equal({ : | 
| 48 | 
            +
                assert_equal({ label: 'My label', id: 'name_label' }, options)
         | 
| 49 49 | 
             
              end
         | 
| 50 50 |  | 
| 51 51 | 
             
              test 'builder should fallback to default label when string is given' do
         | 
| @@ -63,7 +63,7 @@ class LabelTest < ActionView::TestCase | |
| 63 63 | 
             
              end
         | 
| 64 64 |  | 
| 65 65 | 
             
              test 'builder allows label order to be changed' do
         | 
| 66 | 
            -
                swap SimpleForm, : | 
| 66 | 
            +
                swap SimpleForm, label_text: lambda { |l, r| "#{l}:" } do
         | 
| 67 67 | 
             
                  with_label_for @user, :age
         | 
| 68 68 | 
             
                  assert_select 'label.integer[for=user_age]', "Age:"
         | 
| 69 69 | 
             
                end
         |