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