[
  {
    "path": ".github/code-scanning.yml",
    "content": "paths-ignore:\n  - test/**\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Test\n\npermissions:\n  contents: read\non:\n  push:\n    branches:\n      - main\n  pull_request:\n  workflow_dispatch:\njobs:\n  test:\n    strategy:\n      fail-fast: false\n      matrix:\n        gemfile:\n          - Gemfile\n          - gemfiles/Gemfile-rails-main\n          - gemfiles/Gemfile-rails-8-0\n          - gemfiles/Gemfile-rails-7-2\n          - gemfiles/Gemfile-rails-7-1\n          - gemfiles/Gemfile-rails-7-0\n        ruby:\n          - '4.0'\n          - '3.4'\n          - '3.3'\n          - '3.2'\n          - '3.1'\n          - '3.0'\n          - '2.7'\n        exclude:\n          - gemfile: Gemfile\n            ruby: '3.1'\n          - gemfile: Gemfile\n            ruby: '3.0'\n          - gemfile: Gemfile\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.2'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.1'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-main\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '3.1'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-8-0\n            ruby: '2.7'\n          - gemfile: gemfiles/Gemfile-rails-7-2\n            ruby: '3.0'\n          - gemfile: gemfiles/Gemfile-rails-7-2\n            ruby: '2.7'\n    runs-on: ubuntu-latest\n    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps\n      BUNDLE_GEMFILE: ${{ matrix.gemfile }}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: ruby/setup-ruby@v1\n        with:\n          ruby-version: ${{ matrix.ruby }}\n          bundler-cache: true # runs bundle install and caches installed gems automatically\n      - run: bundle exec rake\n"
  },
  {
    "path": ".gitignore",
    "content": ".bundle/\npkg/\nrdoc/\ngemfiles/*.lock\n/.idea/\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "## 5.4.1\n\n* Ruby 4.0 support (no changes required)\n* Support procs on validators for minlength/maxlength, and improve validators logic across the board to match Rails [#1859](https://github.com/heartcombo/simple_form/pull/1859)\n\n## 5.4.0\n\n* Add support for Ruby 3.4 and Rails 7.2/8.0/8.1. (no changes required)\n* Drop support for Rails < 7 and Ruby < 2.7.\n* Add `weekday` input. [#1846](https://github.com/heartcombo/simple_form/pull/1846)\n* Remove redundant `aria-required` attribute for required fields. [#1823](https://github.com/heartcombo/simple_form/pull/1823)\n* Integrate `:rich_text_area` with placeholders [#1842](https://github.com/heartcombo/simple_form/pull/1842)\n* Fix encrypted attributes improperly casted (later fixed in Rails) [#1836](https://github.com/heartcombo/simple_form/pull/1836)\n* Pass `base` object to `human_attribute_name` in labels [#1812](https://github.com/heartcombo/simple_form/pull/1812)\n\n## 5.3.1\n\n* Revert \"Speed up input mapping lookup by avoiding rescuing exceptions\" from v5.3.0, it caused a regression on dev/test environments with custom inputs.\n* Try a slightly different approach to input lookups, without relying on regexp, to see if that helps with performance as originally intended.\n* Add support to Ruby 3.3. (no changes required.)\n\n## 5.3.0\n\n* Add support for Rails 7.1. (no meaningful changes required.)\n* Add `SimpleForm.deprecator` to integrate with new application deprecators in Rails 7.1.\n* Remove test files from the gem package. [@orien](https://github.com/orien)\n* Speed up input mapping lookup by avoiding rescuing exceptions. [@meanphil](https://github.com/meanphil) [@kriom](https://github.com/kriom) [@egeek](https://github.com/egeek)\n\n## 5.2.0\n\n* Add support for Rails 7.0 and Ruby 3.1/3.2 (no changes required)\n* Fix escaping issue on boolean input with `include_hidden: false` and custom wrapper.\n* Update Bootstrap install generator version 5. [@mhw](https://github.com/mhw)\n* Accept proc as `group_method` for grouped collection select\n* Honor `include_hidden` option on inline boolean inputs [@yboulkaid](https://github.com/yboulkaid)\n* Fix deprecation error when using country_select input.\n\n## 5.1.0\n\n* Remove `I18nCache` module entirely. It was added complexity for very little gain in some translations, and caused extra trouble upgrading to Ruby 3. If you need that level of caching consider looking into I18n caching as a whole.\n* Add support for Ruby 3.0, drop support for Ruby < 2.5.\n* Add support for Rails 6.1, drop support for Rails < 5.2.\n* Move CI to GitHub Actions.\n\n## 5.0.3\n\n### Bug fix\n* Fix for ActiveStorage::Attached::Many. [@enriquez](https://github.com/enriquez)\n\n## 5.0.2\n\n### Enhancements\n* Remove instruction to use form-inline class. [@goalaleo](https://github.com/goalaleo)\n* Added RichTextAreaInput for ActionText. [itsterry](https://github.com/itsterry)\n* Skip valid_class check if no class defined. [TALlama](https://github.com/TALlama)\n\n### Bug fix\n* Fix 'aria-required' field generated by prompt. [@CarlosAlbertoSantos](https://github.com/CarlosAlbertoSantos)\n\n## 5.0.1\n\n### Bug fix\n* Replace `_url` with `remote_url` when trying to guess file inputs [@tegon](https://github.com/tegon). This has the side-effect of changing carrierwave's support from `0.2.1` to `0.2.2`.\n\n## 5.0.0\n\n### Enhancements\n* Set multiple attribute for grouped selects also. [@ollym](https://github.com/ollym)\n* Removes or renames label classes. [Abduvakilov](https://github.com/Abduvakilov)\n* Support to label custom classes for inline collections. [@feliperenan](https://github.com/feliperenan)\n* Update bootstrap generator template to match v4.3.x. [@m5o](https://github.com/m5o)\n* Allow \"required\" attribute in generated select elements of PriorityInput. [@mcountis](https://github.com/mcountis)\n\n### Bug fix\n* Do not call `#send` in form object to check whether the attribute is a file input. [@tegon](https://github.com/tegon)\n\n## Deprecations\n* The config `SimpleForm.file_methods` is deprecated and it has no effect. Simple Form now supports automatically discover of file inputs for the following Gems: activestorage, carrierwave, paperclip, refile and shrine. If you are using a custom method that is not from one of the supported Gems, please change your forms to pass the input type explicitly:\n\n```erb\n <%= form.input :avatar, as: :file %>\n ```\n\nSee http://blog.plataformatec.com.br/2019/09/incorrect-access-control-in-simple-form-cve-2019-16676 for more information.\n\n## 4.1.0\n\n### Enhancements\n* Guess input type more carefully. [@sringling](https://github.com/sringling)\n* Allow custom error on forms without model. [@victorperez](https://github.com/victorperez)\n* Do not support Ruby < 2.3 anymore. [@gssbzn](https://github.com/gssbzn)\n* Add color input type. [@gssbzn](https://github.com/gssbzn)\n\n### Bug fix\n* Improve disabled option to input_field. [@betelgeuse](https://github.com/betelgeuse)\n* Memoize `input_html_classes` in `SimpleForm::Inputs::Base`. [@RigoTheDev](https://github.com/RigoTheDev)\n* Fix column type citext HTML5 input type bug. [@brucew](https://github.com/brucew)\n* Use form attribute in the nested boolean hidden field when it is given. [@feliperenan](https://github.com/feliperenan)\n\n## 4.0.1\n\n### Bug fix\n* Do not support Rails 4 anymore. [@rafaelfranca](https://github.com/rafaelfranca)\n* Add missing comma. [@vill](https://github.com/vill)\n\n## 4.0.0\n\n### Enhancements\n* Add bootstrap v4.1 generator template. [@m5o](https://github.com/m5o)\n* Add Rails 5.2 support. [@gobijan](https://github.com/gobijan)\n* Add API to register custom components.[@feliperenan](https://github.com/feliperenan)\n* Allow custom errors classes to inputs.[@feliperenan](https://github.com/feliperenan)\n* Remove support from Rails 4.0, 4.1 and 4.2. [@feliperenan](https://github.com/feliperenan)\n* Add support for citext, hstore, json & jsonb column types. [@swrobel](https://github.com/swrobel)\n* Add :valid_class on input wrapper when value is present and valid [@aeberlin](https://github.com/aeberlin), [@m5o](https://github.com/m5o)\n* Allow :valid_class to inputs when value is present and valid. [@m5o](https://github.com/m5o)\n* Allow validation classes on input_field. [@feliperenan](https://github.com/feliperenan)\n* Add basic ActiveStorage support. [@murb](https://github.com/murb)\n\n### Bug fix\n* Fix horizontal form label position, from right to text-right. [@cavpollo](https://github.com/cavpollo)\n* Add base error display alongside existing errors. [@bluefalcon26](https://github.com/bluefalcon26)\n* Silent deprecation warning for placeholder_text. [@moofkit](https://github.com/moofkit)\n* Use custom i18n scope for label required html. [@tvdeyen](https://github.com/tvdeyen)\n\n## 3.5.1\n\n### Enhancements\n* Exclude hidden field when unchecked_value: false. [@fschwahn](https://github.com/fschwahn)\n* Add frozen_string_literal magic comment to several files. [@oniofchaos](https://github.com/oniofchaos)\n* Try convert @object to model in case we got decorated object [@timurvafin](https://github.com/timurvafin)\n- From now, if you are using some object that inherits from `SimpleDelegator`, you must implement\n  `def to_model; self; end`. Otherwise, *Simple Form* will convert the decorated object to the model\n  since `SimpleDelegator` will delegate it to the model.\n* Code cleanup [@Fornacula](https://github.com/Fornacula)\n\n### Bug fix\n* Fix error when the scope from association has parameter. [@feliperenan](https://github.com/feliperenan)\n* Only call `where` on associations when they respond to it. [@anicholson](https://github.com/anicholson)\n* require 'action_pack' before using it. [@etagwerker](https://github.com/etagwerker)\n* Check if Rails.env is defined. [@etagwerker](https://github.com/etagwerker)\n* Fix minlength. [@mameier](https://github.com/mameier)\n* Make errors_on_attribute return [] when not present. [@redrick](https://github.com/redrick)\n* Fix boolean inputs in nested style for label non-string. [@feliperenan](https://github.com/feliperenan)\n\n## 3.5.0\n\n* Updated gem dependency to support Rails 5.1.x.\n\n## 3.4.0\n\n* Removed Ruby 2.4.0 `Integer` unification deprecation warning.\n* Removed EOL Ruby 1.9.3 from the build matrix.\n* Added `minlength` component.\n* `boolean_label_class` can be set on a per-input basis.\n\n## 3.3.1\n\n### Bug fix\n\n* Fix support for symbols when looking up types with `ActiveModel::Type`.\n\n## 3.3.0\n\n### enhancements\n  * Add the `aria-invalid` attribute on inputs with errors.\n  * Added support for the new `ActiveModel::Type` API over Active Record's\n    column objects.\n\n### bug fix\n  * Fix `merge_wrapper_options` to correctly merge options with duplicated keys. [@herminiotorres](https://github.com/herminiotorres)\n  Closes [#1278](https://github.com/heartcombo/simple_form/issues/1278).\n\n## 3.2.1\n\n### enhancements\n  * Updated gem dependency to support Rails 5.0.x.\n\n## 3.2.0\n\n### bug fix\n  * Improve performance of input generation by disabling support for `_html` translations. This reverts the feature introduced on the 3.1.0 branch\n\n## 3.1.1\n\n### enhancements\n  * Add the `disabled_class` to the label when the input is disabled. [@rhodrid](https://github.com/rhodrid)\n\n### bug fix\n  * Make it possible to override `required` value that was previously set in the wrapper. [@nashby](https://github.com/nashby)\n\n  * `date/time/datetime` inputs now correctly generate the label `for` attribute when\n  HTML5 compatibility is explicitly enabled. [@ericsullivan](https://github.com/ericsullivan)\n\n  * The datetime, date, and time inputs now have a nice format by default on bootstrap.\n  [@ulissesalmeida](https://github.com/ulissesalmeida) [@eltonchrls](https://github.com/eltonchrls)\n\n  * Now it is possible to set custom input mappings for collections.\n\n  Example:\n\n  ```ruby\n    # On configuration:\n    config.input_mappings = { /gender$/ => :check_boxes }\n\n    # On form:\n    f.input :gender, collection: [:male, :female]\n  ```\n  [strangeworks](https://github.com/strangeworks)\n\n## 3.1.0\n\n### enhancements\n  * Update foundation generator to version 5. [@jorge-d](https://github.com/jorge-d)\n  * Add mapping to `uuid` columns.\n  * Add custom namespaces for custom inputs feature. [@vala](https://github.com/vala)\n  * Add `:unless_blank` option to the wrapper API. [@IanVaughan](https://github.com/IanVaughan)\n  * Add support to html markup in the I18n options. [@laurocaetano](https://github.com/laurocaetano)\n  * Add the `full_error` component. [@laurocaetano](https://github.com/laurocaetano)\n  * Add support to `scope` to be used on associations. [@laurocaetano](https://github.com/laurocaetano)\n  * Execute the association `condition` in the object context. [@laurocaetano](https://github.com/laurocaetano)\n  * Check if the given association responds to `order` before calling it. [@laurocaetano](https://github.com/laurocaetano)\n  * Add Bootstrap 3 initializer template.\n  * For radio or checkbox collection always use `:item_wrapper_tag` to wrap the content and add `label` when using `boolean_style` with `:nested` [@kassio](https://github.com/kassio) and [@erichkist](https://github.com/erichkist)\n  * `input_field` uses the same wrapper as input but only with attribute components. [@nashby](https://github.com/nashby)\n  * Add wrapper mapping per form basis [@rcillo](https://github.com/rcillo) and [@bernardoamc](https://github.com/bernardoamc)\n  * Add `for` attribute to `label` when collections are rendered as radio or checkbox [@erichkist](https://github.com/erichkist), [@ulissesalmeida](https://github.com/ulissesalmeida) and [@fabioyamate](https://github.com/fabioyamate)\n  * Add `include_default_input_wrapper_class` config [@luizcosta](https://github.com/luizcosta)\n  * Map `datetime`, `date` and `time` input types to their respective HTML5 input tags\n  when the `:html5` is set to `true` [@volmer](https://github.com/volmer)\n  * Add `boolean_label_class` config.\n  * Add `:html` option to include additional attributes on custom wrappers [@remofritzsche](https://github.com/remofritzsche) and [@ulissesalmeida](https://github.com/ulissesalmeida)\n  * Make possible to use the Wrappers API to define attributes for the components.\n  See https://github.com/heartcombo/simple_form/pull/997 for more information.\n  * Put a whitespace before the `inline_label` options of boolean input if it is present.\n  * Add support to configure the `label_text` proc at the wrapper level. [@NOX73](https://github.com/NOX73)\n  * `label_text` proc now receive three arguments (label, request, and if the label was explicit). [@timscott](https://github.com/timscott)\n  * Add I18n support to `:include_blank` and `:prompt` when `:translate` is used as value. [@haines](https://github.com/heartcombo/simple_form/pull/616)\n  * Add support to define custom error messages for the attributes.\n  * Add support to change the I18n scope to be used in Simple Form. [@nielsbuus](https://github.com/nielsbuus)\n  * The default form class can now be overridden with `html: { :class }`. [@rmm5t](https://github.com/rmm5t)\n\n### bug fix\n  * Fix `full_error` when the attribute is an association. [@mvdamme](https://github.com/jorge-d)\n  * Fix support to `:namespace` and `:index` options for nested check boxes and radio buttons when the attribute is an association.\n  * Collection input that uses automatic collection translation properly sets checked values.\n  Closes [#971](https://github.com/heartcombo/simple_form/issues/971) [@nashby](https://github.com/nashby)\n  * Collection input generates `required` attribute if it has `prompt` option. [@nashby](https://github.com/nashby)\n  * Grouped collection uses the first non-empty object to detect label and value methods.\n\n## deprecation\n  * Methods on custom inputs now accept a required argument with the wrapper options.\n  See https://github.com/heartcombo/simple_form/pull/997 for more information.\n  * SimpleForm.form_class is deprecated in favor of SimpleForm.default_form_class.\n  Future versions of Simple Form will not generate `simple_form` class for the form\n  element.\n  See https://github.com/heartcombo/simple_form/pull/1109 for more information.\n\nPlease check [v3.0](https://github.com/heartcombo/simple_form/blob/v3.0/CHANGELOG.md) for previous changes.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## Contributing\n\n1. If you have any questions about Simple Form, search the\n[Wiki](https://github.com/heartcombo/simple_form/wiki)\nor [Stack Overflow](http://stackoverflow.com/questions/tagged/simple_form).\nDo not post questions here.\n\n2. If you find a security bug, **DO NOT** submit an issue here.\nPlease send an e-mail to [heartcombo@googlegroups.com](mailto:heartcombo@googlegroups.com)\ninstead.\n\n3. Do a small search on the issues tracker before submitting your issue to\nsee if it was already reported or fixed. In case it was not, create your report\nincluding Rails and Simple Form versions. If you are getting exceptions, please\ninclude the full backtrace.\n\nThat's it! The more information you give, the more easy it becomes for us to\ntrack it down and fix it. Ideal scenario would be adding the issue to Simple Form\ntest suite or to a sample application.\n\nThanks!\n"
  },
  {
    "path": "Gemfile",
    "content": "source \"https://rubygems.org\"\n\ngemspec\n\ngem \"activemodel\", \"~> 8.1.0\"\ngem \"actionpack\", \"~> 8.1.0\"\ngem \"railties\", \"~> 8.1.0\"\n"
  },
  {
    "path": "ISSUE_TEMPLATE.md",
    "content": "## Precheck\n\n- Do not use the issues tracker for help or support, try Stack Overflow.\n- For bugs, do a quick search and make sure the bug has not yet been reported\n- If you found a security bug, do not report it through GitHub. Please send an e-mail to heartcombo@googlegroups.com instead.\n- Finally, be nice and have fun!\n\n## Environment\n\n- Ruby **[version]**\n- Rails **[version]**\n- Simple Form **[version]**\n\n## Current behavior\n\nInclude code samples, errors, steps to reproduce the error and stacktraces if appropriate.\n\nWill be even more helpful if you provide a sample application or a test case that reproduces the error.\n\n## Expected behavior\n"
  },
  {
    "path": "MIT-LICENSE",
    "content": "Copyright (c) 2020-CURRENT Rafael França, Carlos Antonio da Silva\nCopyright (c) 2009-2019 Plataformatec\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "![Simple Form Logo](https://raw.github.com/heartcombo/simple_form/main/simple_form.png)\n\n[![Gem Version](https://badge.fury.io/rb/simple_form.svg)](https://badge.fury.io/rb/simple_form)\n\nRails forms made easy.\n\n**Simple Form** aims to be as flexible as possible while helping you with powerful components to create\nyour forms. The basic goal of **Simple Form** is to not touch your way of defining the layout, letting\nyou find the better design for your eyes. Most of the DSL was inherited from Formtastic,\nwhich we are thankful for and should make you feel right at home.\n\nINFO: This README refers to **Simple Form** 5.0. For older releases, check the related branch for your version.\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n## Table of Contents\n\n- [Installation](#installation)\n  - [Bootstrap](#bootstrap-5)\n  - [Zurb Foundation 5](#zurb-foundation-5)\n  - [Country Select](#country-select)\n- [Usage](#usage)\n  - [Stripping away all wrapper divs](#stripping-away-all-wrapper-divs)\n  - [Collections](#collections)\n  - [Priority](#priority)\n  - [Associations](#associations)\n  - [Buttons](#buttons)\n  - [Wrapping Rails Form Helpers](#wrapping-rails-form-helpers)\n  - [Extra helpers](#extra-helpers)\n    - [Simple Fields For](#simple-fields-for)\n    - [Collection Radio Buttons](#collection-radio-buttons)\n    - [Collection Check Boxes](#collection-check-boxes)\n- [Available input types and defaults for each column type](#available-input-types-and-defaults-for-each-column-type)\n- [Custom inputs](#custom-inputs)\n- [Custom form builder](#custom-form-builder)\n- [I18n](#i18n)\n- [Configuration](#configuration)\n  - [The wrappers API](#the-wrappers-api)\n- [Custom Components](#custom-components)\n- [HTML 5 Notice](#html-5-notice)\n  - [Using non Active Record objects](#using-non-active-record-objects)\n- [Information](#information)\n  - [RDocs](#rdocs)\n  - [Supported Ruby / Rails versions](#supported-ruby--rails-versions)\n  - [Bug reports](#bug-reports)\n- [Maintainers](#maintainers)\n- [License](#license)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## Installation\n\nAdd it to your Gemfile:\n\n```ruby\ngem 'simple_form'\n```\n\nRun the following command to install it:\n\n```console\nbundle install\n```\n\nRun the generator:\n\n```console\nrails generate simple_form:install\n```\n\n### Bootstrap 5\n\n**Simple Form** can be easily integrated with [Bootstrap 5](https://getbootstrap.com/).\nUse the `bootstrap` option in the install generator, like this:\n\n```console\nrails generate simple_form:install --bootstrap\n```\n\nThis will add an initializer that configures **Simple Form** wrappers for\nBootstrap 5's [form controls](https://getbootstrap.com/docs/5.0/forms/overview/).\nYou have to be sure that you added a copy of the [Bootstrap](https://getbootstrap.com/)\nassets on your application.\n\nFor more information see the generator output, our\n[example application code](https://github.com/heartcombo/simple_form-bootstrap).\n\n### Zurb Foundation 5\n\nTo generate wrappers that are compatible with [Zurb Foundation 5](https://get.foundation/sites/docs-v5/), pass\nthe `foundation` option to the generator, like this:\n\n```console\nrails generate simple_form:install --foundation\n```\n\nPlease note that the Foundation wrapper does not support the `:hint` option by default. In order to\nenable hints, please uncomment the appropriate line in `config/initializers/simple_form_foundation.rb`.\nYou will need to provide your own CSS styles for hints.\n\nPlease see the [instructions on how to install Foundation in a Rails app](https://get.foundation/sites/docs-v5/applications.html).\n\n### Country Select\n\nIf you want to use the country select, you will need the\n[country_select gem](https://rubygems.org/gems/country_select), add it to your Gemfile:\n\n```ruby\ngem 'country_select'\n```\n\nIf you don't want to use the gem you can easily override this behaviour by mapping the\ncountry inputs to something else, with a line like this in your `simple_form.rb` initializer:\n\n```ruby\nconfig.input_mappings = { /country/ => :string }\n```\n\n## Usage\n\n**Simple Form** was designed to be customized as you need to. Basically it's a stack of components that\nare invoked to create a complete html input for you, which by default contains label, hints, errors\nand the input itself. It does not aim to create a lot of different logic from the default Rails\nform helpers, as they do a great job by themselves. Instead, **Simple Form** acts as a DSL and just\nmaps your input type (retrieved from the column definition in the database) to a specific helper method.\n\nTo start using **Simple Form** you just have to use the helper it provides:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username %>\n  <%= f.input :password %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nThis will generate an entire form with labels for user name and password as well, and render errors\nby default when you render the form with invalid data (after submitting for example).\n\nYou can overwrite the default label by passing it to the input method. You can also add a hint,\nan error, or even a placeholder. For boolean inputs, you can add an inline label as well:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username, label: 'Your username please', error: 'Username is mandatory, please specify one' %>\n  <%= f.input :password, hint: 'No special characters.' %>\n  <%= f.input :email, placeholder: 'user@domain.com' %>\n  <%= f.input :remember_me, inline_label: 'Yes, remember me' %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nIn some cases you may want to disable labels, hints or errors. Or you may want to configure the html\nof any of them:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username, label_html: { class: 'my_class' }, hint_html: { class: 'hint_class' } %>\n  <%= f.input :password, hint: false, error_html: { id: 'password_error' } %>\n  <%= f.input :password_confirmation, label: false %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nIt is also possible to pass any html attribute straight to the input, by using the `:input_html`\noption, for instance:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username, input_html: { class: 'special' } %>\n  <%= f.input :password, input_html: { maxlength: 20 } %>\n  <%= f.input :remember_me, input_html: { value: '1' } %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nIf you want to pass the same options to all inputs in the form (for example, a default class),\nyou can use the `:defaults` option in `simple_form_for`. Specific options in `input` call will\noverwrite the defaults:\n\n```erb\n<%= simple_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f| %>\n  <%= f.input :username, input_html: { class: 'special' } %>\n  <%= f.input :password, input_html: { maxlength: 20 } %>\n  <%= f.input :remember_me, input_html: { value: '1' } %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nSince **Simple Form** generates a wrapper div around your label and input by default, you can pass\nany html attribute to that wrapper as well using the `:wrapper_html` option, like so:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username, wrapper_html: { class: 'username' } %>\n  <%= f.input :password, wrapper_html: { id: 'password' } %>\n  <%= f.input :remember_me, wrapper_html: { class: 'options' } %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nRequired fields are marked with an * prepended to their labels.\n\nBy default all inputs are required. When the form object includes `ActiveModel::Validations`\n(which, for example, happens with Active Record models), fields are required only when there is `presence` validation.\nOtherwise, **Simple Form** will mark fields as optional. For performance reasons, this\ndetection is skipped on validations that make use of conditional options, such as `:if` and `:unless`.\n\nAnd of course, the `required` property of any input can be overwritten as needed:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :name, required: false %>\n  <%= f.input :username %>\n  <%= f.input :password %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nBy default, **Simple Form** will look at the column type in the database and use an\nappropriate input for the column. For example, a column created with type\n`:text` in the database will use a `textarea` input by default. See the section\n[Available input types and defaults for each column\ntype](https://github.com/heartcombo/simple_form#available-input-types-and-defaults-for-each-column-type)\nfor a complete list of defaults.\n\n**Simple Form** also lets you overwrite the default input type it creates:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username %>\n  <%= f.input :password %>\n  <%= f.input :description, as: :text %>\n  <%= f.input :accepts,     as: :radio_buttons %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nSo instead of a checkbox for the *accepts* attribute, you'll have a pair of radio buttons with yes/no\nlabels and a textarea instead of a text field for the description. You can also render boolean\nattributes using `as: :select` to show a dropdown.\n\nIt is also possible to give the `:disabled` option to **Simple Form**, and it'll automatically mark\nthe wrapper as disabled with a CSS class, so you can style labels, hints and other components inside\nthe wrapper as well:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :username, disabled: true, hint: 'You cannot change your username.' %>\n  <%= f.button :submit %>\n<% end %>\n```\n\n**Simple Form** inputs accept the same options as their corresponding input type helper in Rails:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :date_of_birth, as: :date, start_year: Date.today.year - 90,\n                              end_year: Date.today.year - 12, discard_day: true,\n                              order: [:month, :year] %>\n  <%= f.input :accepts, as: :boolean, checked_value: 'positive', unchecked_value: 'negative' %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nBy default, **Simple Form** generates a hidden field to handle the un-checked case for boolean fields.\nPassing `unchecked_value: false` in the options for boolean fields will cause this hidden field to be omitted,\nfollowing the convention in Rails. You can also specify `include_hidden: false` to skip the hidden field:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :just_the_checked_case, as: :boolean, include_hidden: false %>\n  <%= f.button :submit %>\n<% end %>\n```\n\n**Simple Form** also allows you to use label, hint, input_field, error and full_error helpers\n(please take a look at the rdocs for each method for more info):\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.label :username %>\n  <%= f.input_field :username %>\n  <%= f.hint 'No special characters, please!' %>\n  <%= f.error :username, id: 'user_name_error' %>\n  <%= f.full_error :token %>\n  <%= f.submit 'Save' %>\n<% end %>\n```\n\nAny extra option passed to these methods will be rendered as html option.\n\n### Stripping away all wrapper divs\n\n**Simple Form** also allows you to strip away all the div wrappers around the `<input>` field that is\ngenerated with the usual `f.input`.\nThe easiest way to achieve this is to use `f.input_field`.\n\nExample:\n\n```ruby\nsimple_form_for @user do |f|\n  f.input_field :name\n  f.input_field :remember_me, as: :boolean\nend\n```\n\n```html\n<form>\n  ...\n  <input class=\"string required\" id=\"user_name\" maxlength=\"255\" name=\"user[name]\" size=\"255\" type=\"text\">\n  <input name=\"user[remember_me]\" type=\"hidden\" value=\"0\">\n  <label class=\"checkbox\">\n    <input class=\"boolean optional\" id=\"user_published\" name=\"user[remember_me]\" type=\"checkbox\" value=\"1\">\n  </label>\n</form>\n```\n\nFor check boxes and radio buttons you can remove the label changing `boolean_style` from default value `:nested` to `:inline`.\n\nExample:\n\n```ruby\nsimple_form_for @user do |f|\n  f.input_field :name\n  f.input_field :remember_me, as: :boolean, boolean_style: :inline\nend\n```\n\n```html\n<form>\n  ...\n  <input class=\"string required\" id=\"user_name\" maxlength=\"255\" name=\"user[name]\" size=\"255\" type=\"text\">\n  <input name=\"user[remember_me]\" type=\"hidden\" value=\"0\">\n  <input class=\"boolean optional\" id=\"user_remember_me\" name=\"user[remember_me]\" type=\"checkbox\" value=\"1\">\n</form>\n```\n\nTo view the actual RDocs for this, check them out here - https://rubydoc.info/github/heartcombo/simple_form/main/SimpleForm/FormBuilder:input_field\n\n### Collections\n\nAnd what if you want to create a select containing the age from 18 to 60 in your form? You can do it\noverriding the `:collection` option:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :user %>\n  <%= f.input :age, collection: 18..60 %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nCollections can be arrays or ranges, and when a `:collection` is given the `:select` input will be\nrendered by default, so we don't need to pass the `as: :select` option. Other types of collection\nare `:radio_buttons` and `:check_boxes`. Those are added by **Simple Form** to Rails set of form\nhelpers (read Extra Helpers section below for more information).\n\nCollection inputs accept two other options beside collections:\n\n* *label_method* => the label method to be applied to the collection to retrieve the label (use this\n  instead of the `text_method` option in `collection_select`)\n\n* *value_method* => the value method to be applied to the collection to retrieve the value\n\nThose methods are useful to manipulate the given collection. Both of these options also accept\nlambda/procs in case you want to calculate the value or label in a special way eg. custom\ntranslation. You can also define a `to_label` method on your model as **Simple Form** will search for\nand use `:to_label` as a `:label_method` first if it is found.\n\nBy default, **Simple Form** will use the first item from an array as the label and the second one as the value.\nIf you want to change this behavior you must make it explicit, like this:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :gender, as: :radio_buttons, collection: [['0', 'female'], ['1', 'male']], label_method: :second, value_method: :first %>\n<% end %>\n```\n\nAll other options given are sent straight to the underlying Rails helper(s): [`collection_select`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_select), [`collection_check_boxes`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_check_boxes), [`collection_radio_buttons`](https://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-collection_radio_buttons). For example, you can pass `prompt` and `selected` as:\n\n```ruby\nf.input :age, collection: 18..60, prompt: \"Select your age\", selected: 21\n```\n\nIt may also be useful to explicitly pass a value to the optional `:selected` like above, especially if passing a collection of nested objects.\n\nIt is also possible to create grouped collection selects, that will use the html *optgroup* tags, like this:\n\n```ruby\nf.input :country_id, collection: @continents, as: :grouped_select, group_method: :countries\n```\n\nGrouped collection inputs accept the same `:label_method` and `:value_method` options, which will be\nused to retrieve label/value attributes for the `option` tags. Besides that, you can give:\n\n* *group_method* => the method to be called on the given collection to generate the options for\n  each group (required)\n\n* *group_label_method* => the label method to be applied on the given collection to retrieve the label\n  for the _optgroup_ (**Simple Form** will attempt to guess the best one the same way it does with\n  `:label_method`)\n\n### Priority\n\n**Simple Form** also supports `:time_zone` and `:country`. When using such helpers, you can give\n`:priority` as an option to select which time zones and/or countries should be given higher priority:\n\n```ruby\nf.input :residence_country, priority: [ \"Brazil\" ]\nf.input :time_zone, priority: /US/\n```\n\nThose values can also be configured with a default value to be used on the site through the\n`SimpleForm.country_priority` and `SimpleForm.time_zone_priority` helpers.\n\nNote: While using `country_select` if you want to restrict to only a subset of countries for a specific\ndrop down then you may use the `:collection` option:\n\n```ruby\nf.input :shipping_country, priority: [ \"Brazil\" ], collection: [ \"Australia\", \"Brazil\", \"New Zealand\"]\n```\n\n### Associations\n\nTo deal with associations, **Simple Form** can generate select inputs, a series of radios buttons or checkboxes.\nLets see how it works: imagine you have a user model that belongs to a company and `has_and_belongs_to_many`\nroles. The structure would be something like:\n\n```ruby\nclass User < ActiveRecord::Base\n  belongs_to :company\n  has_and_belongs_to_many :roles\nend\n\nclass Company < ActiveRecord::Base\n  has_many :users\nend\n\nclass Role < ActiveRecord::Base\n  has_and_belongs_to_many :users\nend\n```\n\nNow we have the user form:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :name %>\n  <%= f.association :company %>\n  <%= f.association :roles %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nSimple enough, right? This is going to render a `:select` input for choosing the `:company`, and another\n`:select` input with `:multiple` option for the `:roles`. You can, of course, change it to use radio\nbuttons and checkboxes as well:\n\n```ruby\nf.association :company, as: :radio_buttons\nf.association :roles,   as: :check_boxes\n```\n\nThe association helper just invokes `input` under the hood, so all options available to `:select`,\n`:radio_buttons` and `:check_boxes` are also available to association. Additionally, you can specify\nthe collection by hand, all together with the prompt:\n\n```ruby\nf.association :company, collection: Company.active.order(:name), prompt: \"Choose a Company\"\n```\n\nIn case you want to declare different labels and values:\n\n```ruby\nf.association :company, label_method: :company_name, value_method: :id, include_blank: false\n```\n\nPlease note that the association helper is currently only tested with Active Record. It currently\ndoes not work well with Mongoid and depending on the ORM you're using your mileage may vary.\n\n### Buttons\n\nAll web forms need buttons, right? **Simple Form** wraps them in the DSL, acting like a proxy:\n\n```erb\n<%= simple_form_for @user do |f| %>\n  <%= f.input :name %>\n  <%= f.button :submit %>\n<% end %>\n```\n\nThe above will simply call submit. You choose to use it or not, it's just a question of taste.\n\nThe button method also accepts optional parameters, that are delegated to the underlying submit call:\n\n```erb\n<%= f.button :submit, \"Custom Button Text\", class: \"my-button\" %>\n```\n\nTo create a `<button>` element, use the following syntax:\n\n```erb\n<%= f.button :button, \"Custom Button Text\" %>\n\n<%= f.button :button do %>\n  Custom Button Text\n<% end %>\n```\n\n### Wrapping Rails Form Helpers\n\nSay you wanted to use a rails form helper but still wrap it in **Simple Form** goodness? You can, by\ncalling input with a block like so:\n\n```erb\n<%= f.input :role do %>\n  <%= f.select :role, Role.all.map { |r| [r.name, r.id, { class: r.company.id }] }, include_blank: true %>\n<% end %>\n```\n\nIn the above example, we're taking advantage of Rails 3's select method that allows us to pass in a\nhash of additional attributes for each option.\n\n### Extra helpers\n\n**Simple Form** also comes with some extra helpers you can use inside rails default forms without relying\non `simple_form_for` helper. They are listed below.\n\n#### Simple Fields For\n\nWrapper to use **Simple Form** inside a default rails form. It works in the same way that the `fields_for`\nRails helper, but change the builder to use the `SimpleForm::FormBuilder`.\n\n```ruby\nform_for @user do |f|\n  f.simple_fields_for :posts do |posts_form|\n    # Here you have all simple_form methods available\n    posts_form.input :title\n  end\nend\n```\n\n#### Collection Radio Buttons\n\nCreates a collection of radio inputs with labels associated (same API as `collection_select`):\n\n```ruby\nform_for @user do |f|\n  f.collection_radio_buttons :options, [[true, 'Yes'], [false, 'No']], :first, :last\nend\n```\n\n```html\n<input id=\"user_options_true\" name=\"user[options]\" type=\"radio\" value=\"true\" />\n<label class=\"collection_radio_buttons\" for=\"user_options_true\">Yes</label>\n<input id=\"user_options_false\" name=\"user[options]\" type=\"radio\" value=\"false\" />\n<label class=\"collection_radio_buttons\" for=\"user_options_false\">No</label>\n```\n\n#### Collection Check Boxes\n\nCreates a collection of checkboxes with labels associated (same API as `collection_select`):\n\n```ruby\nform_for @user do |f|\n  f.collection_check_boxes :options, [[true, 'Yes'], [false, 'No']], :first, :last\nend\n```\n\n```html\n<input name=\"user[options][]\" type=\"hidden\" value=\"\" />\n<input id=\"user_options_true\" name=\"user[options][]\" type=\"checkbox\" value=\"true\" />\n<label class=\"collection_check_box\" for=\"user_options_true\">Yes</label>\n<input name=\"user[options][]\" type=\"hidden\" value=\"\" />\n<input id=\"user_options_false\" name=\"user[options][]\" type=\"checkbox\" value=\"false\" />\n<label class=\"collection_check_box\" for=\"user_options_false\">No</label>\n```\n\nTo use this with associations in your model, you can do the following:\n\n```ruby\nform_for @user do |f|\n  f.collection_check_boxes :role_ids, Role.all, :id, :name # using :roles here is not going to work.\nend\n```\n\nTo add a CSS class to the label item, you can use the `item_label_class` option:\n\n```ruby\nf.collection_check_boxes :role_ids, Role.all, :id, :name, item_label_class: 'my-custom-class'\n```\n\n## Available input types and defaults for each column type\n\nThe following table shows the html element you will get for each attribute\naccording to its database definition. These defaults can be changed by\nspecifying the helper method in the column `Mapping` as the `as:` option.\n\nMapping         | Generated HTML Element               | Database Column Type\n--------------- |--------------------------------------|---------------------\n`boolean`       | `input[type=checkbox]`               | `boolean`\n`string`        | `input[type=text]`                   | `string`\n`citext`        | `input[type=text]`                   | `citext`\n`email`         | `input[type=email]`                  | `string` with `name =~ /email/`\n`url`           | `input[type=url]`                    | `string` with `name =~ /url/`\n`tel`           | `input[type=tel]`                    | `string` with `name =~ /phone/`\n`password`      | `input[type=password]`               | `string` with `name =~ /password/`\n`search`        | `input[type=search]`                 | -\n`uuid`          | `input[type=text]`                   | `uuid`\n`color`         | `input[type=color]`                  | `string`\n`text`          | `textarea`                           | `text`\n`hstore`        | `textarea`                           | `hstore`\n`json`          | `textarea`                           | `json`\n`jsonb`         | `textarea`                           | `jsonb`\n`file`          | `input[type=file]`                   | `string` responding to file methods\n`hidden`        | `input[type=hidden]`                 | -\n`integer`       | `input[type=number]`                 | `integer`\n`float`         | `input[type=number]`                 | `float`\n`decimal`       | `input[type=number]`                 | `decimal`\n`range`         | `input[type=range]`                  | -\n`datetime`      | `datetime select`                    | `datetime/timestamp`\n`date`          | `date select`                        | `date`\n`time`          | `time select`                        | `time`\n`weekday`       | `select` (weekdays as options)       | -\n`select`        | `select`                             | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations\n`radio_buttons` | collection of `input[type=radio]`    | `belongs_to` associations\n`check_boxes`   | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations\n`country`       | `select` (countries as options)      | `string` with `name =~ /country/`\n`time_zone`     | `select` (timezones as options)      | `string` with `name =~ /time_zone/`\n`rich_text_area`| `trix-editor`                        | -\n\n## Custom inputs\n\nIt is very easy to add custom inputs to **Simple Form**. For instance, if you want to add a custom input\nthat extends the string one, you just need to add this file:\n\n```ruby\n# app/inputs/currency_input.rb\nclass CurrencyInput < SimpleForm::Inputs::Base\n  def input(wrapper_options)\n    merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n    \"$ #{@builder.text_field(attribute_name, merged_input_options)}\".html_safe\n  end\nend\n```\n\nAnd use it in your views:\n\n```ruby\nf.input :money, as: :currency\n```\nNote, you may have to create the `app/inputs/` directory and restart your webserver.\n\nYou can also redefine existing **Simple Form** inputs by creating a new class with the same name. For\ninstance, if you want to wrap date/time/datetime in a div, you can do:\n\n```ruby\n# app/inputs/date_time_input.rb\nclass DateTimeInput < SimpleForm::Inputs::DateTimeInput\n  def input(wrapper_options)\n    template.content_tag(:div, super)\n  end\nend\n```\n\nOr if you want to add a class to all the select fields you can do:\n\n```ruby\n# app/inputs/collection_select_input.rb\nclass CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput\n  def input_html_classes\n    super.push('chosen')\n  end\nend\n```\n\nIf needed, you can namespace your custom inputs in a module and tell **Simple Form** to look for\ntheir definitions in this module. This can avoid conflicts with other form libraries (like Formtastic) that look up\nthe global context to find inputs definition too.\n\n```ruby\n# app/inputs/custom_inputs/numeric_input\nmodule CustomInputs\n  class NumericInput < SimpleForm::Inputs::NumericInput\n    def input_html_classes\n      super.push('no-spinner')\n    end\n  end\nend\n```\n\nAnd in the **SimpleForm** initializer :\n\n```ruby\n# config/simple_form.rb\nconfig.custom_inputs_namespaces << \"CustomInputs\"\n```\n\n## Custom form builder\n\nYou can create a custom form builder that uses **Simple Form**.\n\nCreate a helper method that calls `simple_form_for` with a custom builder:\n\n```ruby\ndef custom_form_for(object, *args, &block)\n  options = args.extract_options!\n  simple_form_for(object, *(args << options.merge(builder: CustomFormBuilder)), &block)\nend\n```\n\nCreate a form builder class that inherits from `SimpleForm::FormBuilder`.\n\n```ruby\nclass CustomFormBuilder < SimpleForm::FormBuilder\n  def input(attribute_name, options = {}, &block)\n    super(attribute_name, options.merge(label: false), &block)\n  end\nend\n```\n\n## I18n\n\n**Simple Form** uses all power of I18n API to lookup labels, hints, prompts and placeholders. To customize your\nforms you can create a locale file like this:\n\n```yaml\nen:\n  simple_form:\n    labels:\n      user:\n        username: 'User name'\n        password: 'Password'\n    hints:\n      user:\n        username: 'User name to sign in.'\n        password: 'No special characters, please.'\n    placeholders:\n      user:\n        username: 'Your username'\n        password: '****'\n    include_blanks:\n      user:\n        age: 'Rather not say'\n    prompts:\n      user:\n        role: 'Select your role'\n```\n\nAnd your forms will use this information to render the components for you.\n\n**Simple Form** also lets you be more specific, separating lookups through actions.\nLet's say you want a different label for new and edit actions, the locale file would\nbe something like:\n\n```yaml\nen:\n  simple_form:\n    labels:\n      user:\n        username: 'User name'\n        password: 'Password'\n        edit:\n          username: 'Change user name'\n          password: 'Change password'\n```\n\nThis way **Simple Form** will figure out the right translation for you, based on the action being\nrendered. And to be a little bit DRYer with your locale file, you can specify defaults for all\nmodels under the 'defaults' key:\n\n```yaml\nen:\n  simple_form:\n    labels:\n      defaults:\n        username: 'User name'\n        password: 'Password'\n        new:\n          username: 'Choose a user name'\n    hints:\n      defaults:\n        username: 'User name to sign in.'\n        password: 'No special characters, please.'\n    placeholders:\n      defaults:\n        username: 'Your username'\n        password: '****'\n```\n\n**Simple Form** will always look for a default attribute translation under the \"defaults\" key if no\nspecific is found inside the model key.\n\nIn addition, **Simple Form** will fallback to default `human_attribute_name` from Rails when no other\ntranslation is found for labels. Finally, you can also overwrite any label, hint or placeholder\ninside your view, just by passing the option manually. This way the I18n lookup will be skipped.\n\nFor `:prompt` and `:include_blank` the I18n lookup is optional and to enable it is necessary to pass\n`:translate` as value.\n\n```ruby\nf.input :role, prompt: :translate\n```\n\n**Simple Form** also has support for translating options in collection helpers. For instance, given a\nUser with a `:role` attribute, you might want to create a select box showing translated labels\nthat would post either `:admin` or `:editor` as value. With **Simple Form** you could create an input\nlike this:\n\n```ruby\nf.input :role, collection: [:admin, :editor]\n```\n\nAnd **Simple Form** will try a lookup like this in your locale file, to find the right labels to show:\n\n```yaml\nen:\n  simple_form:\n    options:\n      user:\n        role:\n          admin: 'Administrator'\n          editor: 'Editor'\n```\n\nYou can also use the `defaults` key as you would do with labels, hints and placeholders. It is\nimportant to notice that **Simple Form** will only do the lookup for options if you give a collection\ncomposed of symbols only. This is to avoid constant lookups to I18n.\n\nIt's also possible to translate buttons, using Rails' built-in I18n support:\n\n```yaml\nen:\n  helpers:\n    submit:\n      user:\n        create: \"Add %{model}\"\n        update: \"Save Changes\"\n```\n\nThere are other options that can be configured through I18n API, such as required text and boolean.\nBe sure to check our locale file or the one copied to your application after you run\n`rails generate simple_form:install`.\n\nIt should be noted that translations for labels, hints and placeholders for a namespaced model, e.g.\n`Admin::User`, should be placed under `admin_user`, not under `admin/user`. This is different from\nhow translations for namespaced model and attribute names are defined:\n\n```yaml\nen:\n  activerecord:\n    models:\n        admin/user: User\n    attributes:\n        admin/user:\n            name: Name\n```\n\nThey should be placed under `admin/user`. Form labels, hints and placeholders for those attributes,\nthough, should be placed under `admin_user`:\n\n```yaml\nen:\n  simple_form:\n    labels:\n        admin_user:\n            name: Name\n```\n\nThis difference exists because **Simple Form** relies on `object_name` provided by Rails'\nFormBuilder to determine the translation path for a given object instead of `i18n_key` from the\nobject itself. Thus, similarly, if a form for an `Admin::User` object is defined by calling\n`simple_form_for @admin_user, as: :some_user`, **Simple Form** will look for translations\nunder `some_user` instead of `admin_user`.\n\nWhen translating `simple_fields_for` attributes be sure to use the same name you pass to it, e.g. `simple_fields_for :posts` should be placed under `posts` not `post`:\n\n```yaml\nen:\n  simple_form:\n    labels:\n      posts:\n        title: 'Post title'\n    hints:\n      posts:\n        title: 'A good title'\n    placeholders:\n      posts:\n        title: 'Once upon a time...'\n```\n\n## Configuration\n\n**Simple Form** has several configuration options. You can read and change them in the initializer\ncreated by **Simple Form**, so if you haven't executed the command below yet, please do:\n\n`rails generate simple_form:install`\n\n### The wrappers API\n\nWith **Simple Form** you can configure how your components will be rendered using the wrappers API.\nThe syntax looks like this:\n\n```ruby\nconfig.wrappers tag: :div, class: :input,\n                error_class: :field_with_errors,\n                valid_class: :field_without_errors do |b|\n\n  # Form extensions\n  b.use :html5\n  b.optional :pattern\n  b.use :maxlength\n  b.use :placeholder\n  b.use :readonly\n\n  # Form components\n  b.use :label_input\n  b.use :hint,  wrap_with: { tag: :span, class: :hint }\n  b.use :error, wrap_with: { tag: :span, class: :error }\nend\n```\n\nThe _Form components_ will generate the form tags like labels, inputs, hints or errors contents.\nThe available components are:\n\n```ruby\n:label         # The <label> tag alone\n:input         # The <input> tag alone\n:label_input   # The <label> and the <input> tags\n:hint          # The hint for the input\n:error         # The error for the input\n```\n\nThe _Form extensions_ are used to generate some attributes or perform some lookups on the model to\nadd extra information to your components.\n\nYou can create new _Form components_ using the wrappers API as in the following example:\n\n```ruby\nconfig.wrappers do |b|\n  b.use :placeholder\n  b.use :label_input\n  b.wrapper tag: :div, class: 'separator' do |component|\n    component.use :hint,  wrap_with: { tag: :span, class: :hint }\n    component.use :error, wrap_with: { tag: :span, class: :error }\n  end\nend\n```\n\nthis will wrap the hint and error components within a `div` tag using the class `'separator'`.\n\nYou can customize _Form components_ passing options to them:\n\n```ruby\nconfig.wrappers do |b|\n  b.use :label_input, class: 'label-input-class', error_class: 'is-invalid', valid_class: 'is-valid'\nend\n```\n\nThis sets the input and label classes to `'label-input-class'` and will set the class `'is-invalid'`\nif the input has errors and `'is-valid'` if the input is valid.\n\nIf you want to customize the custom _Form components_ on demand you can give it a name like this:\n\n```ruby\nconfig.wrappers do |b|\n  b.use :placeholder\n  b.use :label_input\n  b.wrapper :my_wrapper, tag: :div, class: 'separator', html: { id: 'my_wrapper_id' } do |component|\n    component.use :hint,  wrap_with: { tag: :span, class: :hint }\n    component.use :error, wrap_with: { tag: :span, class: :error }\n  end\nend\n```\n\nand now you can pass options to your `input` calls to customize the `:my_wrapper` _Form component_.\n\n```ruby\n# Completely turns off the custom wrapper\nf.input :name, my_wrapper: false\n\n# Configure the html\nf.input :name, my_wrapper_html: { id: 'special_id' }\n\n# Configure the tag\nf.input :name, my_wrapper_tag: :p\n```\n\nYou can also define more than one wrapper and pick one to render in a specific form or input.\nTo define another wrapper you have to give it a name, as the follow:\n\n```ruby\nconfig.wrappers :small do |b|\n  b.use :placeholder\n  b.use :label_input\nend\n```\n\nand use it in this way:\n\n```ruby\n# Specifying to whole form\nsimple_form_for @user, wrapper: :small do |f|\n  f.input :name\nend\n\n# Specifying to one input\nsimple_form_for @user do |f|\n  f.input :name, wrapper: :small\nend\n```\n\n**Simple Form** also allows you to use optional elements. For instance, let's suppose you want to use\nhints or placeholders, but you don't want them to be generated automatically. You can set their\ndefault values to `false` or use the `optional` method. Is preferable to use the `optional` syntax:\n\n```ruby\nconfig.wrappers placeholder: false do |b|\n  b.use :placeholder\n  b.use :label_input\n  b.wrapper tag: :div, class: 'separator' do |component|\n    component.optional :hint, wrap_with: { tag: :span, class: :hint }\n    component.use :error, wrap_with: { tag: :span, class: :error }\n  end\nend\n```\n\nBy setting it as `optional`, a hint will only be generated when `hint: true` is explicitly used.\nThe same for placeholder.\n\nIt is also possible to give the option `:unless_blank` to the wrapper if you want to render it only\nwhen the content is present.\n\n```ruby\n  b.wrapper tag: :span, class: 'hint', unless_blank: true do |component|\n    component.optional :hint\n  end\n```\n\n## Custom Components\n\nWhen you use custom wrappers, you might also be looking for a way to add custom components to your\nwrapper. The default components are:\n\n```ruby\n:label         # The <label> tag alone\n:input         # The <input> tag alone\n:label_input   # The <label> and the <input> tags\n:hint          # The hint for the input\n:error         # The error for the input\n```\n\nA custom component might be interesting for you if your views look something like this:\n\n```erb\n<%= simple_form_for @blog do |f| %>\n  <div class=\"row\">\n    <div class=\"span1 number\">\n      1\n    </div>\n    <div class=\"span8\">\n      <%= f.input :title %>\n    </div>\n  </div>\n  <div class=\"row\">\n    <div class=\"span1 number\">\n      2\n    </div>\n    <div class=\"span8\">\n      <%= f.input :body, as: :text %>\n    </div>\n  </div>\n<% end %>\n```\n\nA cleaner method to create your views would be:\n\n```erb\n<%= simple_form_for @blog, wrapper: :with_numbers do |f| %>\n  <%= f.input :title, number: 1 %>\n  <%= f.input :body, as: :text, number: 2 %>\n<% end %>\n```\n\nTo use the number option on the input, first, tells to Simple Form the place where the components\nwill be:\n\n``` ruby\n# config/initializers/simple_form.rb\nDir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }\n```\n\nCreate a new component within the path specified above:\n\n```ruby\n# lib/components/numbers_component.rb\nmodule NumbersComponent\n  # To avoid deprecation warning, you need to make the wrapper_options explicit\n  # even when they won't be used.\n  def number(wrapper_options = nil)\n    @number ||= begin\n      options[:number].to_s.html_safe if options[:number].present?\n    end\n  end\nend\n\nSimpleForm.include_component(NumbersComponent)\n```\n\nFinally, add a new wrapper to the config/initializers/simple_form.rb file:\n\n```ruby\nconfig.wrappers :with_numbers, tag: 'div', class: 'row', error_class: 'error' do |b|\n  b.use :html5\n  b.use :number, wrap_with: { tag: 'div', class: 'span1 number' }\n  b.wrapper tag: 'div', class: 'span8' do |ba|\n    ba.use :placeholder\n    ba.use :label\n    ba.use :input\n    ba.use :error, wrap_with: { tag: 'span', class: 'help-inline' }\n    ba.use :hint,  wrap_with: { tag: 'p', class: 'help-block' }\n  end\nend\n```\n\n## HTML 5 Notice\n\nBy default, **Simple Form** will generate input field types and attributes that are supported in HTML5,\nbut are considered invalid HTML for older document types such as HTML4 or XHTML1.0. The HTML5\nextensions include the new field types such as email, number, search, url, tel, and the new\nattributes such as required, autofocus, maxlength, min, max, step.\n\nMost browsers will not care, but some of the newer ones - in particular Chrome 10+ - use the\nrequired attribute to force a value into an input and will prevent form submission without it.\nDepending on the design of the application this may or may not be desired. In many cases it can\nbreak existing UI's.\n\nIt is possible to disable all HTML 5 extensions in **Simple Form** by removing the `html5`\ncomponent from the wrapper used to render the inputs.\n\nFor example, change:\n\n```ruby\nconfig.wrappers tag: :div do |b|\n  b.use :html5\n\n  b.use :label_input\nend\n```\n\nTo:\n\n```ruby\nconfig.wrappers tag: :div do |b|\n  b.use :label_input\nend\n```\n\nIf you want to have all other HTML 5 features, such as the new field types, you can disable only\nthe browser validation:\n\n```ruby\nSimpleForm.browser_validations = false # default is true\n```\n\nThis option adds a new `novalidate` property to the form, instructing it to skip all HTML 5\nvalidation. The inputs will still be generated with the required and other attributes, that might\nhelp you to use some generic javascript validation.\n\nYou can also add `novalidate` to a specific form by setting the option on the form itself:\n\n```erb\n<%= simple_form_for(resource, html: { novalidate: true }) do |form| %>\n```\n\nPlease notice that none of the configurations above will disable the `placeholder` component,\nwhich is an HTML 5 feature. We believe most of the newest browsers are handling this attribute\njust fine, and if they aren't, any plugin you use would take care of applying the placeholder.\nIn any case, you can disable it if you really want to, by removing the placeholder component\nfrom the components list in the **Simple Form** configuration file.\n\nHTML 5 date / time inputs are not generated by **Simple Form** by default, so using `date`,\n`time` or `datetime` will all generate select boxes using normal Rails helpers. We believe\nbrowsers are not totally ready for these yet, but you can easily opt-in on a per-input basis\nby passing the html5 option:\n\n```erb\n<%= f.input :expires_at, as: :date, html5: true %>\n```\n\n## Using non Active Record objects\n\nThere are few ways to build forms with objects that don't inherit from Active Record, as\nfollows:\n\nYou can include the module `ActiveModel::Model`.\n\n```ruby\nclass User\n  include ActiveModel::Model\n\n  attr_accessor :id, :name\nend\n```\n\nIf you are using Presenters or Decorators that inherit from `SimpleDelegator` you can delegate\nit to the model.\n\n```ruby\nclass UserPresenter < SimpleDelegator\n  # Without that, Simple Form will consider the user model as the object.\n  def to_model\n    self\n  end\nend\n```\n\nYou can define all methods required by the helpers.\n\n```ruby\nclass User\n  extend ActiveModel::Naming\n\n  attr_accessor :id, :name\n\n  def to_model\n    self\n  end\n\n  def to_key\n    id\n  end\n\n  def persisted?\n    false\n  end\nend\n```\n\nTo have SimpleForm infer the attributes' types, you can provide\n`#has_attribute?` and `#type_for_attribute` methods.\nThe later should return an object that responds to `#type`\nwith the attribute type. This is useful for generating\nthe correct input types (eg: checkboxes for booleans).\n\n```ruby\nclass User < Struct.new(:id, :name, :age, :registered)\n  def to_model\n    self\n  end\n\n  def model_name\n    OpenStruct.new(param_key: \"user\")\n  end\n\n  def to_key\n    id\n  end\n\n  def persisted?\n    id.present?\n  end\n\n  def has_attribute?(attr_name)\n    %w(id name age registered).include?(attr_name.to_s)\n  end\n\n  def type_for_attribute(attr_name)\n    case attr_name.to_s\n      when \"id\" then OpenStruct.new(type: :integer)\n      when \"name\" then OpenStruct.new(type: :string)\n      when \"age\" then OpenStruct.new(type: :integer)\n      when \"registered\" then OpenStruct.new(type: :boolean)\n    end\n  end\nend\n```\n\nIf your object doesn't implement those methods, you must make explicit it when you are\nbuilding the form\n\n```ruby\nclass User\n  attr_accessor :id, :name\n\n  # The only method required to use the f.submit helper.\n  def persisted?\n    false\n  end\nend\n```\n\n```erb\n<%= simple_form_for(@user, as: :user, method: :post, url: users_path) do |f| %>\n  <%= f.input :name %>\n  <%= f.submit 'New user' %>\n<% end %>\n```\n\n## Information\n\n### RDocs\n\nYou can view the **Simple Form** documentation in RDoc format here:\n\nhttps://rubydoc.info/github/heartcombo/simple_form/main/frames\n\n### Supported Ruby / Rails versions\n\nWe intend to maintain support for all Ruby / Rails versions that haven't reached end-of-life.\n\nFor more information about specific versions please check [Ruby](https://www.ruby-lang.org/en/downloads/branches/)\nand [Rails](https://guides.rubyonrails.org/maintenance_policy.html) maintenance policies, and our test matrix.\n\n### Bug reports\n\nIf you discover any bugs, feel free to create an issue on GitHub. Please add as much information as\npossible to help us in fixing the potential bug. We also encourage you to help even more by forking and\nsending us a pull request.\n\nhttps://github.com/heartcombo/simple_form/issues\n\nIf you have discovered a security related bug, please do NOT use the GitHub issue tracker. Send an e-mail to heartcombo.oss@gmail.com.\n\n## License\n\nMIT License.\nCopyright 2020-CURRENT Rafael França, Carlos Antonio da Silva.\nCopyright 2009-2019 Plataformatec.\n\nThe Simple Form logo is licensed under [Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License](https://creativecommons.org/licenses/by-nc-nd/4.0/).\n"
  },
  {
    "path": "Rakefile",
    "content": "# encoding: UTF-8\n\nrequire 'bundler/gem_tasks'\n\nrequire 'rake/testtask'\n\ndesc 'Default: run unit tests.'\ntask default: :test\n\ndesc 'Test the simple_form plugin.'\nRake::TestTask.new(:test) do |t|\n  t.libs << 'lib'\n  t.libs << 'test'\n  t.pattern = 'test/**/*_test.rb'\n  t.verbose = true\nend\n\nbegin\n  require 'rdoc/task'\n  desc 'Generate documentation for the simple_form plugin.'\n  RDoc::Task.new(:rdoc) do |rdoc|\n    rdoc.rdoc_dir = 'rdoc'\n    rdoc.title    = 'SimpleForm'\n    rdoc.options << '--line-numbers'\n    rdoc.rdoc_files.include('README.md')\n    rdoc.rdoc_files.include('lib/**/*.rb')\n  end\nrescue LoadError\n  puts 'RDoc::Task is not supported on this platform'\nend\n"
  },
  {
    "path": "bin/test",
    "content": "#!/usr/bin/env ruby\n$: << File.expand_path(File.expand_path('../../test', __FILE__))\n\nrequire 'bundler/setup'\nrequire 'rails/test_unit/runner'\nrequire 'rails/test_unit/reporter'\n\nRails::TestUnitReporter.executable = 'bin/test'\n\nRails::TestUnit::Runner.parse_options(ARGV)\nRails::TestUnit::Runner.run(ARGV)\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-0",
    "content": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.0.0\"\ngem \"actionpack\", \"~> 7.0.0\"\ngem \"railties\", \"~> 7.0.0\"\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-1",
    "content": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.1.0\"\ngem \"actionpack\", \"~> 7.1.0\"\ngem \"railties\", \"~> 7.1.0\"\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-7-2",
    "content": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 7.2.0\"\ngem \"actionpack\", \"~> 7.2.0\"\ngem \"railties\", \"~> 7.2.0\"\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-8-0",
    "content": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"activemodel\", \"~> 8.0.0\"\ngem \"actionpack\", \"~> 8.0.0\"\ngem \"railties\", \"~> 8.0.0\"\n"
  },
  {
    "path": "gemfiles/Gemfile-rails-main",
    "content": "source \"https://rubygems.org\"\n\ngemspec path: \"..\"\n\ngem \"railties\", github: \"rails/rails\", branch: \"main\"\ngem \"activemodel\", github: \"rails/rails\", branch: \"main\"\ngem \"actionpack\", github: \"rails/rails\", branch: \"main\"\ngem \"tzinfo\"\n"
  },
  {
    "path": "lib/generators/simple_form/USAGE",
    "content": "To copy a SimpleForm initializer to your Rails App, with some configuration values, just do:\n\n    rails generate simple_form:install\n"
  },
  {
    "path": "lib/generators/simple_form/install_generator.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Generators\n    class InstallGenerator < Rails::Generators::Base\n      desc \"Copy SimpleForm default files\"\n      source_root File.expand_path('../templates', __FILE__)\n      class_option :template_engine, desc: 'Template engine to be invoked (erb, haml or slim).'\n      class_option :bootstrap, type: :boolean, desc: 'Add the Bootstrap 5 wrappers to the SimpleForm initializer.'\n      class_option :foundation, type: :boolean, desc: 'Add the Zurb Foundation 5 wrappers to the SimpleForm initializer.'\n\n      def info_bootstrap\n        return if options.bootstrap? || options.foundation?\n        puts \"SimpleForm supports Bootstrap 5 and Zurb Foundation 5. If you want \"\\\n          \"a configuration that is compatible with one of these frameworks, then please \" \\\n          \"re-run this generator with --bootstrap or --foundation as an option.\"\n      end\n\n      def copy_config\n        template \"config/initializers/simple_form.rb\"\n\n        if options[:bootstrap]\n          template \"config/initializers/simple_form_bootstrap.rb\"\n        elsif options[:foundation]\n          template \"config/initializers/simple_form_foundation.rb\"\n        end\n\n        directory 'config/locales'\n      end\n\n      def copy_scaffold_template\n        engine = options[:template_engine]\n        copy_file \"_form.html.#{engine}\", \"lib/templates/#{engine}/scaffold/_form.html.#{engine}\"\n      end\n\n      def show_readme\n        if behavior == :invoke && options.bootstrap?\n          readme \"README\"\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/generators/simple_form/templates/README",
    "content": "===============================================================================\n\n  Be sure to have a copy of the Bootstrap stylesheet available on your\n  application, you can get it on http://getbootstrap.com/.\n\n  For usage examples and documentation, see the example app:\n\n    https://github.com/heartcombo/simple_form-bootstrap\n\n===============================================================================\n"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.erb",
    "content": "<%# frozen_string_literal: true %>\n<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>\n  <%%= f.error_notification %>\n  <%%= f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present? %>\n\n  <div class=\"form-inputs\">\n  <%- attributes.each do |attribute| -%>\n    <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>\n  <%- end -%>\n  </div>\n\n  <div class=\"form-actions\">\n    <%%= f.button :submit %>\n  </div>\n<%% end %>\n"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.haml",
    "content": "-# frozen_string_literal: true\n= simple_form_for(@<%= singular_table_name %>) do |f|\n  = f.error_notification\n  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?\n\n  .form-inputs\n  <%- attributes.each do |attribute| -%>\n    = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>\n  <%- end -%>\n\n  .form-actions\n    = f.button :submit\n"
  },
  {
    "path": "lib/generators/simple_form/templates/_form.html.slim",
    "content": "= simple_form_for(@<%= singular_table_name %>) do |f|\n  = f.error_notification\n  = f.error_notification message: f.object.errors[:base].to_sentence if f.object.errors[:base].present?\n\n  .form-inputs\n<%- attributes.each do |attribute| -%>\n    = f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %>\n<%- end -%>\n\n  .form-actions\n    = f.button :submit\n"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form.rb",
    "content": "# frozen_string_literal: true\n#\n# Uncomment this and change the path if necessary to include your own\n# components.\n# See https://github.com/heartcombo/simple_form#custom-components to know\n# more about custom components.\n# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }\n#\n# Use this setup block to configure all options available in SimpleForm.\nSimpleForm.setup do |config|\n  # Wrappers are used by the form builder to generate a\n  # complete input. You can remove any component from the\n  # wrapper, change the order or even add your own to the\n  # stack. The options given below are used to wrap the\n  # whole input.\n  config.wrappers :default, class: :input,\n    hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|\n    ## Extensions enabled by default\n    # Any of these extensions can be disabled for a\n    # given input by passing: `f.input EXTENSION_NAME => false`.\n    # You can make any of these extensions optional by\n    # renaming `b.use` to `b.optional`.\n\n    # Determines whether to use HTML5 (:email, :url, ...)\n    # and required attributes\n    b.use :html5\n\n    # Calculates placeholders automatically from I18n\n    # You can also pass a string as f.input placeholder: \"Placeholder\"\n    b.use :placeholder\n\n    ## Optional extensions\n    # They are disabled unless you pass `f.input EXTENSION_NAME => true`\n    # to the input. If so, they will retrieve the values from the model\n    # if any exists. If you want to enable any of those\n    # extensions by default, you can change `b.optional` to `b.use`.\n\n    # Calculates maxlength from length validations for string inputs\n    # and/or database column lengths\n    b.optional :maxlength\n\n    # Calculate minlength from length validations for string inputs\n    b.optional :minlength\n\n    # Calculates pattern from format validations for string inputs\n    b.optional :pattern\n\n    # Calculates min and max from length validations for numeric inputs\n    b.optional :min_max\n\n    # Calculates readonly automatically from readonly attributes\n    b.optional :readonly\n\n    ## Inputs\n    # b.use :input, class: 'input', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :label_input\n    b.use :hint,  wrap_with: { tag: :span, class: :hint }\n    b.use :error, wrap_with: { tag: :span, class: :error }\n\n    ## full_messages_for\n    # If you want to display the full error message for the attribute, you can\n    # use the component :full_error, like:\n    #\n    # b.use :full_error, wrap_with: { tag: :span, class: :error }\n  end\n\n  # The default wrapper to be used by the FormBuilder.\n  config.default_wrapper = :default\n\n  # Define the way to render check boxes / radio buttons with labels.\n  # Defaults to :nested for bootstrap config.\n  #   inline: input + label\n  #   nested: label > input\n  config.boolean_style = :nested\n\n  # Default class for buttons\n  config.button_class = 'btn'\n\n  # Method used to tidy up errors. Specify any Rails Array method.\n  # :first lists the first message for each field.\n  # Use :to_sentence to list all errors for each field.\n  # config.error_method = :first\n\n  # Default tag used for error notification helper.\n  config.error_notification_tag = :div\n\n  # CSS class to add for error notification helper.\n  config.error_notification_class = 'error_notification'\n\n  # Series of attempts to detect a default label method for collection.\n  # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]\n\n  # Series of attempts to detect a default value method for collection.\n  # config.collection_value_methods = [ :id, :to_s ]\n\n  # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.\n  # config.collection_wrapper_tag = nil\n\n  # You can define the class to use on all collection wrappers. Defaulting to none.\n  # config.collection_wrapper_class = nil\n\n  # You can wrap each item in a collection of radio/check boxes with a tag,\n  # defaulting to :span.\n  # config.item_wrapper_tag = :span\n\n  # You can define a class to use in all item wrappers. Defaulting to none.\n  # config.item_wrapper_class = nil\n\n  # How the label text should be generated altogether with the required text.\n  # config.label_text = lambda { |label, required, explicit_label| \"#{required} #{label}\" }\n\n  # You can define the class to use on all labels. Default is nil.\n  # config.label_class = nil\n\n  # You can define the default class to be used on forms. Can be overridden\n  # with `html: { :class }`. Defaulting to none.\n  # config.default_form_class = nil\n\n  # You can define which elements should obtain additional classes\n  # config.generate_additional_classes_for = [:wrapper, :label, :input]\n\n  # Whether attributes are required by default (or not). Default is true.\n  # config.required_by_default = true\n\n  # Tell browsers whether to use the native HTML5 validations (novalidate form option).\n  # These validations are enabled in SimpleForm's internal config but disabled by default\n  # in this configuration, which is recommended due to some quirks from different browsers.\n  # To stop SimpleForm from generating the novalidate option, enabling the HTML5 validations,\n  # change this configuration to true.\n  config.browser_validations = false\n\n  # Custom mappings for input types. This should be a hash containing a regexp\n  # to match as key, and the input type that will be used when the field name\n  # matches the regexp as value.\n  # config.input_mappings = { /count/ => :integer }\n\n  # Custom wrappers for input types. This should be a hash containing an input\n  # type as key and the wrapper that will be used for all inputs with specified type.\n  # config.wrapper_mappings = { string: :prepend }\n\n  # Namespaces where SimpleForm should look for custom input classes that\n  # override default inputs.\n  # config.custom_inputs_namespaces << \"CustomInputs\"\n\n  # Default priority for time_zone inputs.\n  # config.time_zone_priority = nil\n\n  # Default priority for country inputs.\n  # config.country_priority = nil\n\n  # When false, do not use translations for labels.\n  # config.translate_labels = true\n\n  # Automatically discover new inputs in Rails' autoload path.\n  # config.inputs_discovery = true\n\n  # Cache SimpleForm inputs discovery\n  # config.cache_discovery = !Rails.env.development?\n\n  # Default class for inputs\n  # config.input_class = nil\n\n  # Define the default class of the input wrapper of the boolean input.\n  config.boolean_label_class = 'checkbox'\n\n  # Defines if the default input wrapper class should be included in radio\n  # collection wrappers.\n  # config.include_default_input_wrapper_class = true\n\n  # Defines which i18n scope will be used in Simple Form.\n  # config.i18n_scope = 'simple_form'\n\n  # Defines validation classes to the input_field. By default it's nil.\n  # config.input_field_valid_class = 'is-valid'\n  # config.input_field_error_class = 'is-invalid'\nend\n"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb",
    "content": "# frozen_string_literal: true\n\n# These defaults are defined and maintained by the community at\n# https://github.com/heartcombo/simple_form-bootstrap\n# Please submit feedback, changes and tests only there.\n\n# Uncomment this and change the path if necessary to include your own\n# components.\n# See https://github.com/heartcombo/simple_form#custom-components\n# to know more about custom components.\n# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }\n\n# Use this setup block to configure all options available in SimpleForm.\nSimpleForm.setup do |config|\n  # Default class for buttons\n  config.button_class = 'btn'\n\n  # Define the default class of the input wrapper of the boolean input.\n  config.boolean_label_class = 'form-check-label'\n\n  # How the label text should be generated altogether with the required text.\n  config.label_text = lambda { |label, required, explicit_label| \"#{label} #{required}\" }\n\n  # Define the way to render check boxes / radio buttons with labels.\n  config.boolean_style = :inline\n\n  # You can wrap each item in a collection of radio/check boxes with a tag\n  config.item_wrapper_tag = :div\n\n  # Defines if the default input wrapper class should be included in radio\n  # collection wrappers.\n  config.include_default_input_wrapper_class = false\n\n  # CSS class to add for error notification helper.\n  config.error_notification_class = 'alert alert-danger'\n\n  # Method used to tidy up errors. Specify any Rails Array method.\n  # :first lists the first message for each field.\n  # :to_sentence to list all errors for each field.\n  config.error_method = :to_sentence\n\n  # add validation classes to `input_field`\n  config.input_field_error_class = 'is-invalid'\n  config.input_field_valid_class = 'is-valid'\n\n\n  # vertical forms\n  #\n  # vertical default_wrapper\n  config.wrappers :vertical_form, class: 'mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :label, class: 'form-label'\n    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical input for boolean\n  config.wrappers :vertical_boolean, tag: 'fieldset', class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :form_check_wrapper, class: 'form-check' do |bb|\n      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n      bb.use :label, class: 'form-check-label'\n      bb.use :full_error, wrap_with: { class: 'invalid-feedback' }\n      bb.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # vertical input for radio buttons and check boxes\n  config.wrappers :vertical_collection, item_wrapper_class: 'form-check', item_label_class: 'form-check-label', tag: 'fieldset', class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|\n      ba.use :label_text\n    end\n    b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical input for inline radio buttons and check boxes\n  config.wrappers :vertical_collection_inline, item_wrapper_class: 'form-check form-check-inline', item_label_class: 'form-check-label', tag: 'fieldset', class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :legend_tag, tag: 'legend', class: 'col-form-label pt-0' do |ba|\n      ba.use :label_text\n    end\n    b.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical file input\n  config.wrappers :vertical_file, class: 'mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :readonly\n    b.use :label, class: 'form-label'\n    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical select input\n  config.wrappers :vertical_select, class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'form-label'\n    b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical multi select\n  config.wrappers :vertical_multi_select, class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'form-label'\n    b.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |ba|\n      ba.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'\n    end\n    b.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # vertical range input\n  config.wrappers :vertical_range, class: 'mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :readonly\n    b.optional :step\n    b.use :label, class: 'form-label'\n    b.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n\n  # horizontal forms\n  #\n  # horizontal default_wrapper\n  config.wrappers :horizontal_form, class: 'row mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal input for boolean\n  config.wrappers :horizontal_boolean, class: 'row mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :grid_wrapper, class: 'col-sm-9 offset-sm-3' do |wr|\n      wr.wrapper :form_check_wrapper, class: 'form-check' do |bb|\n        bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n        bb.use :label, class: 'form-check-label'\n        bb.use :full_error, wrap_with: { class: 'invalid-feedback' }\n        bb.use :hint, wrap_with: { class: 'form-text' }\n      end\n    end\n  end\n\n  # horizontal input for radio buttons and check boxes\n  config.wrappers :horizontal_collection, item_wrapper_class: 'form-check', item_label_class: 'form-check-label', class: 'row mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label pt-0'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal input for inline radio buttons and check boxes\n  config.wrappers :horizontal_collection_inline, item_wrapper_class: 'form-check form-check-inline', item_label_class: 'form-check-label', class: 'row mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label pt-0'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal file input\n  config.wrappers :horizontal_file, class: 'row mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal select input\n  config.wrappers :horizontal_select, class: 'row mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal multi select\n  config.wrappers :horizontal_multi_select, class: 'row mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :label, class: 'col-sm-3 col-form-label'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.wrapper class: 'd-flex flex-row justify-content-between align-items-center' do |bb|\n        bb.use :input, class: 'form-select mx-1', error_class: 'is-invalid', valid_class: 'is-valid'\n      end\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback d-block' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n  # horizontal range input\n  config.wrappers :horizontal_range, class: 'row mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :readonly\n    b.optional :step\n    b.use :label, class: 'col-sm-3 col-form-label pt-0'\n    b.wrapper :grid_wrapper, class: 'col-sm-9' do |ba|\n      ba.use :input, class: 'form-range', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }\n      ba.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n\n  # inline forms\n  #\n  # inline default_wrapper\n  config.wrappers :inline_form, class: 'col-12' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :label, class: 'visually-hidden'\n\n    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :error, wrap_with: { class: 'invalid-feedback' }\n    b.optional :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # inline input for boolean\n  config.wrappers :inline_boolean, class: 'col-12' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :form_check_wrapper, class: 'form-check' do |bb|\n      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n      bb.use :label, class: 'form-check-label'\n      bb.use :error, wrap_with: { class: 'invalid-feedback' }\n      bb.optional :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n\n  # bootstrap custom forms\n  #\n  # custom input switch for boolean\n  config.wrappers :custom_boolean_switch, class: 'mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.wrapper :form_check_wrapper, tag: 'div', class: 'form-check form-switch' do |bb|\n      bb.use :input, class: 'form-check-input', error_class: 'is-invalid', valid_class: 'is-valid'\n      bb.use :label, class: 'form-check-label'\n      bb.use :full_error, wrap_with: { tag: 'div', class: 'invalid-feedback' }\n      bb.use :hint, wrap_with: { class: 'form-text' }\n    end\n  end\n\n\n  # Input Group - custom component\n  # see example app and config at https://github.com/heartcombo/simple_form-bootstrap\n  config.wrappers :input_group, class: 'mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :label, class: 'form-label'\n    b.wrapper :input_group_tag, class: 'input-group' do |ba|\n      ba.optional :prepend\n      ba.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n      ba.optional :append\n      ba.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    end\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n\n  # Floating Labels form\n  #\n  # floating labels default_wrapper\n  config.wrappers :floating_labels_form, class: 'form-floating mb-3' do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :input, class: 'form-control', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :label\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n  # custom multi select\n  config.wrappers :floating_labels_select, class: 'form-floating mb-3' do |b|\n    b.use :html5\n    b.optional :readonly\n    b.use :input, class: 'form-select', error_class: 'is-invalid', valid_class: 'is-valid'\n    b.use :label\n    b.use :full_error, wrap_with: { class: 'invalid-feedback' }\n    b.use :hint, wrap_with: { class: 'form-text' }\n  end\n\n\n  # The default wrapper to be used by the FormBuilder.\n  config.default_wrapper = :vertical_form\n\n  # Custom wrappers for input types. This should be a hash containing an input\n  # type as key and the wrapper that will be used for all inputs with specified type.\n  config.wrapper_mappings = {\n    boolean:       :vertical_boolean,\n    check_boxes:   :vertical_collection,\n    date:          :vertical_multi_select,\n    datetime:      :vertical_multi_select,\n    file:          :vertical_file,\n    radio_buttons: :vertical_collection,\n    range:         :vertical_range,\n    time:          :vertical_multi_select,\n    select:        :vertical_select\n  }\nend\n"
  },
  {
    "path": "lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb",
    "content": "# frozen_string_literal: true\n#\n# Uncomment this and change the path if necessary to include your own\n# components.\n# See https://github.com/heartcombo/simple_form#custom-components to know\n# more about custom components.\n# Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }\n#\n# Use this setup block to configure all options available in SimpleForm.\nSimpleForm.setup do |config|\n  # Don't forget to edit this file to adapt it to your needs (specially\n  # all the grid-related classes)\n  #\n  # Please note that hints are commented out by default since Foundation\n  # doesn't provide styles for hints. You will need to provide your own CSS styles for hints.\n  # Uncomment them to enable hints.\n\n  config.wrappers :vertical_form, class: :input, hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n    b.use :label_input\n    b.use :error, wrap_with: { tag: :small, class: :error }\n\n    # b.use :hint,  wrap_with: { tag: :span, class: :hint }\n  end\n\n  config.wrappers :horizontal_form, tag: 'div', class: 'row', hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n\n    b.wrapper :label_wrapper, tag: :div, class: 'small-3 columns' do |ba|\n      ba.use :label, class: 'text-right inline'\n    end\n\n    b.wrapper :right_input_wrapper, tag: :div, class: 'small-9 columns' do |ba|\n      ba.use :input\n      ba.use :error, wrap_with: { tag: :small, class: :error }\n      # ba.use :hint,  wrap_with: { tag: :span, class: :hint }\n    end\n  end\n\n  config.wrappers :horizontal_radio_and_checkboxes, tag: 'div', class: 'row' do |b|\n    b.use :html5\n    b.optional :readonly\n\n    b.wrapper :container_wrapper, tag: 'div', class: 'small-offset-3 small-9 columns' do |ba|\n      ba.wrapper tag: 'label', class: 'checkbox' do |bb|\n        bb.use :input\n        bb.use :label_text\n      end\n\n      ba.use :error, wrap_with: { tag: :small, class: :error }\n      # ba.use :hint,  wrap_with: { tag: :span, class: :hint }\n    end\n  end\n\n  # Foundation does not provide a way to handle inline forms\n  # This wrapper can be used to create an inline form\n  # by hiding that labels on every screen sizes ('hidden-for-small-up').\n  #\n  # Note that you need to adapt this wrapper to your needs. If you need a 4\n  # columns form then change the wrapper class to 'small-3', if you need\n  # only two use 'small-6' and so on.\n  config.wrappers :inline_form, tag: 'div', class: 'column small-4', hint_class: :field_with_hint, error_class: :error, valid_class: :valid do |b|\n    b.use :html5\n    b.use :placeholder\n    b.optional :maxlength\n    b.optional :minlength\n    b.optional :pattern\n    b.optional :min_max\n    b.optional :readonly\n\n    b.use :label, class: 'hidden-for-small-up'\n    b.use :input\n\n    b.use :error, wrap_with: { tag: :small, class: :error }\n    # b.use :hint,  wrap_with: { tag: :span, class: :hint }\n  end\n\n  # Examples of use:\n  # - wrapper_html: {class: 'row'}, custom_wrapper_html: {class: 'column small-12'}\n  # - custom_wrapper_html: {class: 'column small-3 end'}\n  config.wrappers :customizable_wrapper, tag: 'div', error_class: :error, valid_class: :valid do |b|\n    b.use :html5\n    b.optional :readonly\n\n    b.wrapper :custom_wrapper, tag: :div do |ba|\n      ba.use :label_input\n    end\n\n    b.use :error, wrap_with: { tag: :small, class: :error }\n    # b.use :hint,  wrap_with: { tag: :span, class: :hint }\n  end\n\n  # CSS class for buttons\n  config.button_class = 'button'\n\n  # Set this to div to make the checkbox and radio properly work\n  # otherwise simple_form adds a label tag instead of a div around\n  # the nested label\n  config.item_wrapper_tag = :div\n\n  # CSS class to add for error notification helper.\n  config.error_notification_class = 'alert-box alert'\n\n  # The default wrapper to be used by the FormBuilder.\n  config.default_wrapper = :vertical_form\n\n  # Defines validation classes to the input_field. By default it's nil.\n  # config.input_field_valid_class = 'is-valid'\n  # config.input_field_error_class = 'is-invalid'\nend\n"
  },
  {
    "path": "lib/generators/simple_form/templates/config/locales/simple_form.en.yml",
    "content": "en:\n  simple_form:\n    \"yes\": 'Yes'\n    \"no\": 'No'\n    required:\n      text: 'required'\n      mark: '*'\n      # You can uncomment the line below if you need to overwrite the whole required html.\n      # When using html, text and mark won't be used.\n      # html: '<abbr title=\"required\">*</abbr>'\n    error_notification:\n      default_message: \"Please review the problems below:\"\n    # Examples\n    # labels:\n    #   defaults:\n    #     password: 'Password'\n    #   user:\n    #     new:\n    #       email: 'E-mail to sign in.'\n    #     edit:\n    #       email: 'E-mail.'\n    # hints:\n    #   defaults:\n    #     username: 'User name to sign in.'\n    #     password: 'No special characters, please.'\n    # include_blanks:\n    #   defaults:\n    #     age: 'Rather not say'\n    # prompts:\n    #   defaults:\n    #     age: 'Select your age'\n"
  },
  {
    "path": "lib/simple_form/action_view_extensions/builder.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module ActionViewExtensions\n    # A collection of methods required by simple_form but added to rails default form.\n    # This means that you can use such methods outside simple_form context.\n    module Builder\n\n      # Wrapper for using SimpleForm inside a default rails form.\n      # Example:\n      #\n      #   form_for @user do |f|\n      #     f.simple_fields_for :posts do |posts_form|\n      #       # Here you have all simple_form methods available\n      #       posts_form.input :title\n      #     end\n      #   end\n      def simple_fields_for(*args, &block)\n        options = args.extract_options!\n        options[:wrapper] = self.options[:wrapper] if options[:wrapper].nil?\n        options[:defaults] ||= self.options[:defaults]\n        options[:wrapper_mappings] ||= self.options[:wrapper_mappings]\n\n        if self.class < ActionView::Helpers::FormBuilder\n          options[:builder] ||= self.class\n        else\n          options[:builder] ||= SimpleForm::FormBuilder\n        end\n        fields_for(*args, options, &block)\n      end\n    end\n  end\nend\n\nmodule ActionView::Helpers\n  class FormBuilder\n    include SimpleForm::ActionViewExtensions::Builder\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/action_view_extensions/form_helper.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module ActionViewExtensions\n    # This module creates SimpleForm wrappers around default form_for and fields_for.\n    #\n    # Example:\n    #\n    #   simple_form_for @user do |f|\n    #     f.input :name, hint: 'My hint'\n    #   end\n    #\n    module FormHelper\n\n      def simple_form_for(record, options = {}, &block)\n        options[:builder] ||= SimpleForm::FormBuilder\n        options[:html] ||= {}\n        unless options[:html].key?(:novalidate)\n          options[:html][:novalidate] = !SimpleForm.browser_validations\n        end\n        if options[:html].key?(:class)\n          options[:html][:class] = [SimpleForm.form_class, options[:html][:class]].compact\n        else\n          options[:html][:class] = [SimpleForm.form_class, SimpleForm.default_form_class, simple_form_css_class(record, options)].compact\n        end\n\n        with_simple_form_field_error_proc do\n          form_for(record, options, &block)\n        end\n      end\n\n      def simple_fields_for(record_name, record_object = nil, options = {}, &block)\n        options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?\n        options[:builder] ||= SimpleForm::FormBuilder\n\n        with_simple_form_field_error_proc do\n          fields_for(record_name, record_object, options, &block)\n        end\n      end\n\n      private\n\n      def with_simple_form_field_error_proc\n        default_field_error_proc = ::ActionView::Base.field_error_proc\n        begin\n          ::ActionView::Base.field_error_proc = SimpleForm.field_error_proc\n          yield\n        ensure\n          ::ActionView::Base.field_error_proc = default_field_error_proc\n        end\n      end\n\n      def simple_form_css_class(record, options)\n        html_options = options[:html]\n        as = options[:as]\n\n        if html_options.key?(:class)\n          html_options[:class]\n        elsif record.is_a?(String) || record.is_a?(Symbol)\n          as || record\n        else\n          record = record.last if record.is_a?(Array)\n          action = record.respond_to?(:persisted?) && record.persisted? ? :edit : :new\n          as ? \"#{action}_#{as}\" : dom_class(record, action)\n        end\n      end\n    end\n  end\nend\n\nActiveSupport.on_load(:action_view) do\n  include SimpleForm::ActionViewExtensions::FormHelper\nend\n"
  },
  {
    "path": "lib/simple_form/components/errors.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module Errors\n      def error(wrapper_options = nil)\n        error_text if has_errors?\n      end\n\n      def full_error(wrapper_options = nil)\n        full_error_text if options[:error] != false && has_errors?\n      end\n\n      def has_errors?\n        object_with_errors? || !object && has_custom_error?\n      end\n\n      def has_value?\n        object && object.respond_to?(attribute_name) && object.send(attribute_name).present?\n      end\n\n      def valid?\n        !has_errors? && has_value?\n      end\n\n      protected\n\n      def error_text\n        text = has_custom_error? ? options[:error] : errors.send(error_method)\n\n        \"#{html_escape(options[:error_prefix])} #{html_escape(text)}\".lstrip.html_safe\n      end\n\n      def full_error_text\n        has_custom_error? ? options[:error] : full_errors.send(error_method)\n      end\n\n      def object_with_errors?\n        object && object.respond_to?(:errors) && errors.present?\n      end\n\n      def error_method\n        options[:error_method] || SimpleForm.error_method\n      end\n\n      def errors\n        @errors ||= (errors_on_attribute + errors_on_association).compact\n      end\n\n      def full_errors\n        @full_errors ||= (full_errors_on_attribute + full_errors_on_association).compact\n      end\n\n      def errors_on_attribute\n        object.errors[attribute_name] || []\n      end\n\n      def full_errors_on_attribute\n        object.errors.full_messages_for(attribute_name)\n      end\n\n      def errors_on_association\n        reflection ? object.errors[reflection.name] : []\n      end\n\n      def full_errors_on_association\n        reflection ? object.errors.full_messages_for(reflection.name) : []\n      end\n\n      def has_custom_error?\n        options[:error].is_a?(String)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/hints.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Hints\n      def hint(wrapper_options = nil)\n        @hint ||= begin\n          hint = options[:hint]\n\n          if hint.is_a?(String)\n            html_escape(hint)\n          else\n            content = translate_from_namespace(:hints)\n            content.html_safe if content\n          end\n        end\n      end\n\n      def has_hint?\n        options[:hint] != false && hint.present?\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/html5.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module HTML5\n      def initialize(*)\n        @html5 = false\n      end\n\n      def html5(wrapper_options = nil)\n        @html5 = true\n\n        input_html_options[:required]        = input_html_required_option\n        input_html_options[:'aria-invalid']  = has_errors? || nil\n        nil\n      end\n\n      def html5?\n        @html5\n      end\n\n      def input_html_required_option\n        !options[:required].nil? ? required_field? : has_required?\n      end\n\n      def has_required?\n        # We need to check browser_validations because\n        # some browsers are still checking required even\n        # if novalidate was given.\n        required_field? && SimpleForm.browser_validations\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/label_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module LabelInput\n      extend ActiveSupport::Concern\n\n      included do\n        include SimpleForm::Components::Labels\n      end\n\n      def label_input(wrapper_options = nil)\n        if options[:label] == false\n          deprecated_component(:input, wrapper_options)\n        else\n          deprecated_component(:label, wrapper_options) + deprecated_component(:input, wrapper_options)\n        end\n      end\n\n      private\n\n      def deprecated_component(namespace, wrapper_options)\n        method = method(namespace)\n\n        if method.arity.zero?\n          SimpleForm.deprecator.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: namespace })\n\n          method.call\n        else\n          method.call(wrapper_options)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/labels.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module Labels\n      extend ActiveSupport::Concern\n\n      module ClassMethods #:nodoc:\n        def translate_required_html\n          I18n.t(:\"required.html\", scope: i18n_scope, default:\n            %(<abbr title=\"#{translate_required_text}\">#{translate_required_mark}</abbr>)\n          )\n        end\n\n        def translate_required_text\n          I18n.t(:\"required.text\", scope: i18n_scope, default: 'required')\n        end\n\n        def translate_required_mark\n          I18n.t(:\"required.mark\", scope: i18n_scope, default: '*')\n        end\n\n        private\n\n        def i18n_scope\n          SimpleForm.i18n_scope\n        end\n      end\n\n      def label(wrapper_options = nil)\n        label_options = merge_wrapper_options(label_html_options, wrapper_options)\n\n        if generate_label_for_attribute?\n          @builder.label(label_target, label_text, label_options)\n        else\n          template.label_tag(nil, label_text, label_options)\n        end\n      end\n\n      def label_text(wrapper_options = nil)\n        label_text = options[:label_text] || SimpleForm.label_text\n        label_text.call(html_escape(raw_label_text), required_label_text, options[:label].present?).strip.html_safe\n      end\n\n      def label_target\n        attribute_name\n      end\n\n      def label_html_options\n        label_html_classes = SimpleForm.additional_classes_for(:label) {\n          [input_type, required_class, disabled_class, SimpleForm.label_class].compact\n        }\n\n        label_options = html_options_for(:label, label_html_classes)\n        if options.key?(:input_html) && options[:input_html].key?(:id)\n          label_options[:for] = options[:input_html][:id]\n        end\n\n        label_options\n      end\n\n      protected\n\n      def raw_label_text #:nodoc:\n        options[:label] || label_translation\n      end\n\n      # Default required text when attribute is required.\n      def required_label_text #:nodoc:\n        required_field? ? self.class.translate_required_html.dup : ''\n      end\n\n      # First check labels translation and then human attribute name.\n      def label_translation #:nodoc:\n        if SimpleForm.translate_labels && (translated_label = translate_from_namespace(:labels))\n          translated_label\n        elsif object.class.respond_to?(:human_attribute_name)\n          object.class.human_attribute_name(reflection_or_attribute_name.to_s, { base: object })\n        else\n          attribute_name.to_s.humanize\n        end\n      end\n\n      def generate_label_for_attribute?\n        true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/maxlength.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Maxlength\n      def maxlength(wrapper_options = nil)\n        input_html_options[:maxlength] ||= maximum_length_from_validation || limit\n        nil\n      end\n\n      private\n\n      def maximum_length_from_validation\n        maxlength = options[:maxlength]\n        if maxlength.is_a?(String) || maxlength.is_a?(Integer)\n          maxlength\n        else\n          length_validator = find_length_validator\n          maximum_length_value_from(length_validator)\n        end\n      end\n\n      def find_length_validator\n        find_validator(:length)\n      end\n\n      def maximum_length_value_from(length_validator)\n        if length_validator\n          value = length_validator.options[:is] || length_validator.options[:maximum]\n          resolve_validator_value(value)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/min_max.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    module MinMax\n      def min_max(wrapper_options = nil)\n        if numeric_validator = find_numericality_validator\n          validator_options = numeric_validator.options\n          input_html_options[:min] ||= minimum_value(validator_options)\n          input_html_options[:max] ||= maximum_value(validator_options)\n        end\n        nil\n      end\n\n      private\n\n      def integer?\n        input_type == :integer\n      end\n\n      def minimum_value(validator_options)\n        if integer? && validator_options.key?(:greater_than)\n          resolve_validator_value(validator_options[:greater_than]) + 1\n        else\n          resolve_validator_value(validator_options[:greater_than_or_equal_to])\n        end\n      end\n\n      def maximum_value(validator_options)\n        if integer? && validator_options.key?(:less_than)\n          resolve_validator_value(validator_options[:less_than]) - 1\n        else\n          resolve_validator_value(validator_options[:less_than_or_equal_to])\n        end\n      end\n\n      def find_numericality_validator\n        find_validator(:numericality)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/minlength.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Minlength\n      def minlength(wrapper_options = nil)\n        input_html_options[:minlength] ||= minimum_length_from_validation\n        nil\n      end\n\n      private\n\n      def minimum_length_from_validation\n        minlength = options[:minlength]\n        if minlength.is_a?(String) || minlength.is_a?(Integer)\n          minlength\n        else\n          length_validator = find_length_validator\n          minimum_length_value_from(length_validator)\n        end\n      end\n\n      def find_length_validator\n        find_validator(:length)\n      end\n\n      def minimum_length_value_from(length_validator)\n        if length_validator\n          value = length_validator.options[:is] || length_validator.options[:minimum]\n          resolve_validator_value(value)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/pattern.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Pattern\n      def pattern(wrapper_options = nil)\n        input_html_options[:pattern] ||= pattern_source\n        nil\n      end\n\n      private\n\n      def pattern_source\n        pattern = options[:pattern]\n        if pattern.is_a?(String)\n          pattern\n        elsif (pattern_validator = find_pattern_validator) && (with = pattern_validator.options[:with])\n          resolve_validator_value(with).source\n        end\n      end\n\n      def find_pattern_validator\n        find_validator(:format)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/placeholders.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Placeholders\n      def placeholder(wrapper_options = nil)\n        input_html_options[:placeholder] ||= placeholder_text\n        nil\n      end\n\n      def placeholder_text(wrapper_options = nil)\n        placeholder = options[:placeholder]\n        placeholder.is_a?(String) ? placeholder : translate_from_namespace(:placeholders)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components/readonly.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Components\n    # Needs to be enabled in order to do automatic lookups.\n    module Readonly\n      def readonly(wrapper_options = nil)\n        if readonly_attribute? && !has_readonly?\n          input_html_options[:readonly] ||= true\n          input_html_classes << :readonly\n        end\n        nil\n      end\n\n      private\n\n      def readonly_attribute?\n        object.class.respond_to?(:readonly_attributes) &&\n          object.persisted? &&\n          object.class.readonly_attributes.include?(attribute_name.to_s)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/components.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  # Components are a special type of helpers that can work on their own.\n  # For example, by using a component, it will automatically change the\n  # output under given circumstances without user input. For example,\n  # the disabled helper always need a disabled: true option given\n  # to the input in order to be enabled. On the other hand, things like\n  # hints can generate output automatically by doing I18n lookups.\n  module Components\n    extend ActiveSupport::Autoload\n\n    autoload :Errors\n    autoload :Hints\n    autoload :HTML5\n    autoload :LabelInput\n    autoload :Labels\n    autoload :MinMax\n    autoload :Maxlength\n    autoload :Minlength\n    autoload :Pattern\n    autoload :Placeholders\n    autoload :Readonly\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/error_notification.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  class ErrorNotification\n    delegate :object, :object_name, :template, to: :@builder\n\n    def initialize(builder, options)\n      @builder = builder\n      @message = options.delete(:message)\n      @options = options\n    end\n\n    def render\n      if has_errors?\n        template.content_tag(error_notification_tag, error_message, html_options)\n      end\n    end\n\n    protected\n\n    def errors\n      object.errors\n    end\n\n    def has_errors?\n      object && object.respond_to?(:errors) && errors.present?\n    end\n\n    def error_message\n      (@message || translate_error_notification).html_safe\n    end\n\n    def error_notification_tag\n      SimpleForm.error_notification_tag\n    end\n\n    def html_options\n      @options[:class] = \"#{SimpleForm.error_notification_class} #{@options[:class]}\".strip\n      @options\n    end\n\n    def translate_error_notification\n      lookups = []\n      lookups << :\"#{object_name}\"\n      lookups << :default_message\n      lookups << \"Please review the problems below:\"\n      I18n.t(lookups.shift, scope: :\"simple_form.error_notification\", default: lookups)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/form_builder.rb",
    "content": "# frozen_string_literal: true\nrequire 'active_support/core_ext/object/deep_dup'\nrequire 'simple_form/map_type'\nrequire 'simple_form/tags'\n\nmodule SimpleForm\n  class FormBuilder < ActionView::Helpers::FormBuilder\n    attr_reader :template, :object_name, :object, :wrapper\n\n    # When action is create or update, we still should use new and edit\n    ACTIONS = {\n      'create' => 'new',\n      'update' => 'edit'\n    }\n\n    ATTRIBUTE_COMPONENTS = %i[html5 min_max maxlength minlength placeholder pattern readonly]\n\n    extend MapType\n    include SimpleForm::Inputs\n\n    map_type :text, :hstore, :json, :jsonb,                        to: SimpleForm::Inputs::TextInput\n    map_type :file,                                                to: SimpleForm::Inputs::FileInput\n    map_type :string, :email, :search, :tel, :url, :uuid, :citext, to: SimpleForm::Inputs::StringInput\n    map_type :password,                                            to: SimpleForm::Inputs::PasswordInput\n    map_type :integer, :decimal, :float,                           to: SimpleForm::Inputs::NumericInput\n    map_type :range,                                               to: SimpleForm::Inputs::RangeInput\n    map_type :check_boxes,                                         to: SimpleForm::Inputs::CollectionCheckBoxesInput\n    map_type :radio_buttons,                                       to: SimpleForm::Inputs::CollectionRadioButtonsInput\n    map_type :rich_text_area,                                      to: SimpleForm::Inputs::RichTextAreaInput\n    map_type :select,                                              to: SimpleForm::Inputs::CollectionSelectInput\n    map_type :grouped_select,                                      to: SimpleForm::Inputs::GroupedCollectionSelectInput\n    map_type :date, :time, :datetime,                              to: SimpleForm::Inputs::DateTimeInput\n    map_type :country, :time_zone,                                 to: SimpleForm::Inputs::PriorityInput\n    map_type :boolean,                                             to: SimpleForm::Inputs::BooleanInput\n    map_type :hidden,                                              to: SimpleForm::Inputs::HiddenInput\n\n    def self.discovery_cache\n      @discovery_cache ||= {}\n    end\n\n    def initialize(*) #:nodoc:\n      super\n      @object   = convert_to_model(@object)\n      @defaults = options[:defaults]\n      @wrapper  = SimpleForm.wrapper(options[:wrapper] || SimpleForm.default_wrapper)\n    end\n\n    # Basic input helper, combines all components in the stack to generate\n    # input html based on options the user define and some guesses through\n    # database column information. By default a call to input will generate\n    # label + input + hint (when defined) + errors (when exists), and all can\n    # be configured inside a wrapper html.\n    #\n    # If a block is given, the contents of the block will replace the input\n    # field that would otherwise be generated automatically. The content will\n    # be given a label and wrapper div to make it consistent with the other\n    # elements in the form.\n    #\n    # == Examples\n    #\n    #   # Imagine @user has error \"can't be blank\" on name\n    #   simple_form_for @user do |f|\n    #     f.input :name, hint: 'My hint'\n    #   end\n    #\n    # This is the output html (only the input portion, not the form):\n    #\n    #     <label class=\"string required\" for=\"user_name\">\n    #       <abbr title=\"required\">*</abbr> Super User Name!\n    #     </label>\n    #     <input class=\"string required\" id=\"user_name\" maxlength=\"100\"\n    #        name=\"user[name]\" type=\"text\" value=\"Carlos\" />\n    #     <span class=\"hint\">My hint</span>\n    #     <span class=\"error\">can't be blank</span>\n    #\n    # Each database type will render a default input, based on some mappings and\n    # heuristic to determine which is the best option.\n    #\n    # You have some options for the input to enable/disable some functions:\n    #\n    #   as: allows you to define the input type you want, for instance you\n    #          can use it to generate a text field for a date column.\n    #\n    #   required: defines whether this attribute is required or not. True\n    #               by default.\n    #\n    # The fact SimpleForm is built in components allow the interface to be unified.\n    # So, for instance, if you need to disable :hint for a given input, you can pass\n    # hint: false. The same works for :error, :label and :wrapper.\n    #\n    # Besides the html for any component can be changed. So, if you want to change\n    # the label html you just need to give a hash to :label_html. To configure the\n    # input html, supply :input_html instead and so on.\n    #\n    # == Options\n    #\n    # Some inputs, as datetime, time and select allow you to give extra options, like\n    # prompt and/or include blank. Such options are given in plainly:\n    #\n    #    f.input :created_at, include_blank: true\n    #\n    # == Collection\n    #\n    # When playing with collections (:radio_buttons, :check_boxes and :select\n    # inputs), you have three extra options:\n    #\n    #   collection: use to determine the collection to generate the radio or select\n    #\n    #   label_method: the method to apply on the array collection to get the label\n    #\n    #   value_method: the method to apply on the array collection to get the value\n    #\n    # == Priority\n    #\n    # Some inputs, as :time_zone and :country accepts a :priority option. If none is\n    # given SimpleForm.time_zone_priority and SimpleForm.country_priority are used respectively.\n    #\n    def input(attribute_name, options = {}, &block)\n      options = @defaults.deep_dup.deep_merge(options) if @defaults\n\n      input   = find_input(attribute_name, options, &block)\n      wrapper = find_wrapper(input.input_type, options)\n\n      wrapper.render input\n    end\n    alias :attribute :input\n\n    # Creates a input tag for the given attribute. All the given options\n    # are sent as :input_html.\n    #\n    # == Examples\n    #\n    #   simple_form_for @user do |f|\n    #     f.input_field :name\n    #   end\n    #\n    # This is the output html (only the input portion, not the form):\n    #\n    #     <input class=\"string required\" id=\"user_name\" maxlength=\"100\"\n    #        name=\"user[name]\" type=\"text\" value=\"Carlos\" />\n    #\n    # It also support validation classes once it is configured.\n    #\n    #   # config/initializers/simple_form.rb\n    #   SimpleForm.setup do |config|\n    #     config.input_field_valid_class = 'is-valid'\n    #     config.input_field_error_class = 'is-invalid'\n    #   end\n    #\n    #   simple_form_for @user do |f|\n    #     f.input_field :name\n    #   end\n    #\n    # When the validation happens, the input will be rendered with\n    # the class configured according to the validation:\n    #\n    # - when the input is valid:\n    #\n    #     <input class=\"is-valid string required\" id=\"user_name\" value=\"Carlos\" />\n    #\n    # - when the input is invalid:\n    #\n    #     <input class=\"is-invalid string required\" id=\"user_name\" value=\"\" />\n    #\n    def input_field(attribute_name, options = {})\n      components = (wrapper.components.map(&:namespace) & ATTRIBUTE_COMPONENTS)\n\n      options = options.dup\n      options[:input_html] = options.except(:as, :boolean_style, :collection, :disabled, :label_method, :value_method, :prompt, *components)\n      options = @defaults.deep_dup.deep_merge(options) if @defaults\n\n      input      = find_input(attribute_name, options)\n      wrapper    = find_wrapper(input.input_type, options)\n      components = build_input_field_components(components.push(:input))\n\n      SimpleForm::Wrappers::Root.new(components, wrapper.options.merge(wrapper: false)).render input\n    end\n\n    # Helper for dealing with association selects/radios, generating the\n    # collection automatically. It's just a wrapper to input, so all options\n    # supported in input are also supported by association. Some extra options\n    # can also be given:\n    #\n    # == Examples\n    #\n    #   simple_form_for @user do |f|\n    #     f.association :company          # Company.all\n    #   end\n    #\n    #   f.association :company, collection: Company.all(order: 'name')\n    #   # Same as using :order option, but overriding collection\n    #\n    # == Block\n    #\n    # When a block is given, association simple behaves as a proxy to\n    # simple_fields_for:\n    #\n    #   f.association :company do |c|\n    #     c.input :name\n    #     c.input :type\n    #   end\n    #\n    # From the options above, only :collection can also be supplied.\n    #\n    # Please note that the association helper is currently only tested with Active Record. Depending on the ORM you are using your mileage may vary.\n    #\n    def association(association, options = {}, &block)\n      options = options.dup\n\n      return simple_fields_for(*[association,\n        options.delete(:collection), options].compact, &block) if block_given?\n\n      raise ArgumentError, \"Association cannot be used in forms not associated with an object\" unless @object\n\n      reflection = find_association_reflection(association)\n      raise \"Association #{association.inspect} not found\" unless reflection\n\n      options[:as] ||= :select\n      options[:collection] ||= fetch_association_collection(reflection, options)\n\n      attribute = build_association_attribute(reflection, association, options)\n\n      input(attribute, options.merge(reflection: reflection))\n    end\n\n    # Creates a button:\n    #\n    #   form_for @user do |f|\n    #     f.button :submit\n    #   end\n    #\n    # It just acts as a proxy to method name given. We also alias original Rails\n    # button implementation (3.2 forward (to delegate to the original when\n    # calling `f.button :button`.\n    #\n    alias_method :button_button, :button\n    def button(type, *args, &block)\n      options = args.extract_options!.dup\n      options[:class] = [SimpleForm.button_class, options[:class]].compact\n      args << options\n      if respond_to?(:\"#{type}_button\")\n        send(:\"#{type}_button\", *args, &block)\n      else\n        send(type, *args, &block)\n      end\n    end\n\n    # Creates an error tag based on the given attribute, only when the attribute\n    # contains errors. All the given options are sent as :error_html.\n    #\n    # == Examples\n    #\n    #    f.error :name\n    #    f.error :name, id: \"cool_error\"\n    #\n    def error(attribute_name, options = {})\n      options = options.dup\n\n      options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)\n      column      = find_attribute_column(attribute_name)\n      input_type  = default_input_type(attribute_name, column, options)\n      wrapper.find(:error).\n        render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))\n    end\n\n    # Return the error but also considering its name. This is used\n    # when errors for a hidden field need to be shown.\n    #\n    # == Examples\n    #\n    #    f.full_error :token #=> <span class=\"error\">Token is invalid</span>\n    #\n    def full_error(attribute_name, options = {})\n      options = options.dup\n\n      options[:error_prefix] ||= if object.class.respond_to?(:human_attribute_name)\n        object.class.human_attribute_name(attribute_name.to_s, { base: object })\n      else\n        attribute_name.to_s.humanize\n      end\n\n      error(attribute_name, options)\n    end\n\n    # Creates a hint tag for the given attribute. Accepts a symbol indicating\n    # an attribute for I18n lookup or a string. All the given options are sent\n    # as :hint_html.\n    #\n    # == Examples\n    #\n    #    f.hint :name # Do I18n lookup\n    #    f.hint :name, id: \"cool_hint\"\n    #    f.hint \"Don't forget to accept this\"\n    #\n    def hint(attribute_name, options = {})\n      options = options.dup\n\n      options[:hint_html] = options.except(:hint_tag, :hint)\n      if attribute_name.is_a?(String)\n        options[:hint] = attribute_name\n        attribute_name, column, input_type = nil, nil, nil\n      else\n        column      = find_attribute_column(attribute_name)\n        input_type  = default_input_type(attribute_name, column, options)\n      end\n\n      wrapper.find(:hint).\n        render(SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options))\n    end\n\n    # Creates a default label tag for the given attribute. You can give a label\n    # through the :label option or using i18n. All the given options are sent\n    # as :label_html.\n    #\n    # == Examples\n    #\n    #    f.label :name                     # Do I18n lookup\n    #    f.label :name, \"Name\"             # Same behavior as Rails, do not add required tag\n    #    f.label :name, label: \"Name\"      # Same as above, but adds required tag\n    #\n    #    f.label :name, required: false\n    #    f.label :name, id: \"cool_label\"\n    #\n    def label(attribute_name, *args)\n      return super if args.first.is_a?(String) || block_given?\n\n      options = args.extract_options!.dup\n      options[:label_html] = options.except(:label, :label_text, :required, :as)\n\n      column      = find_attribute_column(attribute_name)\n      input_type  = default_input_type(attribute_name, column, options)\n      SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).label\n    end\n\n    # Creates an error notification message that only appears when the form object\n    # has some error. You can give a specific message with the :message option,\n    # otherwise it will look for a message using I18n. All other options given are\n    # passed straight as html options to the html tag.\n    #\n    # == Examples\n    #\n    #    f.error_notification\n    #    f.error_notification message: 'Something went wrong'\n    #    f.error_notification id: 'user_error_message', class: 'form_error'\n    #\n    def error_notification(options = {})\n      SimpleForm::ErrorNotification.new(self, options).render\n    end\n\n    # Create a collection of radio inputs for the attribute. Basically this\n    # helper will create a radio input associated with a label for each\n    # text/value option in the collection, using value_method and text_method\n    # to convert these text/value. You can give a symbol or a proc to both\n    # value_method and text_method, that will be evaluated for each item in\n    # the collection.\n    #\n    # == Examples\n    #\n    #   form_for @user do |f|\n    #     f.collection_radio_buttons :options, [[true, 'Yes'] ,[false, 'No']], :first, :last\n    #   end\n    #\n    #   <input id=\"user_options_true\" name=\"user[options]\" type=\"radio\" value=\"true\" />\n    #   <label class=\"collection_radio_buttons\" for=\"user_options_true\">Yes</label>\n    #   <input id=\"user_options_false\" name=\"user[options]\" type=\"radio\" value=\"false\" />\n    #   <label class=\"collection_radio_buttons\" for=\"user_options_false\">No</label>\n    #\n    # It is also possible to give a block that should generate the radio +\n    # label. To wrap the radio with the label, for instance:\n    #\n    #   form_for @user do |f|\n    #     f.collection_radio_buttons(\n    #       :options, [[true, 'Yes'] ,[false, 'No']], :first, :last\n    #     ) do |b|\n    #       b.label { b.radio_button + b.text }\n    #     end\n    #   end\n    #\n    # == Options\n    #\n    # Collection radio accepts some extra options:\n    #\n    #   * checked  => the value that should be checked initially.\n    #\n    #   * disabled => the value or values that should be disabled. Accepts a single\n    #                 item or an array of items.\n    #\n    #   * collection_wrapper_tag   => the tag to wrap the entire collection.\n    #\n    #   * collection_wrapper_class => the CSS class to use for collection_wrapper_tag\n    #\n    #   * item_wrapper_tag         => the tag to wrap each item in the collection.\n    #\n    #   * item_wrapper_class       => the CSS class to use for item_wrapper_tag\n    #\n    #   * a block                  => to generate the label + radio or any other component.\n    def collection_radio_buttons(method, collection, value_method, text_method, options = {}, html_options = {}, &block)\n      SimpleForm::Tags::CollectionRadioButtons.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)\n    end\n\n    # Creates a collection of check boxes for each item in the collection,\n    # associated with a clickable label. Use value_method and text_method to\n    # convert items in the collection for use as text/value in check boxes.\n    # You can give a symbol or a proc to both value_method and text_method,\n    # that will be evaluated for each item in the collection.\n    #\n    # == Examples\n    #\n    #   form_for @user do |f|\n    #     f.collection_check_boxes :options, [[true, 'Yes'] ,[false, 'No']], :first, :last\n    #   end\n    #\n    #   <input name=\"user[options][]\" type=\"hidden\" value=\"\" />\n    #   <input id=\"user_options_true\" name=\"user[options][]\" type=\"checkbox\" value=\"true\" />\n    #   <label class=\"collection_check_boxes\" for=\"user_options_true\">Yes</label>\n    #   <input name=\"user[options][]\" type=\"hidden\" value=\"\" />\n    #   <input id=\"user_options_false\" name=\"user[options][]\" type=\"checkbox\" value=\"false\" />\n    #   <label class=\"collection_check_boxes\" for=\"user_options_false\">No</label>\n    #\n    # It is also possible to give a block that should generate the check box +\n    # label. To wrap the check box with the label, for instance:\n    #\n    #   form_for @user do |f|\n    #     f.collection_check_boxes(\n    #       :options, [[true, 'Yes'] ,[false, 'No']], :first, :last\n    #     ) do |b|\n    #       b.label { b.check_box + b.text }\n    #     end\n    #   end\n    #\n    # == Options\n    #\n    # Collection check box accepts some extra options:\n    #\n    #   * checked  => the value or values that should be checked initially. Accepts\n    #                 a single item or an array of items. It overrides existing associations.\n    #\n    #   * disabled => the value or values that should be disabled. Accepts a single\n    #                 item or an array of items.\n    #\n    #   * collection_wrapper_tag   => the tag to wrap the entire collection.\n    #\n    #   * collection_wrapper_class => the CSS class to use for collection_wrapper_tag. This option\n    #                                 is ignored if the :collection_wrapper_tag option is blank.\n    #\n    #   * item_wrapper_tag         => the tag to wrap each item in the collection.\n    #\n    #   * item_wrapper_class       => the CSS class to use for item_wrapper_tag\n    #\n    #   * a block                  => to generate the label + check box or any other component.\n    def collection_check_boxes(method, collection, value_method, text_method, options = {}, html_options = {}, &block)\n      SimpleForm::Tags::CollectionCheckBoxes.new(@object_name, method, @template, collection, value_method, text_method, objectify_options(options), @default_options.merge(html_options)).render(&block)\n    end\n\n    # Extract the model names from the object_name mess, ignoring numeric and\n    # explicit child indexes.\n    #\n    # Example:\n    #\n    # route[blocks_attributes][0][blocks_learning_object_attributes][1][foo_attributes]\n    # [\"route\", \"blocks\", \"blocks_learning_object\", \"foo\"]\n    #\n    def lookup_model_names #:nodoc:\n      @lookup_model_names ||= begin\n        child_index = options[:child_index]\n        names = object_name.to_s.scan(/(?!\\d)\\w+/).flatten\n        names.delete(child_index) if child_index\n        names.each { |name| name.gsub!('_attributes', '') }\n        names.freeze\n      end\n    end\n\n    # The action to be used in lookup.\n    def lookup_action #:nodoc:\n      @lookup_action ||= begin\n        action = template.controller && template.controller.action_name\n        return unless action\n        action = action.to_s\n        ACTIONS[action] || action\n      end\n    end\n\n    private\n\n    def fetch_association_collection(reflection, options)\n      options.fetch(:collection) do\n        relation = reflection.klass.all\n\n        if reflection.respond_to?(:scope) && reflection.scope\n          if reflection.scope.parameters.any?\n            relation = reflection.klass.instance_exec(object, &reflection.scope)\n          else\n            relation = reflection.klass.instance_exec(&reflection.scope)\n          end\n        else\n          order = reflection.options[:order]\n          conditions = reflection.options[:conditions]\n          conditions = object.instance_exec(&conditions) if conditions.respond_to?(:call)\n\n          relation = relation.where(conditions) if relation.respond_to?(:where) && conditions.present?\n          relation = relation.order(order) if relation.respond_to?(:order)\n        end\n\n        relation\n      end\n    end\n\n    def build_association_attribute(reflection, association, options)\n      case reflection.macro\n      when :belongs_to\n        (reflection.respond_to?(:options) && reflection.options[:foreign_key]) || :\"#{reflection.name}_id\"\n      when :has_one\n        raise ArgumentError, \":has_one associations are not supported by f.association\"\n      else\n        if options[:as] == :select || options[:as] == :grouped_select\n          html_options = options[:input_html] ||= {}\n          html_options[:multiple] = true unless html_options.key?(:multiple)\n        end\n\n        # Force the association to be preloaded for performance.\n        if options[:preload] != false && object.respond_to?(association)\n          target = object.send(association)\n          target.to_a if target.respond_to?(:to_a)\n        end\n\n        :\"#{reflection.name.to_s.singularize}_ids\"\n      end\n    end\n\n    # Find an input based on the attribute name.\n    def find_input(attribute_name, options = {}, &block)\n      column     = find_attribute_column(attribute_name)\n      input_type = default_input_type(attribute_name, column, options)\n\n      if block_given?\n        SimpleForm::Inputs::BlockInput.new(self, attribute_name, column, input_type, options, &block)\n      else\n        find_mapping(input_type).new(self, attribute_name, column, input_type, options)\n      end\n    end\n\n    # Attempt to guess the better input type given the defined options. By\n    # default always fallback to the user :as option, or to a :select when a\n    # collection is given.\n    def default_input_type(attribute_name, column, options)\n      return options[:as].to_sym if options[:as]\n      custom_type = find_custom_type(attribute_name.to_s) and return custom_type\n      return :select             if options[:collection]\n\n      input_type = column.try(:type)\n      case input_type\n      when :timestamp\n        :datetime\n      when :string, :citext, nil\n        case attribute_name.to_s\n        when /(?:\\b|\\W|_)password(?:\\b|\\W|_)/  then :password\n        when /(?:\\b|\\W|_)time_zone(?:\\b|\\W|_)/ then :time_zone\n        when /(?:\\b|\\W|_)country(?:\\b|\\W|_)/   then :country\n        when /(?:\\b|\\W|_)email(?:\\b|\\W|_)/     then :email\n        when /(?:\\b|\\W|_)phone(?:\\b|\\W|_)/     then :tel\n        when /(?:\\b|\\W|_)url(?:\\b|\\W|_)/       then :url\n        else\n          file_method?(attribute_name) ? :file : (input_type || :string)\n        end\n      else\n        input_type\n      end\n    end\n\n    def find_custom_type(attribute_name)\n      SimpleForm.input_mappings.find { |match, type|\n        attribute_name =~ match\n      }.try(:last) if SimpleForm.input_mappings\n    end\n\n    # Internal: Try to discover whether an attribute corresponds to a file or not.\n    #\n    # Most upload Gems add some kind of attributes to the ActiveRecord's model they are included in.\n    # This method tries to guess if an attribute belongs to some of these Gems by checking the presence\n    # of their methods using `#respond_to?`.\n    #\n    # Note: This does not support multiple file upload inputs, as this is very application-specific.\n    #\n    # The order here was chosen based on the popularity of Gems:\n    #\n    # - `#{attribute_name}_attachment` - ActiveStorage >= `5.2` and Refile >= `0.2.0` <= `0.4.0`\n    # - `remote_#{attribute_name}_url` - Refile >= `0.3.0` and CarrierWave >= `0.2.2`\n    # - `#{attribute_name}_attacher` - Refile >= `0.4.0` and Shrine >= `0.9.0`\n    # - `#{attribute_name}_file_name` - Paperclip ~> `2.0` (added for backwards compatibility)\n    #\n    # Returns a Boolean.\n    def file_method?(attribute_name)\n      @object.respond_to?(\"#{attribute_name}_attachment\") ||\n        @object.respond_to?(\"#{attribute_name}_attachments\") ||\n        @object.respond_to?(\"remote_#{attribute_name}_url\") ||\n        @object.respond_to?(\"#{attribute_name}_attacher\") ||\n        @object.respond_to?(\"#{attribute_name}_file_name\")\n    end\n\n    def find_attribute_column(attribute_name)\n      if @object.respond_to?(:type_for_attribute) && @object.has_attribute?(attribute_name)\n        detected_type = @object.type_for_attribute(attribute_name.to_s)\n\n        # Some attributes like ActiveRecord::Encryption::EncryptedAttribute are detected\n        # as different type, in that case we need to use the original type\n        detected_type.respond_to?(:cast_type) ? detected_type.cast_type : detected_type\n      elsif @object.respond_to?(:column_for_attribute) && @object.has_attribute?(attribute_name)\n        @object.column_for_attribute(attribute_name)\n      end\n    end\n\n    def find_association_reflection(association)\n      if @object.class.respond_to?(:reflect_on_association)\n        @object.class.reflect_on_association(association)\n      end\n    end\n\n    # Attempts to find a mapping. It follows the following rules:\n    #\n    # 1) It tries to find a registered mapping, if succeeds:\n    #    a) Try to find an alternative with the same name in the Object scope\n    #    b) Or use the found mapping\n    # 2) If not, fallbacks to #{input_type}Input\n    # 3) If not, fallbacks to SimpleForm::Inputs::#{input_type}Input\n    def find_mapping(input_type)\n      discovery_cache[input_type] ||=\n        if mapping = self.class.mappings[input_type]\n          mapping_override(mapping) || mapping\n        else\n          camelized = \"#{input_type.to_s.camelize}Input\"\n          attempt_mapping_with_custom_namespace(camelized) ||\n            attempt_mapping(camelized, Object) ||\n            attempt_mapping(camelized, self.class) ||\n            raise(\"No input found for #{input_type}\")\n        end\n    end\n\n    # Attempts to find a wrapper mapping. It follows the following rules:\n    #\n    # 1) It tries to find a wrapper for the current form\n    # 2) If not, it tries to find a config\n    def find_wrapper_mapping(input_type)\n      if options[:wrapper_mappings] && options[:wrapper_mappings][input_type]\n        options[:wrapper_mappings][input_type]\n      else\n        SimpleForm.wrapper_mappings && SimpleForm.wrapper_mappings[input_type]\n      end\n    end\n\n    def find_wrapper(input_type, options)\n      if name = options[:wrapper] || find_wrapper_mapping(input_type)\n        name.respond_to?(:render) ? name : SimpleForm.wrapper(name)\n      else\n        wrapper\n      end\n    end\n\n    # If cache_discovery is enabled, use the class level cache that persists\n    # between requests, otherwise use the instance one.\n    def discovery_cache\n      if SimpleForm.cache_discovery\n        self.class.discovery_cache\n      else\n        @discovery_cache ||= {}\n      end\n    end\n\n    def mapping_override(klass)\n      name = klass.name\n      if name =~ /^SimpleForm::Inputs/\n        input_name = name.split(\"::\").last\n        attempt_mapping_with_custom_namespace(input_name) ||\n          attempt_mapping(input_name, Object)\n      end\n    end\n\n    def attempt_mapping(mapping, at)\n      return if SimpleForm.inputs_discovery == false && at == Object\n\n      begin\n        at.const_get(mapping)\n      rescue NameError => e\n        raise unless e.message.include?(mapping)\n      end\n    end\n\n    def attempt_mapping_with_custom_namespace(input_name)\n      SimpleForm.custom_inputs_namespaces.each do |namespace|\n        if (mapping = attempt_mapping(input_name, namespace.constantize))\n          return mapping\n        end\n      end\n\n      nil\n    end\n\n    def build_input_field_components(components)\n      components.map do |component|\n        if component == :input\n          SimpleForm::Wrappers::Leaf.new(component, build_input_field_options)\n        else\n          SimpleForm::Wrappers::Leaf.new(component)\n        end\n      end\n    end\n\n    def build_input_field_options\n      input_field_options = {}\n      valid_class         = SimpleForm.input_field_valid_class\n      error_class         = SimpleForm.input_field_error_class\n\n      if error_class.present?\n        input_field_options[:error_class] = error_class\n      end\n\n      if valid_class.present?\n        input_field_options[:valid_class] = valid_class\n      end\n\n      input_field_options\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers/autofocus.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Autofocus\n      private\n\n      def has_autofocus?\n        options[:autofocus] == true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers/disabled.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Disabled\n      private\n\n      def has_disabled?\n        options[:disabled] == true\n      end\n\n      def disabled_class\n        :disabled if has_disabled?\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers/readonly.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Readonly\n      private\n\n      def readonly_class\n        :readonly if has_readonly?\n      end\n\n      def has_readonly?\n        options[:readonly] == true\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers/required.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Required\n      private\n\n      def required_field?\n        @required\n      end\n\n      def calculate_required\n        if !options[:required].nil?\n          options[:required]\n        elsif has_validators?\n          required_by_validators?\n        else\n          required_by_default?\n        end\n      end\n\n      def required_by_validators?\n        (attribute_validators + reflection_validators).any? { |v| v.kind == :presence && valid_validator?(v) }\n      end\n\n      def required_by_default?\n        SimpleForm.required_by_default\n      end\n\n      # Do not use has_required? because we want to add the class\n      # regardless of the required option.\n      def required_class\n        required_field? ? :required : :optional\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers/validators.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Helpers\n    module Validators\n      def has_validators?\n        @has_validators ||= attribute_name && object.class.respond_to?(:validators_on)\n      end\n\n      private\n\n      def attribute_validators\n        object.class.validators_on(attribute_name)\n      end\n\n      def reflection_validators\n        reflection ? object.class.validators_on(reflection.name) : []\n      end\n\n      def valid_validator?(validator)\n        !conditional_validators?(validator) && action_validator_match?(validator)\n      end\n\n      def conditional_validators?(validator)\n        validator.options.include?(:if) || validator.options.include?(:unless)\n      end\n\n      def action_validator_match?(validator)\n        return true unless validator.options.include?(:on)\n\n        case validator.options[:on]\n        when :save\n          true\n        when :create\n          !object.persisted?\n        when :update\n          object.persisted?\n        end\n      end\n\n      def find_validator(kind)\n        attribute_validators.find { |v| v.kind == kind } if has_validators?\n      end\n\n      # Implements `ActiveModel::Validations::ResolveValue`, introduced by Rails 7.1.\n      # https://github.com/rails/rails/blob/v7.1.0/activemodel/lib/active_model/validations/resolve_value.rb\n      def resolve_validator_value(value)\n        case value\n        when Proc\n          if value.arity == 0\n            value.call\n          else\n            value.call(object)\n          end\n        when Symbol\n          object.send(value)\n        else\n          if value.respond_to?(:call)\n            value.call(object)\n          else\n            value\n          end\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/helpers.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  # Helpers are made of several helpers that cannot be turned on automatically.\n  # For instance, disabled cannot be turned on automatically, it requires the\n  # user to explicitly pass the option disabled: true so it may work.\n  module Helpers\n    autoload :Autofocus,  'simple_form/helpers/autofocus'\n    autoload :Disabled,   'simple_form/helpers/disabled'\n    autoload :Readonly,   'simple_form/helpers/readonly'\n    autoload :Required,   'simple_form/helpers/required'\n    autoload :Validators, 'simple_form/helpers/validators'\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/base.rb",
    "content": "# frozen_string_literal: true\nrequire 'active_support/core_ext/string/output_safety'\nrequire 'action_view/helpers'\n\nmodule SimpleForm\n  module Inputs\n    class Base\n      include ERB::Util\n      include ActionView::Helpers::TranslationHelper\n\n      include SimpleForm::Helpers::Autofocus\n      include SimpleForm::Helpers::Disabled\n      include SimpleForm::Helpers::Readonly\n      include SimpleForm::Helpers::Required\n      include SimpleForm::Helpers::Validators\n\n      include SimpleForm::Components::Errors\n      include SimpleForm::Components::Hints\n      include SimpleForm::Components::HTML5\n      include SimpleForm::Components::LabelInput\n      include SimpleForm::Components::Maxlength\n      include SimpleForm::Components::Minlength\n      include SimpleForm::Components::MinMax\n      include SimpleForm::Components::Pattern\n      include SimpleForm::Components::Placeholders\n      include SimpleForm::Components::Readonly\n\n      attr_reader :attribute_name, :column, :input_type, :reflection,\n                  :options, :input_html_options, :input_html_classes, :html_classes\n\n      delegate :template, :object, :object_name, :lookup_model_names, :lookup_action, to: :@builder\n\n      class_attribute :default_options\n      self.default_options = {}\n\n      def self.enable(*keys)\n        options = self.default_options.dup\n        keys.each { |key| options.delete(key) }\n        self.default_options = options\n      end\n\n      def self.disable(*keys)\n        options = self.default_options.dup\n        keys.each { |key| options[key] = false }\n        self.default_options = options\n      end\n\n      # Always enabled.\n      enable :hint\n\n      # Usually disabled, needs to be enabled explicitly passing true as option.\n      disable :maxlength, :minlength, :placeholder, :pattern, :min_max\n\n      def initialize(builder, attribute_name, column, input_type, options = {})\n        super\n\n        options         = options.dup\n        @builder        = builder\n        @attribute_name = attribute_name\n        @column         = column\n        @input_type     = input_type\n        @reflection     = options.delete(:reflection)\n        @options        = options.reverse_merge!(self.class.default_options)\n        @required       = calculate_required\n\n        # Notice that html_options_for receives a reference to input_html_classes.\n        # This means that classes added dynamically to input_html_classes will\n        # still propagate to input_html_options.\n        @html_classes = SimpleForm.additional_classes_for(:input) { additional_classes }\n\n        @input_html_classes = @html_classes.dup\n\n        input_html_classes = self.input_html_classes\n\n        if SimpleForm.input_class && input_html_classes.any?\n          input_html_classes << SimpleForm.input_class\n        end\n\n        @input_html_options = html_options_for(:input, input_html_classes).tap do |o|\n          o[:readonly]  = true if has_readonly?\n          o[:disabled]  = true if has_disabled?\n          o[:autofocus] = true if has_autofocus?\n        end\n      end\n\n      def input(wrapper_options = nil)\n        raise NotImplementedError\n      end\n\n      def input_options\n        options\n      end\n\n      def additional_classes\n        @additional_classes ||= [input_type, required_class, readonly_class, disabled_class].compact\n      end\n\n      def input_class\n        \"#{lookup_model_names.join('_')}_#{reflection_or_attribute_name}\"\n      end\n\n      private\n\n      def limit\n        if column\n          decimal_or_float? ? decimal_limit : column_limit\n        end\n      end\n\n      def column_limit\n        column.limit\n      end\n\n      # Add one for decimal point\n      def decimal_limit\n        column_limit && (column_limit + 1)\n      end\n\n      def decimal_or_float?\n        column.type == :float || column.type == :decimal\n      end\n\n      def nested_boolean_style?\n        options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested\n      end\n\n      # Find reflection name when available, otherwise use attribute\n      def reflection_or_attribute_name\n        @reflection_or_attribute_name ||= reflection ? reflection.name : attribute_name\n      end\n\n      # Retrieve options for the given namespace from the options hash\n      def html_options_for(namespace, css_classes)\n        html_options = options[:\"#{namespace}_html\"]\n        html_options = html_options ? html_options.dup : {}\n        css_classes << html_options[:class] if html_options.key?(:class)\n        html_options[:class] = css_classes unless css_classes.empty?\n        html_options\n      end\n\n      # Lookup translations for the given namespace using I18n, based on object name,\n      # actual action and attribute name. Lookup priority as follows:\n      #\n      #   simple_form.{namespace}.{model}.{action}.{attribute}\n      #   simple_form.{namespace}.{model}.{attribute}\n      #   simple_form.{namespace}.defaults.{attribute}\n      #\n      #  Namespace is used for :labels and :hints.\n      #\n      #  Model is the actual object name, for a @user object you'll have :user.\n      #  Action is the action being rendered, usually :new or :edit.\n      #  And attribute is the attribute itself, :name for example.\n      #\n      #  The lookup for nested attributes is also done in a nested format using\n      #  both model and nested object names, such as follow:\n      #\n      #   simple_form.{namespace}.{model}.{nested}.{action}.{attribute}\n      #   simple_form.{namespace}.{model}.{nested}.{attribute}\n      #   simple_form.{namespace}.{nested}.{action}.{attribute}\n      #   simple_form.{namespace}.{nested}.{attribute}\n      #   simple_form.{namespace}.defaults.{attribute}\n      #\n      #  Example:\n      #\n      #    simple_form:\n      #      labels:\n      #        user:\n      #          new:\n      #            email: 'E-mail para efetuar o sign in.'\n      #          edit:\n      #            email: 'E-mail.'\n      #\n      #  Take a look at our locale example file.\n      def translate_from_namespace(namespace, default = '')\n        model_names = lookup_model_names.dup\n        lookups     = []\n\n        while !model_names.empty?\n          joined_model_names = model_names.join(\".\")\n          model_names.shift\n\n          lookups << :\"#{joined_model_names}.#{lookup_action}.#{reflection_or_attribute_name}\"\n          lookups << :\"#{joined_model_names}.#{reflection_or_attribute_name}\"\n        end\n        lookups << :\"defaults.#{lookup_action}.#{reflection_or_attribute_name}\"\n        lookups << :\"defaults.#{reflection_or_attribute_name}\"\n        lookups << default\n\n        I18n.t(lookups.shift, scope: :\"#{i18n_scope}.#{namespace}\", default: lookups).presence\n      end\n\n      def merge_wrapper_options(options, wrapper_options)\n        if wrapper_options\n          wrapper_options = set_input_classes(wrapper_options)\n\n          wrapper_options.merge(options) do |key, oldval, newval|\n            case key.to_s\n            when \"class\"\n              Array(oldval) + Array(newval)\n            when \"data\", \"aria\"\n              oldval.merge(newval)\n            else\n              newval\n            end\n          end\n        else\n          options\n        end\n      end\n\n      def set_input_classes(wrapper_options)\n        wrapper_options = wrapper_options.dup\n        error_class     = wrapper_options.delete(:error_class)\n        valid_class     = wrapper_options.delete(:valid_class)\n\n        if error_class.present? && has_errors?\n          wrapper_options[:class] = \"#{wrapper_options[:class]} #{error_class}\"\n        end\n\n        if valid_class.present? && valid?\n          wrapper_options[:class] = \"#{wrapper_options[:class]} #{valid_class}\"\n        end\n\n        wrapper_options\n      end\n\n      def i18n_scope\n        SimpleForm.i18n_scope\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/block_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class BlockInput < Base\n      def initialize(*args, &block)\n        super\n        @block = block\n      end\n\n      def input(wrapper_options = nil)\n        template.capture(&@block)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/boolean_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class BooleanInput < Base\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        if nested_boolean_style?\n          build_hidden_field_for_checkbox +\n            template.label_tag(nil, class: boolean_label_class) {\n              build_check_box_without_hidden_field(merged_input_options) +\n                inline_label\n            }\n        else\n          if include_hidden?\n            build_check_box(unchecked_value, merged_input_options)\n          else\n            build_check_box_without_hidden_field(merged_input_options)\n          end\n        end\n      end\n\n      def label_input(wrapper_options = nil)\n        if options[:label] == false || inline_label?\n          input(wrapper_options)\n        elsif nested_boolean_style?\n          html_options = label_html_options.dup\n          html_options[:class] ||= []\n          html_options[:class].push(boolean_label_class) if boolean_label_class\n\n          merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n          build_hidden_field_for_checkbox +\n            @builder.label(label_target, html_options) {\n              build_check_box_without_hidden_field(merged_input_options) + label_text\n            }\n        else\n          input(wrapper_options) + label(wrapper_options)\n        end\n      end\n\n      private\n\n      def boolean_label_class\n        options[:boolean_label_class] || SimpleForm.boolean_label_class\n      end\n\n      # Build a checkbox tag using default unchecked value. This allows us to\n      # reuse the method for nested boolean style, but with no unchecked value,\n      # which won't generate the hidden checkbox. This is the default functionality\n      # in Rails > 3.2.1, and is backported in SimpleForm AV helpers.\n      def build_check_box(unchecked_value, options)\n        @builder.check_box(attribute_name, options, checked_value, unchecked_value)\n      end\n\n      # Build a checkbox without generating the hidden field. See\n      # #build_hidden_field_for_checkbox for more info.\n      def build_check_box_without_hidden_field(options)\n        build_check_box(nil, options)\n      end\n\n      # Create a hidden field for the current checkbox, so we can simulate Rails\n      # functionality with hidden + checkbox, but under a nested context, where\n      # we need the hidden field to be *outside* the label (otherwise it\n      # generates invalid html - html5 only).\n      def build_hidden_field_for_checkbox\n        return \"\".html_safe if !include_hidden? || !unchecked_value\n        options = { value: unchecked_value, id: nil, disabled: input_html_options[:disabled] }\n        options[:name] = input_html_options[:name] if input_html_options.key?(:name)\n        options[:form] = input_html_options[:form] if input_html_options.key?(:form)\n\n        @builder.hidden_field(attribute_name, options)\n      end\n\n      def inline_label?\n        nested_boolean_style? && options[:inline_label]\n      end\n\n      def inline_label\n        inline_option = options[:inline_label]\n\n        if inline_option\n          label = inline_option == true ? label_text : html_escape(inline_option)\n          \" #{label}\".html_safe\n        end\n      end\n\n      # Booleans are not required by default because in most of the cases\n      # it makes no sense marking them as required. The only exception is\n      # Terms of Use usually presented at most sites sign up screen.\n      def required_by_default?\n        false\n      end\n\n      def include_hidden?\n        options.fetch(:include_hidden, true)\n      end\n\n      def checked_value\n        options.fetch(:checked_value, '1')\n      end\n\n      def unchecked_value\n        options.fetch(:unchecked_value, '0')\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/collection_check_boxes_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionCheckBoxesInput < CollectionRadioButtonsInput\n      protected\n\n      # Checkbox components do not use the required html tag.\n      # More info: https://github.com/heartcombo/simple_form/issues/340#issuecomment-2871956\n      def has_required?\n        false\n      end\n\n      def build_nested_boolean_style_item_tag(collection_builder)\n        collection_builder.check_box + collection_builder.text.to_s\n      end\n\n      def item_wrapper_class\n        \"checkbox\"\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/collection_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionInput < Base\n      BASIC_OBJECT_CLASSES = [String, Integer, Float, NilClass, Symbol, TrueClass, FalseClass]\n      BASIC_OBJECT_CLASSES.push(Fixnum, Bignum) unless 1.class == Integer\n\n      # Default boolean collection for use with selects/radios when no\n      # collection is given. Always fallback to this boolean collection.\n      # Texts can be translated using i18n in \"simple_form.yes\" and\n      # \"simple_form.no\" keys. See the example locale file.\n      def self.boolean_collection\n        [ [I18n.t(:\"simple_form.yes\", default: 'Yes'), true],\n          [I18n.t(:\"simple_form.no\", default: 'No'), false] ]\n      end\n\n      def input(wrapper_options = nil)\n        raise NotImplementedError,\n          \"input should be implemented by classes inheriting from CollectionInput\"\n      end\n\n      def input_options\n        options = super\n\n        options[:include_blank] = true unless skip_include_blank?\n        translate_option options, :prompt\n        translate_option options, :include_blank\n\n        options\n      end\n\n      private\n\n      def collection\n        @collection ||= begin\n          collection = options.delete(:collection) || self.class.boolean_collection\n          collection.respond_to?(:call) ? collection.call : collection.to_a\n        end\n      end\n\n      def has_required?\n        super && (input_options[:include_blank] || input_options[:prompt].present? || multiple?)\n      end\n\n      # Check if :include_blank must be included by default.\n      def skip_include_blank?\n        (options.keys & %i[prompt include_blank default selected]).any? || multiple?\n      end\n\n      def multiple?\n        !!options[:input_html].try(:[], :multiple)\n      end\n\n      # Detect the right method to find the label and value for a collection.\n      # If no label or value method are defined, will attempt to find them based\n      # on default label and value methods that can be configured through\n      # SimpleForm.collection_label_methods and\n      # SimpleForm.collection_value_methods.\n      def detect_collection_methods\n        label, value = options.delete(:label_method), options.delete(:value_method)\n\n        unless label && value\n          common_method_for = detect_common_display_methods\n          label ||= common_method_for[:label]\n          value ||= common_method_for[:value]\n        end\n\n        [label, value]\n      end\n\n      def detect_common_display_methods(collection_classes = detect_collection_classes)\n        collection_translated = translate_collection if collection_classes == [Symbol]\n\n        if collection_translated || collection_classes.include?(Array)\n          { label: :first, value: :second }\n        elsif collection_includes_basic_objects?(collection_classes)\n          { label: :to_s, value: :to_s }\n        else\n          detect_method_from_class(collection_classes)\n        end\n      end\n\n      def detect_method_from_class(collection_classes)\n        sample = collection.first || collection.last\n\n        { label: SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },\n          value: SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }\n      end\n\n      def detect_collection_classes(some_collection = collection)\n        some_collection.map(&:class).uniq\n      end\n\n      def collection_includes_basic_objects?(collection_classes)\n        (collection_classes & BASIC_OBJECT_CLASSES).any?\n      end\n\n      def translate_collection\n        if translated_collection = translate_from_namespace(:options)\n          @collection = collection.map do |key|\n            html_key = \"#{key}_html\".to_sym\n\n            if translated_collection[html_key]\n              [translated_collection[html_key].html_safe || key, key.to_s]\n            else\n              [translated_collection[key] || key, key.to_s]\n            end\n          end\n          true\n        end\n      end\n\n      def translate_option(options, key)\n        if options[key] == :translate\n          namespace = key.to_s.pluralize\n\n          options[key] = translate_from_namespace(namespace, true)\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/collection_radio_buttons_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionRadioButtonsInput < CollectionInput\n      def input(wrapper_options = nil)\n        label_method, value_method = detect_collection_methods\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.send(:\"collection_#{input_type}\",\n          attribute_name, collection, value_method, label_method,\n          input_options, merged_input_options,\n          &collection_block_for_nested_boolean_style\n        )\n      end\n\n      def input_options\n        options = super\n        apply_default_collection_options!(options)\n        options\n      end\n\n      protected\n\n      def apply_default_collection_options!(options)\n        options[:item_wrapper_tag] ||= options.fetch(:item_wrapper_tag, SimpleForm.item_wrapper_tag)\n        options[:item_wrapper_class] = [\n          item_wrapper_class, options[:item_wrapper_class], SimpleForm.item_wrapper_class\n        ].compact.presence if SimpleForm.include_default_input_wrapper_class\n\n        options[:collection_wrapper_tag] ||= options.fetch(:collection_wrapper_tag, SimpleForm.collection_wrapper_tag)\n        options[:collection_wrapper_class] = [\n          options[:collection_wrapper_class], SimpleForm.collection_wrapper_class\n        ].compact.presence\n      end\n\n      def collection_block_for_nested_boolean_style\n        return unless nested_boolean_style?\n\n        proc { |builder| build_nested_boolean_style_item_tag(builder) }\n      end\n\n      def build_nested_boolean_style_item_tag(collection_builder)\n        collection_builder.radio_button + collection_builder.text.to_s\n      end\n\n      def item_wrapper_class\n        \"radio\"\n      end\n\n      # Do not attempt to generate label[for] attributes by default, unless an\n      # explicit html option is given. This avoids generating labels pointing to\n      # non existent fields.\n      def generate_label_for_attribute?\n        false\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/collection_select_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class CollectionSelectInput < CollectionInput\n      def input(wrapper_options = nil)\n        label_method, value_method = detect_collection_methods\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.collection_select(\n          attribute_name, collection, value_method, label_method,\n          input_options, merged_input_options\n        )\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/color_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class ColorInput < Base\n      def input(wrapper_options = nil)\n        input_html_options[:type] ||= \"color\" if html5?\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.text_field(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/date_time_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class DateTimeInput < Base\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        if use_html5_inputs?\n          @builder.send(:\"#{input_type}_field\", attribute_name, merged_input_options)\n        else\n          @builder.send(:\"#{input_type}_select\", attribute_name, input_options, merged_input_options)\n        end\n      end\n\n      private\n\n      def label_target\n        if use_html5_inputs?\n          attribute_name\n        else\n          position = case input_type\n          when :date, :datetime\n            date_order = input_options[:order] || I18n.t('date.order')\n            date_order.first.to_sym\n          else\n            :hour\n          end\n\n          position = ActionView::Helpers::DateTimeSelector::POSITION[position]\n          \"#{attribute_name}_#{position}i\"\n        end\n      end\n\n      def use_html5_inputs?\n        input_options[:html5]\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/file_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class FileInput < Base\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.file_field(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/grouped_collection_select_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class GroupedCollectionSelectInput < CollectionInput\n      def input(wrapper_options = nil)\n        label_method, value_method = detect_collection_methods\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.grouped_collection_select(attribute_name, grouped_collection,\n                      group_method, group_label_method, value_method, label_method,\n                      input_options, merged_input_options)\n      end\n\n      private\n\n      def grouped_collection\n        @grouped_collection ||= begin\n          grouped_collection = options.delete(:collection)\n          grouped_collection.respond_to?(:call) ? grouped_collection.call : grouped_collection.to_a\n        end\n      end\n\n      # Sample collection\n      def collection\n        @collection ||= grouped_collection.map { |collection| group_method.respond_to?(:call) ? group_method.call(collection) : collection.try(:send, group_method) }.detect(&:present?) || []\n      end\n\n      def group_method\n        @group_method ||= options.delete(:group_method)\n      end\n\n      def group_label_method\n        label = options.delete(:group_label_method)\n\n        unless label\n          common_method_for = detect_common_display_methods(detect_collection_classes(grouped_collection))\n          label = common_method_for[:label]\n        end\n\n        label\n      end\n\n      def detect_method_from_class(collection_classes)\n        return {} if collection_classes.empty?\n\n        sample = collection_classes.first\n\n        { label: SimpleForm.collection_label_methods.find { |m| sample.instance_methods.include?(m) },\n          value: SimpleForm.collection_value_methods.find { |m| sample.instance_methods.include?(m) } }\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/hidden_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class HiddenInput < Base\n      disable :label, :errors, :hint, :required\n\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.hidden_field(attribute_name, merged_input_options)\n      end\n\n      private\n\n      def required_class\n        nil\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/numeric_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class NumericInput < Base\n      enable :placeholder, :min_max\n\n      def input(wrapper_options = nil)\n        input_html_classes.unshift(\"numeric\")\n        if html5?\n          input_html_options[:type] ||= \"number\"\n          input_html_options[:step] ||= integer? ? 1 : \"any\"\n        end\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.text_field(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/password_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class PasswordInput < Base\n      enable :placeholder, :maxlength, :minlength\n\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.password_field(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/priority_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class PriorityInput < CollectionSelectInput\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        send(:\"#{input_type}_input\", merged_input_options)\n      end\n\n      def input_priority\n        options[:priority] || SimpleForm.send(:\"#{input_type}_priority\")\n      end\n\n      protected\n\n      def country_input(merged_input_options)\n        @builder.send(:country_select,\n                      attribute_name,\n                      input_options.merge(priority_countries: input_priority),\n                      merged_input_options)\n      end\n\n      def time_zone_input(merged_input_options)\n        @builder.send(:time_zone_select,\n                      attribute_name,\n                      input_priority,\n                      input_options,\n                      merged_input_options)\n      end\n\n      def skip_include_blank?\n        super || input_priority.present?\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/range_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class RangeInput < NumericInput\n      def input(wrapper_options = nil)\n        if html5?\n          input_html_options[:type] ||= \"range\"\n          input_html_options[:step] ||= 1\n        end\n\n        super\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/rich_text_area_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class RichTextAreaInput < Base\n      enable :placeholder\n\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.rich_text_area(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/string_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class StringInput < Base\n      enable :placeholder, :maxlength, :minlength, :pattern\n\n      def input(wrapper_options = nil)\n        unless string?\n          input_html_classes.unshift(\"string\")\n          input_html_options[:type] ||= input_type if html5?\n        end\n\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.text_field(attribute_name, merged_input_options)\n      end\n\n      private\n\n      def string?\n        input_type == :string || input_type == :citext\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/text_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class TextInput < Base\n      enable :placeholder, :maxlength, :minlength\n\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.text_area(attribute_name, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs/weekday_input.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    class WeekdayInput < CollectionSelectInput\n      enable :placeholder\n\n      def input(wrapper_options = nil)\n        merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)\n\n        @builder.weekday_select(attribute_name, input_options, merged_input_options)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/inputs.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Inputs\n    extend ActiveSupport::Autoload\n\n    autoload :Base\n    autoload :BlockInput\n    autoload :BooleanInput\n    autoload :CollectionCheckBoxesInput\n    autoload :CollectionInput\n    autoload :CollectionRadioButtonsInput\n    autoload :CollectionSelectInput\n    autoload :ColorInput\n    autoload :DateTimeInput\n    autoload :FileInput\n    autoload :GroupedCollectionSelectInput\n    autoload :HiddenInput\n    autoload :NumericInput\n    autoload :PasswordInput\n    autoload :PriorityInput\n    autoload :RangeInput\n    autoload :RichTextAreaInput\n    autoload :StringInput\n    autoload :TextInput\n    autoload :WeekdayInput\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/map_type.rb",
    "content": "# frozen_string_literal: true\nrequire 'active_support/core_ext/class/attribute'\n\nmodule SimpleForm\n  module MapType\n    def self.extended(base)\n      base.class_attribute :mappings\n      base.mappings = {}\n    end\n\n    def map_type(*types)\n      map_to = types.extract_options![:to]\n      raise ArgumentError, \"You need to give :to as option to map_type\" unless map_to\n      self.mappings = mappings.merge types.each_with_object({}) { |t, m| m[t] = map_to }\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/railtie.rb",
    "content": "# frozen_string_literal: true\nrequire 'rails/railtie'\n\nmodule SimpleForm\n  class Railtie < Rails::Railtie\n    config.eager_load_namespaces << SimpleForm\n\n    config.after_initialize do\n      unless SimpleForm.configured?\n        warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +\n          ' Use `rails generate simple_form:install` to generate the Simple Form configuration.'\n      end\n    end\n\n    initializer \"simple_form.deprecator\" do |app|\n      app.deprecators[:simple_form] = SimpleForm.deprecator if app.respond_to?(:deprecators)\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/tags.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Tags\n    module CollectionExtensions\n      private\n\n      def render_collection\n        item_wrapper_tag   = @options.fetch(:item_wrapper_tag, :span)\n        item_wrapper_class = @options[:item_wrapper_class]\n\n        @collection.map do |item|\n          value = value_for_collection(item, @value_method)\n          text  = value_for_collection(item, @text_method)\n          default_html_options = default_html_options_for_collection(item, value)\n          additional_html_options = option_html_attributes(item)\n\n          rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)\n\n          if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested\n            label_options = default_html_options.slice(:index, :namespace)\n            label_options['class'] = @options[:item_label_class]\n            rendered_item = @template_object.label(@object_name, sanitize_attribute_name(value), rendered_item, label_options)\n          end\n\n          item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item\n        end.join.html_safe\n      end\n\n      def wrap_rendered_collection(collection)\n        wrapper_tag = @options[:collection_wrapper_tag]\n\n        if wrapper_tag\n          wrapper_class = @options[:collection_wrapper_class]\n          @template_object.content_tag(wrapper_tag, collection, class: wrapper_class)\n        else\n          collection\n        end\n      end\n    end\n\n    class CollectionRadioButtons < ActionView::Helpers::Tags::CollectionRadioButtons\n      include CollectionExtensions\n\n      def render\n        wrap_rendered_collection(super)\n      end\n\n      private\n\n      def render_component(builder)\n        label_class = \"#{@options[:item_label_class]} collection_radio_buttons\".strip\n\n        builder.radio_button + builder.label(class: label_class)\n      end\n    end\n\n    class CollectionCheckBoxes < ActionView::Helpers::Tags::CollectionCheckBoxes\n      include CollectionExtensions\n\n      def render\n        wrap_rendered_collection(super)\n      end\n\n      private\n\n      def render_component(builder)\n        label_class = \"#{@options[:item_label_class]} collection_check_boxes\".strip\n\n        builder.check_box + builder.label(class: label_class)\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/version.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  VERSION = \"5.4.1\".freeze\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/builder.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # Provides the builder syntax for components. The builder provides\n    # three methods `use`, `optional` and `wrapper` and they allow the following invocations:\n    #\n    #     config.wrappers do |b|\n    #       # Use a single component\n    #       b.use :html5\n    #\n    #       # Use the component, but do not automatically lookup. It will only be triggered when\n    #       # :placeholder is explicitly set.\n    #       b.optional :placeholder\n    #\n    #       # Use a component with specific wrapper options\n    #       b.use :error, wrap_with: { tag: \"span\", class: \"error\" }\n    #\n    #       # Use a set of components by wrapping them in a tag+class.\n    #       b.wrapper tag: \"div\", class: \"another\" do |ba|\n    #         ba.use :label\n    #         ba.use :input\n    #       end\n    #\n    #       # Use a set of components by wrapping them in a tag+class.\n    #       # This wrapper is identified by :label_input, which means it can\n    #       # be turned off on demand with `f.input :name, label_input: false`\n    #       b.wrapper :label_input, tag: \"div\", class: \"another\" do |ba|\n    #         ba.use :label\n    #         ba.use :input\n    #       end\n    #     end\n    #\n    # The builder also accepts default options at the root level. This is usually\n    # used if you want a component to be disabled by default:\n    #\n    #     config.wrappers hint: false do |b|\n    #       b.use :hint\n    #       b.use :label_input\n    #     end\n    #\n    # In the example above, hint defaults to false, which means it won't automatically\n    # do the lookup anymore. It will only be triggered when :hint is explicitly set.\n    class Builder\n      def initialize(options)\n        @options    = options\n        @components = []\n      end\n\n      def use(name, options = {})\n        if options && wrapper = options[:wrap_with]\n          @components << Single.new(name, wrapper, options.except(:wrap_with))\n        else\n          @components << Leaf.new(name, options)\n        end\n      end\n\n      def optional(name, options = {}, &block)\n        @options[name] = false\n        use(name, options)\n      end\n\n      def wrapper(name, options = nil)\n        if block_given?\n          name, options = nil, name if name.is_a?(Hash)\n          builder = self.class.new(@options)\n          options ||= {}\n          options[:tag] = :div if options[:tag].nil?\n          yield builder\n          @components << Many.new(name, builder.to_a, options)\n        else\n          raise ArgumentError, \"A block is required as argument to wrapper\"\n        end\n      end\n\n      def to_a\n        @components\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/leaf.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    class Leaf\n      attr_reader :namespace\n\n      def initialize(namespace, options = {})\n        @namespace = namespace\n        @options = options\n      end\n\n      def render(input)\n        method = input.method(@namespace)\n\n        if method.arity.zero?\n          SimpleForm.deprecator.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })\n\n          method.call\n        else\n          method.call(@options)\n        end\n      end\n\n      def find(name)\n        self if @namespace == name\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/many.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # A wrapper is an object that holds several components and render them.\n    # A component may be any object that responds to `render`.\n    # This API allows inputs/components to be easily wrapped, removing the\n    # need to modify the code only to wrap input in an extra tag.\n    #\n    # `Many` represents a wrapper around several components at the same time.\n    # It may optionally receive a namespace, allowing it to be configured\n    # on demand on input generation.\n    class Many\n      attr_reader :namespace, :defaults, :components\n\n      def initialize(namespace, components, defaults = {})\n        @namespace  = namespace\n        @components = components\n        @defaults   = defaults\n        @defaults[:tag]   = :div unless @defaults.key?(:tag)\n        @defaults[:class] = Array(@defaults[:class])\n      end\n\n      def render(input)\n        content = \"\".html_safe\n        options = input.options\n\n        components.each do |component|\n          next if options[component.namespace] == false\n          rendered = component.render(input)\n          content.safe_concat rendered.to_s if rendered\n        end\n\n        wrap(input, options, content)\n      end\n\n      def find(name)\n        return self if namespace == name\n\n        @components.each do |c|\n          if c.is_a?(Symbol)\n            return nil if c == namespace\n          elsif value = c.find(name)\n            return value\n          end\n        end\n\n        nil\n      end\n\n      private\n\n      def wrap(input, options, content)\n        return content if options[namespace] == false\n        return if defaults[:unless_blank] && content.empty?\n\n        tag = (namespace && options[:\"#{namespace}_tag\"]) || @defaults[:tag]\n        return content unless tag\n\n        klass = html_classes(input, options)\n        opts  = html_options(options)\n        opts[:class] = (klass << opts[:class]).join(' ').strip unless klass.empty?\n        input.template.content_tag(tag, content, opts)\n      end\n\n      def html_options(options)\n        (@defaults[:html] || {}).merge(options[:\"#{namespace}_html\"] || {})\n      end\n\n      def html_classes(input, options)\n        @defaults[:class].dup\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/root.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # `Root` is the root wrapper for all components. It is special cased to\n    # always have a namespace and to add special html classes.\n    class Root < Many\n      attr_reader :options\n\n      def initialize(*args)\n        super(:wrapper, *args)\n        @options = @defaults.except(:tag, :class, :error_class, :hint_class)\n      end\n\n      def render(input)\n        input.options.reverse_merge!(@options)\n        super\n      end\n\n      # Provide a fallback if name cannot be found.\n      def find(name)\n        super || SimpleForm::Wrappers::Many.new(name, [Leaf.new(name)])\n      end\n\n      private\n\n      def html_classes(input, options)\n        css = options[:wrapper_class] ? Array(options[:wrapper_class]) : @defaults[:class]\n        css += SimpleForm.additional_classes_for(:wrapper) do\n          input.additional_classes + [input.input_class]\n        end\n        css << html_class(:error_class, options) { input.has_errors? }\n        css << html_class(:hint_class, options) { input.has_hint? }\n        css << html_class(:valid_class, options) { input.valid? }\n        css.compact\n      end\n\n      def html_class(key, options)\n        css = (options[:\"wrapper_#{key}\"] || @defaults[key])\n        css if css && yield\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers/single.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    # `Single` is an optimization for a wrapper that has only one component.\n    class Single < Many\n      def initialize(name, wrapper_options = {}, options = {})\n        @component = Leaf.new(name, options)\n\n        super(name, [@component], wrapper_options)\n      end\n\n      def render(input)\n        options = input.options\n        if options[namespace] != false\n          content = @component.render(input)\n          wrap(input, options, content) if content\n        end\n      end\n\n      private\n\n      def html_options(options)\n        %i[label input].include?(namespace) ? {} : super\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "lib/simple_form/wrappers.rb",
    "content": "# frozen_string_literal: true\nmodule SimpleForm\n  module Wrappers\n    autoload :Builder, 'simple_form/wrappers/builder'\n    autoload :Many,    'simple_form/wrappers/many'\n    autoload :Root,    'simple_form/wrappers/root'\n    autoload :Single,  'simple_form/wrappers/single'\n    autoload :Leaf,    'simple_form/wrappers/leaf'\n  end\nend\n"
  },
  {
    "path": "lib/simple_form.rb",
    "content": "# frozen_string_literal: true\nrequire 'action_view'\nrequire 'action_pack'\nrequire 'simple_form/action_view_extensions/form_helper'\nrequire 'simple_form/action_view_extensions/builder'\nrequire 'active_support/core_ext/hash/slice'\nrequire 'active_support/core_ext/hash/except'\nrequire 'active_support/core_ext/hash/reverse_merge'\n\nmodule SimpleForm\n  extend ActiveSupport::Autoload\n\n  autoload :Helpers\n  autoload :Wrappers\n\n  eager_autoload do\n    autoload :Components\n    autoload :ErrorNotification\n    autoload :FormBuilder\n    autoload :Inputs\n  end\n\n  def self.eager_load!\n    super\n    SimpleForm::Inputs.eager_load!\n    SimpleForm::Components.eager_load!\n  end\n\n  CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN\n%{name} method now accepts a `wrapper_options` argument. The method definition without the argument is deprecated and will be removed in the next Simple Form version. Change your code from:\n\n    def %{name}\n\nto\n\n    def %{name}(wrapper_options)\n\nSee https://github.com/heartcombo/simple_form/pull/997 for more information.\n  WARN\n\n  FILE_METHODS_DEPRECATION_WARN = <<-WARN\n[SIMPLE_FORM] SimpleForm.file_methods is deprecated and has no effect.\n\nSince version 5, Simple Form now supports automatically discover of file inputs for the following Gems: activestorage, carrierwave, paperclip, refile and shrine.\nIf you are using a custom method that is not from one of the supported Gems, please change your forms to pass the input type explicitly:\n\n    <%= form.input :avatar, as: :file %>\n\nSee http://blog.plataformatec.com.br/2019/09/incorrect-access-control-in-simple-form-cve-2019-16676 for more information.\n  WARN\n\n  @@configured = false\n\n  def self.configured? #:nodoc:\n    @@configured\n  end\n\n  def self.deprecator\n    @deprecator ||= ActiveSupport::Deprecation.new(\"5.3\", \"SimpleForm\")\n  end\n\n  ## CONFIGURATION OPTIONS\n\n  # Method used to tidy up errors.\n  mattr_accessor :error_method\n  @@error_method = :first\n\n  # Default tag used for error notification helper.\n  mattr_accessor :error_notification_tag\n  @@error_notification_tag = :p\n\n  # CSS class to add for error notification helper.\n  mattr_accessor :error_notification_class\n  @@error_notification_class = :error_notification\n\n  # Series of attempts to detect a default label method for collection.\n  mattr_accessor :collection_label_methods\n  @@collection_label_methods = %i[to_label name title to_s]\n\n  # Series of attempts to detect a default value method for collection.\n  mattr_accessor :collection_value_methods\n  @@collection_value_methods = %i[id to_s]\n\n  # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.\n  mattr_accessor :collection_wrapper_tag\n  @@collection_wrapper_tag = nil\n\n  # You can define the class to use on all collection wrappers, defaulting to none.\n  mattr_accessor :collection_wrapper_class\n  @@collection_wrapper_class = nil\n\n  # You can wrap each item in a collection of radio/check boxes with a tag,\n  # defaulting to span. Please note that when using :boolean_style = :nested,\n  # SimpleForm will force this option to be a :label.\n  mattr_accessor :item_wrapper_tag\n  @@item_wrapper_tag = :span\n\n  # You can define the class to use on all item wrappers, defaulting to none.\n  mattr_accessor :item_wrapper_class\n  @@item_wrapper_class = nil\n\n  # How the label text should be generated altogether with the required text.\n  mattr_accessor :label_text\n  @@label_text = ->(label, required, explicit_label) { \"#{required} #{label}\" }\n\n  # You can define the class to be used on all labels. Defaults to none.\n  mattr_accessor :label_class\n  @@label_class = nil\n\n  # Define the way to render check boxes / radio buttons with labels.\n  #   inline: input + label (default)\n  #   nested: label > input\n  mattr_accessor :boolean_style\n  @@boolean_style = :inline\n\n  # DEPRECATED: You can define the class to be used on all forms. Default is\n  # simple_form.\n  mattr_reader :form_class\n  @@form_class = :simple_form\n\n  # You can define the default class to be used on all forms. Can be overridden\n  # with `html: { :class }`. Defaults to none.\n  mattr_accessor :default_form_class\n  @@default_form_class = nil\n\n  # You can define which elements should obtain additional classes.\n  mattr_accessor :generate_additional_classes_for\n  @@generate_additional_classes_for = %i[wrapper label input]\n\n  # Whether attributes are required by default or not.\n  mattr_accessor :required_by_default\n  @@required_by_default = true\n\n  # Tell browsers whether to use default HTML5 validations (novalidate option).\n  mattr_accessor :browser_validations\n  @@browser_validations = true\n\n  # Custom mappings for input types. This should be a hash containing a regexp\n  # to match as key, and the input type that will be used when the field name\n  # matches the regexp as value, such as { /count/ => :integer }.\n  mattr_accessor :input_mappings\n  @@input_mappings = nil\n\n  # Custom wrappers for input types. This should be a hash containing an input\n  # type as key and the wrapper that will be used for all inputs with specified type.\n  # e.g { string: :string_wrapper, boolean: :boolean_wrapper }\n  # You can also set a wrapper mapping per form basis.\n  # e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox })\n  mattr_accessor :wrapper_mappings\n  @@wrapper_mappings = nil\n\n  # Namespaces where SimpleForm should look for custom input classes that override\n  # default inputs. Namespaces are given as string to allow lazy loading inputs.\n  # e.g. config.custom_inputs_namespaces << \"CustomInputs\"\n  #      will try to find CustomInputs::NumericInput when an :integer\n  #      field is called.\n  mattr_accessor :custom_inputs_namespaces\n  @@custom_inputs_namespaces = []\n\n  # Default priority for time_zone inputs.\n  mattr_accessor :time_zone_priority\n  @@time_zone_priority = nil\n\n  # Default priority for country inputs.\n  mattr_accessor :country_priority\n  @@country_priority = nil\n\n  # When off, do not use translations in labels. Disabling translation in\n  # hints and placeholders can be done manually in the wrapper API.\n  mattr_accessor :translate_labels\n  @@translate_labels = true\n\n  # Automatically discover new inputs in Rails' autoload path.\n  mattr_accessor :inputs_discovery\n  @@inputs_discovery = true\n\n  # Cache SimpleForm inputs discovery.\n  mattr_accessor :cache_discovery\n  @@cache_discovery = defined?(Rails.env) && !Rails.env.development?\n\n  # Adds a class to each generated button, mostly for compatibility.\n  mattr_accessor :button_class\n  @@button_class = 'button'\n\n  # Override the default ActiveModelHelper behaviour of wrapping the input.\n  # This gets taken care of semantically by adding an error class to the wrapper tag\n  # containing the input.\n  mattr_accessor :field_error_proc\n  @@field_error_proc = proc do |html_tag, instance_tag|\n    html_tag\n  end\n\n  # Adds a class to each generated inputs\n  mattr_accessor :input_class\n  @@input_class = nil\n\n  # Defines if an input wrapper class should be included or not\n  mattr_accessor :include_default_input_wrapper_class\n  @@include_default_input_wrapper_class = true\n\n  # Define the default class of the input wrapper of the boolean input.\n  mattr_accessor :boolean_label_class\n  @@boolean_label_class = 'checkbox'\n\n  ## WRAPPER CONFIGURATION\n  # The default wrapper to be used by the FormBuilder.\n  mattr_accessor :default_wrapper\n  @@default_wrapper = :default\n  @@wrappers = {} #:nodoc:\n\n  mattr_accessor :i18n_scope\n  @@i18n_scope = 'simple_form'\n\n  mattr_accessor :input_field_error_class\n  @@input_field_error_class = nil\n\n  mattr_accessor :input_field_valid_class\n  @@input_field_valid_class = nil\n\n  # Retrieves a given wrapper\n  def self.wrapper(name)\n    @@wrappers[name.to_s] or raise WrapperNotFound, \"Couldn't find wrapper with name #{name}\"\n  end\n\n  # Raised when fails to find a given wrapper name\n  class WrapperNotFound < StandardError\n  end\n\n  # Define a new wrapper using SimpleForm::Wrappers::Builder\n  # and store it in the given name.\n  def self.wrappers(*args, &block)\n    if block_given?\n      options                 = args.extract_options!\n      name                    = args.first || :default\n      @@wrappers[name.to_s]   = build(options, &block)\n    else\n      @@wrappers\n    end\n  end\n\n  # Builds a new wrapper using SimpleForm::Wrappers::Builder.\n  def self.build(options = {})\n    options[:tag] = :div if options[:tag].nil?\n    builder = SimpleForm::Wrappers::Builder.new(options)\n    yield builder\n    SimpleForm::Wrappers::Root.new(builder.to_a, options)\n  end\n\n  wrappers class: :input, hint_class: :field_with_hint, error_class: :field_with_errors, valid_class: :field_without_errors do |b|\n    b.use :html5\n\n    b.use :min_max\n    b.use :maxlength\n    b.use :minlength\n    b.use :placeholder\n    b.optional :pattern\n    b.optional :readonly\n\n    b.use :label_input\n    b.use :hint,  wrap_with: { tag: :span, class: :hint }\n    b.use :error, wrap_with: { tag: :span, class: :error }\n  end\n\n  def self.additional_classes_for(component)\n    generate_additional_classes_for.include?(component) ? yield : []\n  end\n\n  ## SETUP\n\n  def self.default_input_size=(*)\n    SimpleForm.deprecator.warn \"[SIMPLE_FORM] SimpleForm.default_input_size= is deprecated and has no effect\", caller\n  end\n\n  def self.form_class=(value)\n    SimpleForm.deprecator.warn \"[SIMPLE_FORM] SimpleForm.form_class= is deprecated and will be removed in 4.x. Use SimpleForm.default_form_class= instead\", caller\n    @@form_class = value\n  end\n\n  def self.file_methods=(file_methods)\n    SimpleForm.deprecator.warn(FILE_METHODS_DEPRECATION_WARN, caller)\n    @@file_methods = file_methods\n  end\n\n  def self.file_methods\n    SimpleForm.deprecator.warn(FILE_METHODS_DEPRECATION_WARN, caller)\n    @@file_methods\n  end\n\n  # Default way to setup Simple Form. Run rails generate simple_form:install\n  # to create a fresh initializer with all configuration values.\n  def self.setup\n    @@configured = true\n    yield self\n  end\n\n  # Includes a component to be used by Simple Form. Methods defined in a\n  # component will be exposed to be used in the wrapper as Simple::Components\n  #\n  # Examples\n  #\n  #    # The application needs to tell where the components will be.\n  #    Dir[Rails.root.join('lib/components/**/*.rb')].each { |f| require f }\n  #\n  #    # Create a custom component in the path specified above.\n  #    # lib/components/input_group_component.rb\n  #    module InputGroupComponent\n  #      def prepend\n  #        ...\n  #      end\n  #\n  #      def append\n  #        ...\n  #      end\n  #    end\n  #\n  #    SimpleForm.setup do |config|\n  #      # Create a wrapper using the custom component.\n  #      config.wrappers :input_group, tag: :div, error_class: :error do |b|\n  #        b.use :label\n  #        b.optional :prepend\n  #        b.use :input\n  #        b.use :append\n  #      end\n  #    end\n  #\n  #    # Using the custom component in the form.\n  #    <%= simple_form_for @blog, wrapper: input_group do |f| %>\n  #      <%= f.input :title, prepend: true %>\n  #    <% end %>\n  #\n  def self.include_component(component)\n    if Module === component\n      SimpleForm::Inputs::Base.include(component)\n    else\n      raise TypeError, \"SimpleForm.include_component expects a module but got: #{component.class}\"\n    end\n  end\nend\n\nrequire 'simple_form/railtie' if defined?(Rails)\n"
  },
  {
    "path": "simple_form.gemspec",
    "content": "# -*- encoding: utf-8 -*-\n$:.push File.expand_path(\"../lib\", __FILE__)\nrequire \"simple_form/version\"\n\nGem::Specification.new do |s|\n  s.name        = \"simple_form\"\n  s.version     = SimpleForm::VERSION.dup\n  s.platform    = Gem::Platform::RUBY\n  s.summary     = \"Forms made easy!\"\n  s.email       = \"heartcombo.oss@gmail.com\"\n  s.homepage    = \"https://github.com/heartcombo/simple_form\"\n  s.description = \"Forms made easy!\"\n  s.authors     = ['José Valim', 'Carlos Antonio', 'Rafael França']\n  s.license     = \"MIT\"\n  s.metadata    = {\n    \"homepage_uri\"      => \"https://github.com/heartcombo/simple_form\",\n    \"documentation_uri\" => \"https://rubydoc.info/github/heartcombo/simple_form\",\n    \"changelog_uri\"     => \"https://github.com/heartcombo/simple_form/blob/main/CHANGELOG.md\",\n    \"source_code_uri\"   => \"https://github.com/heartcombo/simple_form\",\n    \"bug_tracker_uri\"   => \"https://github.com/heartcombo/simple_form/issues\",\n    \"wiki_uri\"          => \"https://github.com/heartcombo/simple_form/wiki\"\n  }\n\n  s.files         = Dir[\"CHANGELOG.md\", \"MIT-LICENSE\", \"README.md\", \"lib/**/*\"]\n  s.require_paths = [\"lib\"]\n\n  s.required_ruby_version = \">= 2.7.0\"\n\n  s.add_dependency \"activemodel\", \">= 7.0\"\n  s.add_dependency \"actionpack\", \">= 7.0\"\n\n  s.add_development_dependency \"country_select\"\n  s.add_development_dependency \"minitest\", \"< 6\"\n  s.add_development_dependency \"rake\"\n  s.add_development_dependency \"rdoc\"\nend\n"
  },
  {
    "path": "test/action_view_extensions/builder_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass BuilderTest < ActionView::TestCase\n  def with_custom_form_for(object, *args, &block)\n    with_concat_custom_form_for(object) do |f|\n      assert f.instance_of?(CustomFormBuilder)\n      yield f\n    end\n  end\n\n  def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)\n    with_concat_form_for(object) do |f|\n      f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block\n    end\n  end\n\n  def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)\n    with_concat_form_for(object) do |f|\n      f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block\n    end\n  end\n\n  # COLLECTION RADIO\n  test \"collection radio accepts a collection and generate inputs from value method\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=radio][value=true]#user_active_true'\n    assert_select 'form input[type=radio][value=false]#user_active_false'\n  end\n\n  test \"collection radio accepts a collection and generate inputs from label method\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form label.collection_radio_buttons[for=user_active_true]', 'true'\n    assert_select 'form label.collection_radio_buttons[for=user_active_false]', 'false'\n  end\n\n  test \"collection radio handles camelized collection values for labels correctly\" do\n    with_collection_radio_buttons @user, :active, %w[Yes No], :to_s, :to_s\n\n    assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'\n    assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'\n  end\n\n  test \"collection radio sanitizes collection values for labels correctly\" do\n    with_collection_radio_buttons @user, :name, ['$0.99', '$1.99'], :to_s, :to_s\n\n    assert_select 'label.collection_radio_buttons[for=user_name_0_99]', '$0.99'\n    assert_select 'label.collection_radio_buttons[for=user_name_1_99]', '$1.99'\n  end\n\n  test \"collection radio checks the correct value to local variables\" do\n    user = User.build(active: false)\n    with_collection_radio_buttons user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=radio][value=true]'\n    assert_select 'form input[type=radio][value=false][checked=checked]'\n  end\n\n  test \"collection radio accepts checked item\" do\n    with_collection_radio_buttons @user, :active, [[1, true], [0, false]], :last, :first, checked: true\n\n    assert_select 'form input[type=radio][value=true][checked=checked]'\n    assert_no_select 'form input[type=radio][value=false][checked=checked]'\n  end\n\n  test \"collection radio accepts checked item which has a value of false\" do\n    with_collection_radio_buttons @user, :active, [[1, true], [0, false]], :last, :first, checked: false\n    assert_no_select 'form input[type=radio][value=true][checked=checked]'\n    assert_select 'form input[type=radio][value=false][checked=checked]'\n  end\n\n  test \"collection radio accepts multiple disabled items\" do\n    collection = [[1, true], [0, false], [2, 'other']]\n    with_collection_radio_buttons @user, :active, collection, :last, :first, disabled: [true, false]\n\n    assert_select 'form input[type=radio][value=true][disabled=disabled]'\n    assert_select 'form input[type=radio][value=false][disabled=disabled]'\n    assert_no_select 'form input[type=radio][value=other][disabled=disabled]'\n  end\n\n  test \"collection radio accepts single disable item\" do\n    collection = [[1, true], [0, false]]\n    with_collection_radio_buttons @user, :active, collection, :last, :first, disabled: true\n\n    assert_select 'form input[type=radio][value=true][disabled=disabled]'\n    assert_no_select 'form input[type=radio][value=false][disabled=disabled]'\n  end\n\n  test \"collection radio accepts html options as input\" do\n    collection = [[1, true], [0, false]]\n    with_collection_radio_buttons @user, :active, collection, :last, :first, {}, class: 'special-radio'\n\n    assert_select 'form input[type=radio][value=true].special-radio#user_active_true'\n    assert_select 'form input[type=radio][value=false].special-radio#user_active_false'\n  end\n\n  test \"collection radio wraps the collection in the given collection wrapper tag\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: :ul\n\n    assert_select 'form ul input[type=radio]', count: 2\n  end\n\n  test \"collection radio does not render any wrapper tag by default\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=radio]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test \"collection radio does not wrap the collection when given falsy values\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: false\n\n    assert_select 'form input[type=radio]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test \"collection radio uses the given class for collection wrapper tag\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,\n      collection_wrapper_tag: :ul, collection_wrapper_class: \"items-list\"\n\n    assert_select 'form ul.items-list input[type=radio]', count: 2\n  end\n\n  test \"collection radio uses no class for collection wrapper tag when no wrapper tag is given\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,\n      collection_wrapper_class: \"items-list\"\n\n    assert_select 'form input[type=radio]', count: 2\n    assert_no_select 'form ul'\n    assert_no_select '.items-list'\n  end\n\n  test \"collection radio uses no class for collection wrapper tag by default\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: :ul\n\n    assert_select 'form ul'\n    assert_no_select 'form ul[class]'\n  end\n\n  test \"collection radio wrap items in a span tag by default\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form span input[type=radio][value=true]#user_active_true + label'\n    assert_select 'form span input[type=radio][value=false]#user_active_false + label'\n  end\n\n  test \"collection radio wraps each item in the given item wrapper tag\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, item_wrapper_tag: :li\n\n    assert_select 'form li input[type=radio]', count: 2\n  end\n\n  test \"collection radio does not wrap each item when given explicitly falsy value\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, item_wrapper_tag: false\n\n    assert_select 'form input[type=radio]'\n    assert_no_select 'form span input[type=radio]'\n  end\n\n  test \"collection radio uses the given class for item wrapper tag\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: :li, item_wrapper_class: \"inline\"\n\n    assert_select \"form li.inline input[type=radio]\", count: 2\n  end\n\n  test \"collection radio uses no class for item wrapper tag when no wrapper tag is given\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: nil, item_wrapper_class: \"inline\"\n\n    assert_select 'form input[type=radio]', count: 2\n    assert_no_select 'form li'\n    assert_no_select '.inline'\n  end\n\n  test \"collection radio uses no class for item wrapper tag by default\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: :li\n\n    assert_select \"form li\", count: 2\n    assert_no_select \"form li[class]\"\n  end\n\n  test \"collection radio does not wrap input inside the label\" do\n    with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=radio] + label'\n    assert_no_select 'form label input'\n  end\n\n  test \"collection radio accepts a block to render the label as radio button wrapper\" do\n    with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label { b.radio_button }\n    end\n\n    assert_select 'label[for=user_active_true] > input#user_active_true[type=radio]'\n    assert_select 'label[for=user_active_false] > input#user_active_false[type=radio]'\n  end\n\n  test \"collection radio accepts a block to change the order of label and radio button\" do\n    with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label + b.radio_button\n    end\n\n    assert_select 'label[for=user_active_true] + input#user_active_true[type=radio]'\n    assert_select 'label[for=user_active_false] + input#user_active_false[type=radio]'\n  end\n\n  test \"collection radio with block helpers accept extra html options\" do\n    with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(class: \"radio_button\") + b.radio_button(class: \"radio_button\")\n    end\n\n    assert_select 'label.radio_button[for=user_active_true] + input#user_active_true.radio_button[type=radio]'\n    assert_select 'label.radio_button[for=user_active_false] + input#user_active_false.radio_button[type=radio]'\n  end\n\n  test \"collection radio with block helpers allows access to current text and value\" do\n    with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(:\"data-value\" => b.value) { b.radio_button + b.text }\n    end\n\n    assert_select 'label[for=user_active_true][data-value=true]', 'true' do\n      assert_select 'input#user_active_true[type=radio]'\n    end\n    assert_select 'label[for=user_active_false][data-value=false]', 'false' do\n      assert_select 'input#user_active_false[type=radio]'\n    end\n  end\n\n  test \"collection radio with block helpers allows access to the current object item in the collection to access extra properties\" do\n    with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(class: b.object) { b.radio_button + b.text }\n    end\n\n    assert_select 'label.true[for=user_active_true]', 'true' do\n      assert_select 'input#user_active_true[type=radio]'\n    end\n    assert_select 'label.false[for=user_active_false]', 'false' do\n      assert_select 'input#user_active_false[type=radio]'\n    end\n  end\n\n  test \"collection radio with block helpers does not leak the template\" do\n    with_concat_form_for(@user) do |f|\n      collection_input = f.collection_radio_buttons :active, [true, false], :to_s, :to_s do |b|\n        b.label(class: b.object) { b.radio_button + b.text }\n      end\n      concat collection_input\n\n      concat f.hidden_field :name\n    end\n\n    assert_select 'label.true[for=user_active_true]', text: 'true', count: 1 do\n      assert_select 'input#user_active_true[type=radio]'\n    end\n    assert_select 'label.false[for=user_active_false]', text: 'false', count: 1 do\n      assert_select 'input#user_active_false[type=radio]'\n    end\n  end\n  # COLLECTION CHECK BOX\n  test \"collection check box accepts a collection and generate a series of checkboxes for value method\" do\n    collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]\n    with_collection_check_boxes @user, :tag_ids, collection, :id, :name\n\n    assert_select 'form input#user_tag_ids_1[type=checkbox][value=\"1\"]'\n    assert_select 'form input#user_tag_ids_2[type=checkbox][value=\"2\"]'\n  end\n\n  test \"collection check box generates only one hidden field for the entire collection, to ensure something will be sent back to the server when posting an empty collection\" do\n    collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]\n    with_collection_check_boxes @user, :tag_ids, collection, :id, :name\n\n    assert_select \"form input[type=hidden][name='user[tag_ids][]'][value='']\", count: 1\n  end\n\n  test \"collection check box accepts a collection and generate a series of checkboxes with labels for label method\" do\n    collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]\n    with_collection_check_boxes @user, :tag_ids, collection, :id, :name\n\n    assert_select 'form label.collection_check_boxes[for=user_tag_ids_1]', 'Tag 1'\n    assert_select 'form label.collection_check_boxes[for=user_tag_ids_2]', 'Tag 2'\n  end\n\n  test \"collection check box handles camelized collection values for labels correctly\" do\n    with_collection_check_boxes @user, :active, %w[Yes No], :to_s, :to_s\n\n    assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'\n    assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'\n  end\n\n  test \"collection check box sanitizes collection values for labels correctly\" do\n    with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s\n\n    assert_select 'label.collection_check_boxes[for=user_name_0_99]', '$0.99'\n    assert_select 'label.collection_check_boxes[for=user_name_1_99]', '$1.99'\n  end\n\n  test \"collection check box checks the correct value to local variables\" do\n    user = User.build(tag_ids: [1, 3])\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n\n    with_collection_check_boxes user, :tag_ids, collection, :first, :last\n\n    assert_select 'form input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_select 'form input[type=checkbox][value=\"3\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][checked=checked]'\n  end\n\n  test \"collection check box accepts selected values as :checked option\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: [1, 3]\n\n    assert_select 'form input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_select 'form input[type=checkbox][value=\"3\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][checked=checked]'\n  end\n\n  test \"collection check boxes accepts selected string values as :checked option\" do\n    collection = (1..3).map { |i| [i, \"Category #{i}\"] }\n    with_collection_check_boxes :user, :category_ids, collection, :first, :last, checked: %w[1 3]\n\n    assert_select 'input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_select 'input[type=checkbox][value=\"3\"][checked=checked]'\n    assert_no_select 'input[type=checkbox][value=\"2\"][checked=checked]'\n  end\n\n  test \"collection check box accepts a single checked value\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: 3\n\n    assert_select 'form input[type=checkbox][value=\"3\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][checked=checked]'\n  end\n\n  test \"collection check box accepts selected values as :checked option and override the model values\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    @user.tag_ids = [2]\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, checked: [1, 3]\n\n    assert_select 'form input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_select 'form input[type=checkbox][value=\"3\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][checked=checked]'\n  end\n\n  test \"collection check box accepts multiple disabled items\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: [1, 3]\n\n    assert_select 'form input[type=checkbox][value=\"1\"][disabled=disabled]'\n    assert_select 'form input[type=checkbox][value=\"3\"][disabled=disabled]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][disabled=disabled]'\n  end\n\n  test \"collection check box accepts single disable item\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: 1\n\n    assert_select 'form input[type=checkbox][value=\"1\"][disabled=disabled]'\n    assert_no_select 'form input[type=checkbox][value=\"3\"][disabled=disabled]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][disabled=disabled]'\n  end\n\n  test \"collection check box accepts a proc to disabled items\" do\n    collection = (1..3).map { |i| [i, \"Tag #{i}\"] }\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, disabled: proc { |i| i.first == 1 }\n\n    assert_select 'form input[type=checkbox][value=\"1\"][disabled=disabled]'\n    assert_no_select 'form input[type=checkbox][value=\"3\"][disabled=disabled]'\n    assert_no_select 'form input[type=checkbox][value=\"2\"][disabled=disabled]'\n  end\n\n  test \"collection check box accepts html options\" do\n    collection = [[1, 'Tag 1'], [2, 'Tag 2']]\n    with_collection_check_boxes @user, :tag_ids, collection, :first, :last, {}, class: 'check'\n\n    assert_select 'form input.check[type=checkbox][value=\"1\"]'\n    assert_select 'form input.check[type=checkbox][value=\"2\"]'\n  end\n\n  test \"collection check box with fields for\" do\n    collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]\n    with_concat_form_for(@user) do |f|\n      f.fields_for(:post) do |p|\n        p.collection_check_boxes :tag_ids, collection, :id, :name\n      end\n    end\n\n    assert_select 'form input#user_post_tag_ids_1[type=checkbox][value=\"1\"]'\n    assert_select 'form input#user_post_tag_ids_2[type=checkbox][value=\"2\"]'\n\n    assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_1]', 'Tag 1'\n    assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'\n  end\n\n  test \"collection check boxes wraps the collection in the given collection wrapper tag\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: :ul\n\n    assert_select 'form ul input[type=checkbox]', count: 2\n  end\n\n  test \"collection check boxes does not render any wrapper tag by default\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=checkbox]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test \"collection check boxes does not wrap the collection when given falsy values\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: false\n\n    assert_select 'form input[type=checkbox]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test \"collection check boxes uses the given class for collection wrapper tag\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,\n      collection_wrapper_tag: :ul, collection_wrapper_class: \"items-list\"\n\n    assert_select 'form ul.items-list input[type=checkbox]', count: 2\n  end\n\n  test \"collection check boxes uses no class for collection wrapper tag when no wrapper tag is given\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,\n      collection_wrapper_class: \"items-list\"\n\n    assert_select 'form input[type=checkbox]', count: 2\n    assert_no_select 'form ul'\n    assert_no_select '.items-list'\n  end\n\n  test \"collection check boxes uses no class for collection wrapper tag by default\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, collection_wrapper_tag: :ul\n\n    assert_select 'form ul'\n    assert_no_select 'form ul[class]'\n  end\n\n  test \"collection check boxes wrap items in a span tag by default\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form span input[type=checkbox]', count: 2\n  end\n\n  test \"collection check boxes wraps each item in the given item wrapper tag\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, item_wrapper_tag: :li\n\n    assert_select 'form li input[type=checkbox]', count: 2\n  end\n\n  test \"collection check boxes does not wrap each item when given explicitly falsy value\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, item_wrapper_tag: false\n\n    assert_select 'form input[type=checkbox]'\n    assert_no_select 'form span input[type=checkbox]'\n  end\n\n  test \"collection check boxes uses the given class for item wrapper tag\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: :li, item_wrapper_class: \"inline\"\n\n    assert_select \"form li.inline input[type=checkbox]\", count: 2\n  end\n\n  test \"collection check boxes uses no class for item wrapper tag when no wrapper tag is given\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: nil, item_wrapper_class: \"inline\"\n\n    assert_select 'form input[type=checkbox]', count: 2\n    assert_no_select 'form li'\n    assert_no_select '.inline'\n  end\n\n  test \"collection check boxes uses no class for item wrapper tag by default\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,\n      item_wrapper_tag: :li\n\n    assert_select \"form li\", count: 2\n    assert_no_select \"form li[class]\"\n  end\n\n  test \"collection check box does not wrap input inside the label\" do\n    with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s\n\n    assert_select 'form input[type=checkbox] + label'\n    assert_no_select 'form label input'\n  end\n\n  test \"collection check boxes accepts a block to render the label as check box wrapper\" do\n    with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label { b.check_box }\n    end\n\n    assert_select 'label[for=user_active_true] > input#user_active_true[type=checkbox]'\n    assert_select 'label[for=user_active_false] > input#user_active_false[type=checkbox]'\n  end\n\n  test \"collection check boxes accepts a block to change the order of label and check box\" do\n    with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label + b.check_box\n    end\n\n    assert_select 'label[for=user_active_true] + input#user_active_true[type=checkbox]'\n    assert_select 'label[for=user_active_false] + input#user_active_false[type=checkbox]'\n  end\n\n  test \"collection check boxes with block helpers accept extra html options\" do\n    with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(class: \"check_box\") + b.check_box(class: \"check_box\")\n    end\n\n    assert_select 'label.check_box[for=user_active_true] + input#user_active_true.check_box[type=checkbox]'\n    assert_select 'label.check_box[for=user_active_false] + input#user_active_false.check_box[type=checkbox]'\n  end\n\n  test \"collection check boxes with block helpers allows access to current text and value\" do\n    with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(:\"data-value\" => b.value) { b.check_box + b.text }\n    end\n\n    assert_select 'label[for=user_active_true][data-value=true]', 'true' do\n      assert_select 'input#user_active_true[type=checkbox]'\n    end\n    assert_select 'label[for=user_active_false][data-value=false]', 'false' do\n      assert_select 'input#user_active_false[type=checkbox]'\n    end\n  end\n\n  test \"collection check boxes with block helpers allows access to the current object item in the collection to access extra properties\" do\n    with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|\n      b.label(class: b.object) { b.check_box + b.text }\n    end\n\n    assert_select 'label.true[for=user_active_true]', 'true' do\n      assert_select 'input#user_active_true[type=checkbox]'\n    end\n    assert_select 'label.false[for=user_active_false]', 'false' do\n      assert_select 'input#user_active_false[type=checkbox]'\n    end\n  end\n\n  test \"collection check boxes with block helpers does not leak the template\" do\n    with_concat_form_for(@user) do |f|\n      collection_input = f.collection_check_boxes :active, [true, false], :to_s, :to_s do |b|\n        b.label(class: b.object) { b.check_box + b.text }\n      end\n      concat collection_input\n\n      concat f.hidden_field :name\n    end\n\n    assert_select 'label.true[for=user_active_true]', text: 'true', count: 1 do\n      assert_select 'input#user_active_true[type=checkbox]'\n    end\n    assert_select 'label.false[for=user_active_false]', text: 'false', count: 1 do\n      assert_select 'input#user_active_false[type=checkbox]'\n    end\n  end\n\n  # SIMPLE FIELDS\n  test \"simple fields for is available and yields an instance of FormBuilder\" do\n    with_concat_form_for(@user) do |f|\n      f.simple_fields_for(:posts) do |posts_form|\n        assert posts_form.instance_of?(SimpleForm::FormBuilder)\n      end\n    end\n  end\n\n  test \"fields for with a hash like model yields an instance of FormBuilder\" do\n    with_concat_form_for(:user) do |f|\n      f.simple_fields_for(:author, HashBackedAuthor.new) do |author|\n        assert author.instance_of?(SimpleForm::FormBuilder)\n        author.input :name\n      end\n    end\n\n    assert_select \"input[name='user[author][name]'][value='hash backed author']\"\n  end\n\n  test \"fields for yields an instance of CustomBuilder if main builder is a CustomBuilder\" do\n    with_custom_form_for(:user) do |f|\n      f.simple_fields_for(:company) do |company|\n        assert company.instance_of?(CustomFormBuilder)\n      end\n    end\n  end\n\n  test \"fields for yields an instance of FormBuilder if it was set in options\" do\n    with_custom_form_for(:user) do |f|\n      f.simple_fields_for(:company, builder: SimpleForm::FormBuilder) do |company|\n        assert company.instance_of?(SimpleForm::FormBuilder)\n      end\n    end\n  end\n\n  test \"fields inherits wrapper option from the parent form\" do\n    swap_wrapper :another do\n      simple_form_for(:user, wrapper: :another) do |f|\n        f.simple_fields_for(:company) do |company|\n          assert_equal :another, company.options[:wrapper]\n        end\n      end\n    end\n  end\n\n  test \"fields overrides wrapper option from the parent form\" do\n    swap_wrapper :another do\n      simple_form_for(:user, wrapper: :another) do |f|\n        f.simple_fields_for(:company, wrapper: false) do |company|\n          assert_equal false, company.options[:wrapper]\n        end\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/action_view_extensions/form_helper_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass FormHelperTest < ActionView::TestCase\n\n  test 'SimpleForm for yields an instance of FormBuilder' do\n    simple_form_for :user do |f|\n      assert f.instance_of?(SimpleForm::FormBuilder)\n    end\n  end\n\n  test 'SimpleForm adds default class to form' do\n    with_concat_form_for(:user)\n    assert_select 'form.simple_form'\n  end\n\n  test 'SimpleForm allows overriding default form class' do\n    swap SimpleForm, default_form_class: \"my_custom_class\" do\n      with_concat_form_for :user, html: { class: \"override_class\" }\n      assert_no_select 'form.my_custom_class'\n      assert_select 'form.override_class'\n    end\n  end\n\n  # Remove this test when SimpleForm.form_class is removed in 4.x\n  test 'SimpleForm allows overriding default form class, but not form class' do\n    SimpleForm.deprecator.silence do\n      swap SimpleForm, form_class: \"fixed_class\", default_form_class: \"my_custom_class\" do\n        with_concat_form_for :user, html: { class: \"override_class\" }\n        assert_no_select 'form.my_custom_class'\n        assert_select 'form.fixed_class.override_class'\n      end\n    end\n  end\n\n  test 'SimpleForm uses default browser validations by default' do\n    with_concat_form_for(:user)\n    assert_no_select 'form[novalidate]'\n  end\n\n  test 'SimpleForm does not use default browser validations if specified in the configuration options' do\n    swap SimpleForm, browser_validations: false do\n      with_concat_form_for(:user)\n      assert_select 'form[novalidate=\"novalidate\"]'\n    end\n  end\n\n  test 'disabled browser validations overrides default configuration' do\n    with_concat_form_for(:user, html: { novalidate: true })\n    assert_select 'form[novalidate=\"novalidate\"]'\n  end\n\n  test 'enabled browser validations overrides disabled configuration' do\n    swap SimpleForm, browser_validations: false do\n      with_concat_form_for(:user, html: { novalidate: false })\n      assert_no_select 'form[novalidate]'\n    end\n  end\n\n  test 'SimpleForm adds object name as css class to form when object is not present' do\n    with_concat_form_for(:user, html: { novalidate: true })\n    assert_select 'form.simple_form.user'\n  end\n\n  test 'SimpleForm adds :as option as css class to form when object is not present' do\n    with_concat_form_for(:user, as: 'superuser')\n    assert_select 'form.simple_form.superuser'\n  end\n\n  test 'SimpleForm adds object class name with new prefix as css class to form if record is not persisted' do\n    @user.new_record!\n    with_concat_form_for(@user)\n    assert_select 'form.simple_form.new_user'\n  end\n\n  test 'SimpleForm adds :as option with new prefix as css class to form if record is not persisted' do\n    @user.new_record!\n    with_concat_form_for(@user, as: 'superuser')\n    assert_select 'form.simple_form.new_superuser'\n  end\n\n  test 'SimpleForm adds edit class prefix as css class to form if record is persisted' do\n    with_concat_form_for(@user)\n    assert_select 'form.simple_form.edit_user'\n  end\n\n  test 'SimpleForm adds :as options with edit prefix as css class to form if record is persisted' do\n    with_concat_form_for(@user, as: 'superuser')\n    assert_select 'form.simple_form.edit_superuser'\n  end\n\n  test 'SimpleForm adds last object name as css class to form when there is array of objects' do\n    with_concat_form_for([Company.new, @user])\n    assert_select 'form.simple_form.edit_user'\n  end\n\n  test 'SimpleForm does not add object class to form if css_class is specified' do\n    with_concat_form_for(:user, html: { class: nil })\n    assert_no_select 'form.user'\n  end\n\n  test 'SimpleForm adds custom class to form if css_class is specified' do\n    with_concat_form_for(:user, html: { class: 'my_class' })\n    assert_select 'form.my_class'\n  end\n\n  test 'passes options to SimpleForm' do\n    with_concat_form_for(:user, url: '/account', html: { id: 'my_form' })\n    assert_select 'form#my_form'\n    assert_select 'form[action=\"/account\"]'\n  end\n\n  test 'form_for yields an instance of FormBuilder' do\n    with_concat_form_for(:user) do |f|\n      assert f.instance_of?(SimpleForm::FormBuilder)\n    end\n  end\n\n  test 'fields_for with a hash like model yields an instance of FormBuilder' do\n    with_concat_fields_for(:author, HashBackedAuthor.new) do |f|\n      assert f.instance_of?(SimpleForm::FormBuilder)\n      f.input :name\n    end\n\n    assert_select \"input[name='author[name]'][value='hash backed author']\"\n  end\n\n  test 'custom error proc is not destructive' do\n    swap_field_error_proc do\n      result = nil\n      simple_form_for :user do |f|\n        result = simple_fields_for 'address' do\n          'hello'\n        end\n      end\n\n      assert_equal 'hello', result\n    end\n  end\n\n  test 'custom error proc survives an exception' do\n    swap_field_error_proc do\n      begin\n        simple_form_for :user do |f|\n          simple_fields_for 'address' do\n            raise 'an exception'\n          end\n        end\n      rescue StandardError\n      end\n    end\n  end\n\n  test 'SimpleForm for swaps default action view field_error_proc' do\n    expected_error_proc = -> {}\n    swap SimpleForm, field_error_proc: expected_error_proc do\n      simple_form_for :user do |f|\n        assert_equal expected_error_proc, ::ActionView::Base.field_error_proc\n      end\n    end\n  end\n\n  private\n\n  def swap_field_error_proc(expected_error_proc = -> {})\n    swap ActionView::Base, field_error_proc: expected_error_proc do\n      yield\n\n      assert_equal expected_error_proc, ActionView::Base.field_error_proc\n    end\n  end\nend\n"
  },
  {
    "path": "test/components/custom_components_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'test_helper'\n\n# Module that represents a custom component.\nmodule Numbers\n  def number(wrapper_options = nil)\n    @number ||= options[:number].to_s.html_safe\n  end\nend\n\n# Module that represents a custom component.\nmodule InputGroup\n  def prepend(wrapper_options = nil)\n    span_tag = content_tag(:span, options[:prepend], class: 'input-group-text')\n    template.content_tag(:div, span_tag, class: 'input-group-prepend')\n  end\n\n  def append(wrapper_options = nil)\n    span_tag = content_tag(:span, options[:append], class: 'input-group-text')\n    template.content_tag(:div, span_tag, class: 'input-group-append')\n  end\nend\n\nclass CustomComponentsTest < ActionView::TestCase\n  test 'includes the custom components' do\n    SimpleForm.include_component Numbers\n\n    custom_wrapper = SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :number, wrap_with: { tag: 'div', class: 'number' }\n    end\n\n    with_form_for @user, :name, number: 1, wrapper: custom_wrapper\n\n    assert_select 'div.number', text: '1'\n  end\n\n  test 'includes custom components and use it as optional in the wrapper' do\n    SimpleForm.include_component InputGroup\n\n    custom_wrapper = SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|\n      b.use :label\n      b.optional :prepend\n      b.use :input\n      b.use :append\n    end\n\n    with_form_for @user, :name, prepend: true, wrapper: custom_wrapper\n\n    assert_select 'div.input-group-prepend > span.input-group-text'\n    assert_select 'div.input-group-append > span.input-group-text'\n  end\n\n  test 'raises a TypeError when the component is not a Module' do\n    component = 'MyComponent'\n\n    exception = assert_raises TypeError do \n      SimpleForm.include_component(component)\n    end\n    assert_equal exception.message, \"SimpleForm.include_component expects a module but got: String\"\n  end\nend\n"
  },
  {
    "path": "test/components/label_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Isolated tests for label without triggering f.label.\nclass IsolatedLabelTest < ActionView::TestCase\n  def with_label_for(object, attribute_name, type, options = {})\n    with_concat_form_for(object) do |f|\n      options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)\n      SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label\n    end\n  end\n\n  test 'label generates a default humanized description' do\n    with_label_for @user, :name, :string\n    assert_select 'label[for=user_name]', /Name/\n  end\n\n  test 'label allows a customized description' do\n    with_label_for @user, :name, :string, label: 'My label!'\n    assert_select 'label[for=user_name]', /My label!/\n  end\n\n  test 'label uses human attribute name from object when available' do\n    with_label_for @user, :description, :text\n    assert_select 'label[for=user_description]', /User Description!/\n  end\n\n  test 'label uses human_attribute_name and passed object as an option to it' do\n    with_label_for @user, :status, :text\n    assert_select 'label[for=user_status]', /\\[#{@user.id}\\] User Status!/\n  end\n\n  test 'label uses human attribute name based on association name' do\n    with_label_for @user, :company_id, :string, setup_association: true\n    assert_select 'label', /Company Human Name!/\n  end\n\n  test 'label uses i18n based on model, action, and attribute to lookup translation' do\n    @controller.action_name = \"new\"\n    store_translations(:en, simple_form: { labels: { user: {\n      new: { description: 'Nova descrição' }\n    } } }) do\n      with_label_for @user, :description, :text\n      assert_select 'label[for=user_description]', /Nova descrição/\n    end\n  end\n\n  test 'label fallbacks to new when action is create' do\n    @controller.action_name = \"create\"\n    store_translations(:en, simple_form: { labels: { user: {\n      new: { description: 'Nova descrição' }\n    } } }) do\n      with_label_for @user, :description, :text\n      assert_select 'label[for=user_description]', /Nova descrição/\n    end\n  end\n\n  test 'label does not explode while looking for i18n translation when action is not set' do\n    def @controller.action_name; nil; end\n\n    assert_nothing_raised do\n      with_label_for @user, :description, :text\n    end\n    assert_select 'label[for=user_description]'\n  end\n\n  test 'label uses i18n based on model and attribute to lookup translation' do\n    store_translations(:en, simple_form: { labels: { user: {\n      description: 'Descrição'\n    } } }) do\n      with_label_for @user, :description, :text\n      assert_select 'label[for=user_description]', /Descrição/\n    end\n  end\n\n  test 'label uses i18n under defaults to lookup translation' do\n    store_translations(:en, simple_form: { labels: { defaults: { age: 'Idade' } } }) do\n      with_label_for @user, :age, :integer\n      assert_select 'label[for=user_age]', /Idade/\n    end\n  end\n\n  test 'label does not use i18n label if translate is false' do\n    swap SimpleForm, translate_labels: false do\n      store_translations(:en, simple_form: { labels: { defaults: { age: 'Idade' } } }) do\n        with_label_for @user, :age, :integer\n        assert_select 'label[for=user_age]', /Age/\n      end\n    end\n  end\n\n  test 'label uses i18n with lookup for association name' do\n    store_translations(:en, simple_form: { labels: {\n      user: { company: 'My company!' }\n    } }) do\n      with_label_for @user, :company_id, :string, setup_association: true\n      assert_select 'label[for=user_company_id]', /My company!/\n    end\n  end\n\n  test 'label uses i18n under defaults namespace to lookup for association name' do\n    store_translations(:en, simple_form: { labels: {\n      defaults: { company: 'Plataformatec' }\n    } }) do\n      with_label_for @user, :company, :string, setup_association: true\n\n      assert_select 'form label', /Plataformatec/\n    end\n  end\n\n  test 'label does correct i18n lookup for nested models with nested translation' do\n    @user.company = Company.new(1, 'Empresa')\n\n    store_translations(:en, simple_form: { labels: {\n      user: { name: 'Usuario', company: { name: 'Nome da empresa' } }\n    } }) do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n        concat(f.simple_fields_for(:company) do |company_form|\n          concat(company_form.input :name)\n        end)\n      end\n\n      assert_select 'label[for=user_name]', /Usuario/\n      assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/\n    end\n  end\n\n  test 'label does correct i18n lookup for nested models with no nested translation' do\n    @user.company = Company.new(1, 'Empresa')\n\n    store_translations(:en, simple_form: { labels: {\n      user: { name: 'Usuario' },\n      company: { name: 'Nome da empresa' }\n    } }) do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n        concat(f.simple_fields_for(:company) do |company_form|\n          concat(company_form.input :name)\n        end)\n      end\n\n      assert_select 'label[for=user_name]', /Usuario/\n      assert_select 'label[for=user_company_attributes_name]', /Nome da empresa/\n    end\n  end\n\n  test 'label does correct i18n lookup for nested has_many models with no nested translation' do\n    @user.tags = [Tag.new(1, 'Empresa')]\n\n    store_translations(:en, simple_form: { labels: {\n      user: { name: 'Usuario' },\n      tags: { name: 'Nome da empresa' }\n    } }) do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n        concat(f.simple_fields_for(:tags, child_index: \"new_index\") do |tags_form|\n          concat(tags_form.input :name)\n        end)\n      end\n\n      assert_select 'label[for=user_name]', /Usuario/\n      assert_select 'label[for=user_tags_attributes_new_index_name]', /Nome da empresa/\n    end\n  end\n\n  test 'label has css class from type' do\n    with_label_for @user, :name, :string\n    assert_select 'label.string'\n    with_label_for @user, :description, :text\n    assert_select 'label.text'\n    with_label_for @user, :age, :integer\n    assert_select 'label.integer'\n    with_label_for @user, :born_at, :date\n    assert_select 'label.date'\n    with_label_for @user, :created_at, :datetime\n    assert_select 'label.datetime'\n  end\n\n  test 'label does not have css class from type when generate_additional_classes_for does not include :label' do\n    swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do\n      with_label_for @user, :name, :string\n      assert_no_select 'label.string'\n      with_label_for @user, :description, :text\n      assert_no_select 'label.text'\n      with_label_for @user, :age, :integer\n      assert_no_select 'label.integer'\n      with_label_for @user, :born_at, :date\n      assert_no_select 'label.date'\n      with_label_for @user, :created_at, :datetime\n      assert_no_select 'label.datetime'\n    end\n  end\n\n  test 'label does not generate empty css class' do\n    swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do\n      with_label_for @user, :name, :string\n      assert_no_select 'label[class]'\n    end\n  end\n\n  test 'label obtains required from ActiveModel::Validations when it is included' do\n    with_label_for @validating_user, :name, :string\n    assert_select 'label.required'\n    with_label_for @validating_user, :status, :string\n    assert_select 'label.optional'\n  end\n\n  test 'label does not obtain required from ActiveModel::Validations when generate_additional_classes_for does not include :label' do\n    swap SimpleForm, generate_additional_classes_for: %i[wrapper input] do\n      with_label_for @validating_user, :name, :string\n      assert_no_select 'label.required'\n      with_label_for @validating_user, :status, :string\n      assert_no_select 'label.optional'\n    end\n  end\n\n  test 'label allows overriding required when ActiveModel::Validations is included' do\n    with_label_for @validating_user, :name, :string, required: false\n    assert_select 'label.optional'\n    with_label_for @validating_user, :status, :string, required: true\n    assert_select 'label.required'\n  end\n\n  test 'label is required by default when ActiveModel::Validations is not included' do\n    with_label_for @user, :name, :string\n    assert_select 'label.required'\n  end\n\n  test 'label is able to disable required when ActiveModel::Validations is not included' do\n    with_label_for @user, :name, :string, required: false\n    assert_no_select 'label.required'\n  end\n\n  test 'label adds required text when required' do\n    with_label_for @user, :name, :string\n    assert_select 'label.required abbr[title=required]', '*'\n  end\n\n  test 'label does not have required text in no required inputs' do\n    with_label_for @user, :name, :string, required: false\n    assert_no_select 'form label abbr'\n  end\n\n  test 'label uses i18n to find required text' do\n    store_translations(:en, simple_form: { required: { text: 'campo requerido' } }) do\n      with_label_for @user, :name, :string\n      assert_select 'form label abbr[title=\"campo requerido\"]', '*'\n    end\n  end\n\n  test 'label uses custom i18n scope to find required text' do\n    store_translations(:en, my_scope: { required: { text: 'Pflichtfeld' } }) do\n      swap SimpleForm, i18n_scope: :my_scope do\n        with_label_for @user, :name, :string\n        assert_select 'form label abbr[title=\"Pflichtfeld\"]', '*'\n      end\n    end\n  end\n\n  test 'label uses i18n to find required mark' do\n    store_translations(:en, simple_form: { required: { mark: '*-*' } }) do\n      with_label_for @user, :name, :string\n      assert_select 'form label abbr', '*-*'\n    end\n  end\n\n  test 'label uses custom i18n scope to find required mark' do\n    store_translations(:en, my_scope: { required: { mark: '!!' } }) do\n      swap SimpleForm, i18n_scope: :my_scope do\n        with_label_for @user, :name, :string\n        assert_select 'form label abbr', '!!'\n      end\n    end\n  end\n\n  test 'label uses i18n to find required string tag' do\n    store_translations(:en, simple_form: { required: { html: '<span class=\"required\" title=\"requerido\">*</span>' } }) do\n      with_label_for @user, :name, :string\n      assert_no_select 'form label abbr'\n      assert_select 'form label span.required[title=requerido]', '*'\n    end\n  end\n\n  test 'label uses custom i18n scope to find required string tag' do\n    store_translations(:en, my_scope: { required: { html: '<span class=\"mandatory\" title=\"Pflichtfeld\">!!</span>' } }) do\n      swap SimpleForm, i18n_scope: :my_scope do\n        with_label_for @user, :name, :string\n        assert_no_select 'form label abbr'\n        assert_select 'form label span.mandatory[title=Pflichtfeld]', '!!'\n      end\n    end\n  end\n\n  test 'label allows overwriting input id' do\n    with_label_for @user, :name, :string, input_html: { id: 'my_new_id' }\n    assert_select 'label[for=my_new_id]'\n  end\n\n  test 'label allows overwriting of for attribute' do\n    with_label_for @user, :name, :string, label_html: { for: 'my_new_id' }\n    assert_select 'label[for=my_new_id]'\n  end\n\n  test 'label allows overwriting of for attribute with input_html not containing id' do\n    with_label_for @user, :name, :string, label_html: { for: 'my_new_id' }, input_html: { class: 'foo' }\n    assert_select 'label[for=my_new_id]'\n  end\n\n  test 'label uses default input id when it was not overridden' do\n    with_label_for @user, :name, :string, input_html: { class: 'my_new_id' }\n    assert_select 'label[for=user_name]'\n  end\n\n  test 'label is generated properly when object is not present' do\n    with_label_for :project, :name, :string\n    assert_select 'label[for=project_name]', /Name/\n  end\n\n  test 'label includes for attribute for select collection' do\n    with_label_for @user, :sex, :select, collection: %i[male female]\n    assert_select 'label[for=user_sex]'\n  end\n\n  test 'label uses i18n properly when object is not present' do\n    store_translations(:en, simple_form: { labels: {\n      project: { name: 'Nome' }\n    } }) do\n      with_label_for :project, :name, :string\n      assert_select 'label[for=project_name]', /Nome/\n    end\n  end\n\n  test 'label adds required by default when object is not present' do\n    with_label_for :project, :name, :string\n    assert_select 'label.required[for=project_name]'\n    with_label_for :project, :description, :string, required: false\n    assert_no_select 'label.required[for=project_description]'\n  end\n\n  test 'label adds chosen label class' do\n    swap SimpleForm, label_class: :my_custom_class do\n      with_label_for @user, :name, :string\n      assert_select 'label.my_custom_class'\n    end\n  end\n\n  test 'label strips extra classes even when label_class is nil' do\n    swap SimpleForm, label_class: nil do\n      with_label_for @user, :name, :string\n      assert_select \"label[class='string required']\"\n      assert_no_select \"label[class='string required ']\"\n      assert_no_select \"label[class=' string required']\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/association_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass AssociationTest < ActionView::TestCase\n  def with_association_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.association(*args)\n    end\n  end\n\n  test 'builder does not allow creating an association input when no object exists' do\n    assert_raise ArgumentError do\n      with_association_for :post, :author\n    end\n  end\n\n  test 'builder association works with decorated object responsive to #to_model' do\n    assert_nothing_raised do\n      with_association_for @decorated_user, :company\n    end\n  end\n\n  test 'builder association with a block calls simple_fields_for' do\n    simple_form_for @user do |f|\n      f.association :posts do |posts_form|\n        assert posts_form.instance_of?(SimpleForm::FormBuilder)\n      end\n    end\n  end\n\n  test 'builder association forwards collection to simple_fields_for' do\n    calls = 0\n    simple_form_for @user do |f|\n      f.association :company, collection: Company.all do |c|\n        calls += 1\n      end\n    end\n\n    assert_equal 3, calls\n  end\n\n  test 'builder association marks input as required based on both association and attribute' do\n    swap SimpleForm, required_by_default: false do\n      with_association_for @validating_user, :company, collection: []\n      assert_select 'label.required'\n    end\n  end\n\n  test 'builder preloads collection association' do\n    value = @user.tags = Minitest::Mock.new\n    value.expect(:to_a, value)\n\n    with_association_for @user, :tags\n    assert_select 'form select.select#user_tag_ids'\n    assert_select 'form select option[value=\"1\"]', 'Tag 1'\n    assert_select 'form select option[value=\"2\"]', 'Tag 2'\n    assert_select 'form select option[value=\"3\"]', 'Tag 3'\n\n    value.verify\n  end\n\n  test 'builder does not preload collection association if preload is false' do\n    value = @user.tags = Minitest::Mock.new\n    value.expect(:to_a, nil)\n\n    with_association_for @user, :tags, preload: false\n    assert_select 'form select.select#user_tag_ids'\n    assert_select 'form select option[value=\"1\"]', 'Tag 1'\n    assert_select 'form select option[value=\"2\"]', 'Tag 2'\n    assert_select 'form select option[value=\"3\"]', 'Tag 3'\n\n    assert_raises MockExpectationError do\n      value.verify\n    end\n  end\n\n  test 'builder does not preload non-collection association' do\n    value = @user.company = Minitest::Mock.new\n    value.expect(:to_a, nil)\n\n    with_association_for @user, :company\n    assert_select 'form select.select#user_company_id'\n    assert_select 'form select option[value=\"1\"]', 'Company 1'\n    assert_select 'form select option[value=\"2\"]', 'Company 2'\n    assert_select 'form select option[value=\"3\"]', 'Company 3'\n\n    assert_raises MockExpectationError do\n      value.verify\n    end\n  end\n\n  # ASSOCIATIONS - BELONGS TO\n  test 'builder creates a select for belongs_to associations' do\n    with_association_for @user, :company\n    assert_select 'form select.select#user_company_id'\n    assert_select 'form select option[value=\"1\"]', 'Company 1'\n    assert_select 'form select option[value=\"2\"]', 'Company 2'\n    assert_select 'form select option[value=\"3\"]', 'Company 3'\n  end\n\n  test 'builder creates blank select if collection is nil' do\n    with_association_for @user, :company, collection: nil\n    assert_select 'form select.select#user_company_id'\n    assert_no_select 'form select option[value=\"1\"]', 'Company 1'\n  end\n\n  test 'builder allows collection radio for belongs_to associations' do\n    with_association_for @user, :company, as: :radio_buttons\n    assert_select 'form input.radio_buttons#user_company_id_1'\n    assert_select 'form input.radio_buttons#user_company_id_2'\n    assert_select 'form input.radio_buttons#user_company_id_3'\n  end\n\n  test 'builder allows collection to have a proc as a condition' do\n    with_association_for @user, :extra_special_company\n    assert_select 'form select.select#user_extra_special_company_id'\n    assert_select 'form select option[value=\"1\"]'\n    assert_no_select 'form select option[value=\"2\"]'\n    assert_no_select 'form select option[value=\"3\"]'\n  end\n\n  test 'builder allows collection to have a scope' do\n    with_association_for @user, :special_pictures\n    assert_select 'form select.select#user_special_picture_ids'\n    assert_select 'form select option[value=\"3\"]', '3'\n    assert_no_select 'form select option[value=\"1\"]'\n    assert_no_select 'form select option[value=\"2\"]'\n  end\n\n  test 'builder allows collection to have a scope with parameter' do\n    with_association_for @user, :special_tags\n    assert_select 'form select.select#user_special_tag_ids'\n    assert_select 'form select[multiple=multiple]'\n    assert_select 'form select option[value=\"1\"]', 'Tag 1'\n    assert_no_select 'form select option[value=\"2\"]'\n    assert_no_select 'form select option[value=\"3\"]'\n  end\n\n  test 'builder marks the record which already belongs to the user' do\n    @user.company_id = 2\n    with_association_for @user, :company, as: :radio_buttons\n    assert_no_select 'form input.radio_buttons#user_company_id_1[checked=checked]'\n    assert_select 'form input.radio_buttons#user_company_id_2[checked=checked]'\n    assert_no_select 'form input.radio_buttons#user_company_id_3[checked=checked]'\n  end\n\n  # ASSOCIATIONS - FINDERS\n  test 'builder uses reflection conditions to find collection' do\n    with_association_for @user, :special_company\n    assert_select 'form select.select#user_special_company_id'\n    assert_select 'form select option[value=\"1\"]'\n    assert_no_select 'form select option[value=\"2\"]'\n    assert_no_select 'form select option[value=\"3\"]'\n  end\n\n  test 'builder allows overriding collection to association input' do\n    with_association_for @user, :company, include_blank: false,\n                         collection: [Company.new(999, 'Teste')]\n    assert_select 'form select.select#user_company_id'\n    assert_no_select 'form select option[value=\"1\"]'\n    assert_select 'form select option[value=\"999\"]', 'Teste'\n    assert_select 'form select option', count: 1\n  end\n\n  # ASSOCIATIONS - has_*\n  test 'builder does not allow has_one associations' do\n    assert_raise ArgumentError do\n      with_association_for @user, :first_company, as: :radio_buttons\n    end\n  end\n\n  test 'builder does not call where if the given association does not respond to it' do\n    with_association_for @user, :friends\n    assert_select 'form select.select#user_friend_ids'\n    assert_select 'form select[multiple=multiple]'\n    assert_select 'form select option[value=\"1\"]', 'Friend 1'\n    assert_select 'form select option[value=\"2\"]', 'Friend 2'\n    assert_select 'form select option[value=\"3\"]', 'Friend 3'\n  end\n\n  test 'builder does not call order if the given association does not respond to it' do\n    with_association_for @user, :pictures\n    assert_select 'form select.select#user_picture_ids'\n    assert_select 'form select[multiple=multiple]'\n    assert_select 'form select option[value=\"1\"]', 'Picture 1'\n    assert_select 'form select option[value=\"2\"]', 'Picture 2'\n    assert_select 'form select option[value=\"3\"]', 'Picture 3'\n  end\n\n  test 'builder creates a select with multiple options for collection associations' do\n    with_association_for @user, :tags\n    assert_select 'form select.select#user_tag_ids'\n    assert_select 'form select[multiple=multiple]'\n    assert_select 'form select option[value=\"1\"]', 'Tag 1'\n    assert_select 'form select option[value=\"2\"]', 'Tag 2'\n    assert_select 'form select option[value=\"3\"]', 'Tag 3'\n  end\n\n  test 'builder allows size to be overwritten for collection associations' do\n    with_association_for @user, :tags, input_html: { size: 10 }\n    assert_select 'form select[multiple=multiple][size=\"10\"]'\n  end\n\n  test 'builder marks all selected records which already belongs to user' do\n    @user.tag_ids = [1, 2]\n    with_association_for @user, :tags\n    assert_select 'form select option[value=\"1\"][selected=selected]'\n    assert_select 'form select option[value=\"2\"][selected=selected]'\n    assert_no_select 'form select option[value=\"3\"][selected=selected]'\n  end\n\n  test 'builder allows a collection of check boxes for collection associations' do\n    @user.tag_ids = [1, 2]\n    with_association_for @user, :tags, as: :check_boxes\n    assert_select 'form input#user_tag_ids_1[type=checkbox]'\n    assert_select 'form input#user_tag_ids_2[type=checkbox]'\n    assert_select 'form input#user_tag_ids_3[type=checkbox]'\n  end\n\n  test 'builder marks all selected records for collection boxes' do\n    @user.tag_ids = [1, 2]\n    with_association_for @user, :tags, as: :check_boxes\n    assert_select 'form input[type=checkbox][value=\"1\"][checked=checked]'\n    assert_select 'form input[type=checkbox][value=\"2\"][checked=checked]'\n    assert_no_select 'form input[type=checkbox][value=\"3\"][checked=checked]'\n  end\n\n  test 'builder with collection support giving collection and item wrapper tags' do\n    with_association_for @user, :tags, as: :check_boxes,\n      collection_wrapper_tag: :ul, item_wrapper_tag: :li\n\n    assert_select 'form ul', count: 1\n    assert_select 'form ul li', count: 3\n  end\n\n  test 'builder with collection support does not change the options hash' do\n    options = { as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li }\n    with_association_for @user, :tags, options\n\n    assert_select 'form ul', count: 1\n    assert_select 'form ul li', count: 3\n    assert_equal({ as: :check_boxes, collection_wrapper_tag: :ul, item_wrapper_tag: :li },\n                 options)\n  end\n\n  test 'builder with group select considers multiple select by default' do\n    with_association_for @user, :tags, as: :grouped_select, group_method: :group_method\n\n    assert_select 'select[multiple=\"multiple\"].grouped_select'\n  end\nend\n"
  },
  {
    "path": "test/form_builder/button_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass ButtonTest < ActionView::TestCase\n  def with_button_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.button(*args)\n    end\n  end\n\n  test 'builder creates buttons' do\n    with_button_for :post, :submit\n    assert_select 'form input.button[type=submit][value=\"Save Post\"]'\n  end\n\n  test 'builder creates buttons with options' do\n    with_button_for :post, :submit, class: 'my_button'\n    assert_select 'form input.button.my_button[type=submit][value=\"Save Post\"]'\n  end\n\n  test 'builder does not modify the options hash' do\n    options = { class: 'my_button' }\n    with_button_for :post, :submit, options\n    assert_select 'form input.button.my_button[type=submit][value=\"Save Post\"]'\n    assert_equal({ class: 'my_button' }, options)\n  end\n\n  test 'builder creates buttons for records' do\n    @user.new_record!\n    with_button_for @user, :submit\n    assert_select 'form input.button[type=submit][value=\"Create User\"]'\n  end\n\n  test \"builder uses the default class from the configuration\" do\n    swap SimpleForm, button_class: 'btn' do\n      with_button_for :post, :submit\n      assert_select 'form input.btn[type=submit][value=\"Save Post\"]'\n    end\n  end\n\n  if ActionView::Helpers::FormBuilder.method_defined?(:button)\n    test \"allows to use Rails button helper when available\" do\n      with_button_for :post, :button, 'Save!'\n      assert_select 'form button.button[type=submit]', 'Save!'\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/error_notification_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Tests for f.error_notification\nclass ErrorNotificationTest < ActionView::TestCase\n  def with_error_notification_for(object, options = {}, &block)\n    with_concat_form_for(object) do |f|\n      f.error_notification(options)\n    end\n  end\n\n  test 'error notification is not generated when the object has no error' do\n    assert @validating_user.valid?\n\n    with_error_notification_for @validating_user\n    assert_no_select 'p.error_notification'\n  end\n\n  test 'error notification is not generated for forms without objects' do\n    with_error_notification_for :user\n    assert_no_select 'p.error_notification'\n  end\n\n  test 'error notification is generated when the object has some error' do\n    with_error_notification_for @user\n    assert_select 'p.error_notification', 'Please review the problems below:'\n  end\n\n  test 'error notification uses I18n based on model to generate the notification message' do\n    store_translations(:en, simple_form: { error_notification: { user:\n      'Alguns erros foram encontrados para o usuário:'\n    } }) do\n      with_error_notification_for @user\n      assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'\n    end\n  end\n\n  test 'error notification uses I18n fallbacking to default message' do\n    store_translations(:en, simple_form: { error_notification: {\n      default_message: 'Opa! Alguns erros foram encontrados, poderia verificar?'\n    } }) do\n      with_error_notification_for @user\n      assert_select 'p.error_notification', 'Opa! Alguns erros foram encontrados, poderia verificar?'\n    end\n  end\n\n  test 'error notification allows passing the notification message' do\n    with_error_notification_for @user, message: 'Erro encontrado ao criar usuario'\n    assert_select 'p.error_notification', 'Erro encontrado ao criar usuario'\n  end\n\n  test 'error notification accepts other html options' do\n    with_error_notification_for @user, id: 'user_error_message', class: 'form_error'\n    assert_select 'p#user_error_message.form_error.error_notification'\n  end\n\n  test 'error notification allows configuring the wrapper element' do\n    swap SimpleForm, error_notification_tag: :div do\n      with_error_notification_for @user\n      assert_select 'div.error_notification'\n    end\n  end\n\n  test 'error notification can contain HTML tags' do\n    with_error_notification_for @user, message: 'Erro encontrado ao criar <b>usuário</b>'\n    assert_select 'p.error_notification', 'Erro encontrado ao criar usuário'\n    assert_select 'p.error_notification b', 'usuário'\n  end\n\n  test 'error notification uses I18n based on model to generate the notification message and accepts HTML' do\n    store_translations(:en, simple_form: { error_notification: { user:\n      'Alguns erros foram encontrados para o <b>usuário</b>:'\n    } }) do\n      with_error_notification_for @user\n      assert_select 'p.error_notification', 'Alguns erros foram encontrados para o usuário:'\n      assert_select 'p.error_notification b', 'usuário'\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/error_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.error and f.full_error\nclass ErrorTest < ActionView::TestCase\n  def with_error_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.error(*args)\n    end\n  end\n\n  def with_full_error_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.full_error(*args)\n    end\n  end\n\n  test 'error does not generate content for attribute without errors' do\n    with_error_for @user, :active\n    assert_no_select 'span.error'\n  end\n\n  test 'error does not generate messages when object is not present' do\n    with_error_for :project, :name\n    assert_no_select 'span.error'\n  end\n\n  test \"error does not generate messages when object doesn't respond to errors method\" do\n    @user.instance_eval { undef errors }\n    with_error_for @user, :name\n    assert_no_select 'span.error'\n  end\n\n  test 'error generates messages for attribute with single error' do\n    with_error_for @user, :name\n    assert_select 'span.error', \"cannot be blank\"\n  end\n\n  test 'error generates messages with decorated object responsive to #to_model' do\n    with_error_for @decorated_user, :name\n    assert_select 'span.error', \"cannot be blank\"\n  end\n\n  test 'error generates messages for attribute with one error when using first' do\n    swap SimpleForm, error_method: :first do\n      with_error_for @user, :age\n      assert_select 'span.error', 'is not a number'\n    end\n  end\n\n  test 'error generates messages for attribute with several errors when using to_sentence' do\n    swap SimpleForm, error_method: :to_sentence do\n      with_error_for @user, :age\n      assert_select 'span.error', 'is not a number and must be greater than 18'\n    end\n  end\n\n  test 'error is able to pass html options' do\n    with_error_for @user, :name, id: 'error', class: 'yay'\n    assert_select 'span#error.error.yay'\n  end\n\n  test 'error does not modify the options hash' do\n    options = { id: 'error', class: 'yay' }\n    with_error_for @user, :name, options\n    assert_select 'span#error.error.yay'\n    assert_equal({ id: 'error', class: 'yay' }, options)\n  end\n\n  test 'error finds errors on attribute and association' do\n    with_error_for @user, :company_id, as: :select,\n      error_method: :to_sentence, reflection: Association.new(Company, :company, {})\n    assert_select 'span.error', 'must be valid and company must be present'\n  end\n\n  test 'error generates an error tag with a clean HTML' do\n    with_error_for @user, :name\n    assert_no_select 'span.error[error_html]'\n  end\n\n  test 'error generates an error tag with a clean HTML when errors options are present' do\n    with_error_for @user, :name, error_tag: :p, error_prefix: 'Name', error_method: :first\n    assert_no_select 'p.error[error_html]'\n    assert_no_select 'p.error[error_tag]'\n    assert_no_select 'p.error[error_prefix]'\n    assert_no_select 'p.error[error_method]'\n  end\n\n  test 'error escapes error prefix text' do\n    with_error_for @user, :name, error_prefix: '<b>Name</b>'\n    assert_no_select 'span.error b'\n  end\n\n  test 'error escapes error text' do\n    @user.errors.add(:action, 'must not contain <b>markup</b>')\n\n    with_error_for @user, :action\n\n    assert_select 'span.error'\n    assert_no_select 'span.error b', 'markup'\n  end\n\n  test 'error generates an error message with raw HTML tags' do\n    with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe\n    assert_select 'span.error', \"Name cannot be blank\"\n    assert_select 'span.error b', \"Name\"\n  end\n\n  test 'error adds aria-invalid attribute to inputs' do\n    with_form_for @user, :name, error: true\n    assert_select \"input#user_name[name='user[name]'][aria-invalid='true']\"\n\n    with_form_for @user, :name, as: :text, error: true\n    assert_select \"textarea#user_name[name='user[name]'][aria-invalid='true']\"\n\n    @user.errors.add(:active, 'must select one')\n    with_form_for @user, :active, as: :radio_buttons\n    assert_select \"input#user_active_true[type=radio][name='user[active]'][aria-invalid='true']\"\n    assert_select \"input#user_active_false[type=radio][name='user[active]'][aria-invalid='true']\"\n\n    with_form_for @user, :active, as: :check_boxes\n    assert_select \"input#user_active_true[type=checkbox][aria-invalid='true']\"\n    assert_select \"input#user_active_false[type=checkbox][aria-invalid='true']\"\n\n    with_form_for @user, :company_id, as: :select, error: true\n    assert_select \"select#user_company_id[aria-invalid='true']\"\n\n    @user.errors.add(:password, 'must not be blank')\n    with_form_for @user, :password\n    assert_select \"input#user_password[type=password][aria-invalid='true']\"\n  end\n\n  # FULL ERRORS\n\n  test 'full error generates a full error tag for the attribute' do\n    with_full_error_for @user, :name\n    assert_select 'span.error', \"Super User Name! cannot be blank\"\n  end\n\n  test 'full error generates a full error tag with a clean HTML' do\n    with_full_error_for @user, :name\n    assert_no_select 'span.error[error_html]'\n  end\n\n  test 'full error allows passing options to full error tag' do\n    with_full_error_for @user, :name, id: 'name_error', error_prefix: \"Your name\"\n    assert_select 'span.error#name_error', \"Your name cannot be blank\"\n  end\n\n  test 'full error does not modify the options hash' do\n    options = { id: 'name_error' }\n    with_full_error_for @user, :name, options\n    assert_select 'span.error#name_error', \"Super User Name! cannot be blank\"\n    assert_equal({ id: 'name_error' }, options)\n  end\n\n  test 'full error escapes error text' do\n    @user.errors.add(:action, 'must not contain <b>markup</b>')\n\n    with_full_error_for @user, :action\n\n    assert_select 'span.error'\n    assert_no_select 'span.error b', 'markup'\n  end\n\n  test 'full error uses human_attribute_name and passed object as an option to it' do\n    @user.errors.add(:status, 'error')\n    with_full_error_for @user, :status\n\n    assert_select 'span.error', \"\\[#{@user.id}\\] User Status! error\"\n  end\n\n  # CUSTOM WRAPPERS\n\n  test 'error with custom wrappers works' do\n    swap_wrapper do\n      with_error_for @user, :name\n      assert_select 'span.omg_error', \"cannot be blank\"\n    end\n  end\n\n  # FULL_ERROR_WRAPPER\n\n  test 'full error finds errors on association' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :company_id, as: :select\n      assert_select 'span.error', 'Company must be valid'\n    end\n  end\n\n  test 'full error finds errors on association with reflection' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :company_id, as: :select,\n        reflection: Association.new(Company, :company, {})\n      assert_select 'span.error', 'Company must be valid'\n    end\n  end\n\n  test 'full error can be disabled' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :company_id, as: :select, full_error: false\n      assert_no_select 'span.error'\n    end\n  end\n\n  test 'full error can be disabled setting error to false' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :company_id, as: :select, error: false\n      assert_no_select 'span.error'\n    end\n  end\n\n  # CUSTOM ERRORS\n\n  test 'input with custom error works' do\n    error_text = \"Super User Name! cannot be blank\"\n    with_form_for @user, :name, error: error_text\n\n    assert_select 'span.error', error_text\n  end\n\n  test 'input with error option as true does not use custom error' do\n    with_form_for @user, :name, error: true\n\n    assert_select 'span.error', \"cannot be blank\"\n  end\n\n  test 'input with custom error does not generate the error if there is no error on the attribute' do\n    with_form_for @user, :active, error: \"Super User Active! cannot be blank\"\n\n    assert_no_select 'span.error'\n  end\n\n  test 'input with custom error works when form does not use a model' do\n    with_form_for :user, :active, error: \"Super User Active! cannot be blank\"\n\n    assert_select 'span.error'\n  end\n\n  test 'input with custom error works when using full_error component' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      error_text = \"Super User Name! cannot be blank\"\n      with_form_for @user, :name, error: error_text\n\n      assert_select 'span.error', error_text\n    end\n  end\n\n  test 'input with custom error escapes the error text' do\n    with_form_for @user, :name, error: 'error must not contain <b>markup</b>'\n\n    assert_select 'span.error'\n    assert_no_select 'span.error b', 'markup'\n  end\n\n  test 'input with custom error does not escape the error text if it is safe' do\n    with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe\n\n    assert_select 'span.error'\n    assert_select 'span.error b', 'markup'\n  end\n\n  test 'input with custom error escapes the error text using full_error component' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :name, error: 'error must not contain <b>markup</b>'\n\n      assert_select 'span.error'\n      assert_no_select 'span.error b', 'markup'\n    end\n  end\n\n  test 'input with custom error does not escape the error text if it is safe using full_error component' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe\n\n      assert_select 'span.error'\n      assert_select 'span.error b', 'markup'\n    end\n  end\n\n  test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :active, error: \"Super User Active! can't be blank\"\n\n      assert_no_select 'span.error'\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/general_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass FormBuilderTest < ActionView::TestCase\n  def with_custom_form_for(object, *args, &block)\n    with_concat_custom_form_for(object) do |f|\n      f.input(*args, &block)\n    end\n  end\n\n  test 'nested simple fields yields an instance of FormBuilder' do\n    simple_form_for :user do |f|\n      f.simple_fields_for :posts do |posts_form|\n        assert posts_form.instance_of?(SimpleForm::FormBuilder)\n      end\n    end\n  end\n\n  test 'builder input is html safe' do\n    simple_form_for @user do |f|\n      assert f.input(:name).html_safe?\n    end\n  end\n\n  test 'builder works without controller' do\n    stub_any_instance ActionView::TestCase, :controller, nil do\n      simple_form_for @user do |f|\n        assert f.input(:name)\n      end\n    end\n  end\n\n  test 'builder works with decorated object responsive to #to_model' do\n    assert_nothing_raised do\n      with_form_for @decorated_user, :name\n    end\n  end\n\n  test 'builder input allows a block to configure input' do\n    with_form_for @user, :name do\n      text_field_tag :foo, :bar, id: :cool\n    end\n    assert_no_select 'input.string'\n    assert_select 'input#cool'\n  end\n\n  test 'builder allows adding custom input mappings for default input types' do\n    swap SimpleForm, input_mappings: { /count$/ => :integer } do\n      with_form_for @user, :post_count\n      assert_no_select 'form input#user_post_count.string'\n      assert_select 'form input#user_post_count.numeric.integer'\n    end\n  end\n\n  test 'builder does not override custom input mappings for custom collection' do\n    swap SimpleForm, input_mappings: { /gender$/ => :check_boxes } do\n      with_concat_form_for @user do |f|\n        f.input :gender, collection: %i[male female]\n      end\n\n      assert_no_select 'select option', 'Male'\n      assert_select 'input[type=checkbox][value=male]'\n    end\n  end\n\n  test 'builder allows to skip input_type class' do\n    swap SimpleForm, generate_additional_classes_for: %i[label wrapper] do\n      with_form_for @user, :post_count\n      assert_no_select \"form input#user_post_count.integer\"\n      assert_select \"form input#user_post_count\"\n    end\n  end\n\n  test 'builder allows to add additional classes only for wrapper' do\n    swap SimpleForm, generate_additional_classes_for: [:wrapper] do\n      with_form_for @user, :post_count\n      assert_no_select \"form input#user_post_count.string\"\n      assert_no_select \"form label#user_post_count.string\"\n      assert_select \"form div.input.string\"\n    end\n  end\n\n  test 'builder allows adding custom input mappings for integer input types' do\n    swap SimpleForm, input_mappings: { /lock_version/ => :hidden } do\n      with_form_for @user, :lock_version\n      assert_no_select 'form input#user_lock_version.integer'\n      assert_select 'form input#user_lock_version.hidden'\n    end\n  end\n\n  test 'builder uses the first matching custom input map when more than one matches' do\n    swap SimpleForm, input_mappings: { /count$/ => :integer, /^post_/ => :password } do\n      with_form_for @user, :post_count\n      assert_no_select 'form input#user_post_count.password'\n      assert_select 'form input#user_post_count.numeric.integer'\n    end\n  end\n\n  test 'builder uses the custom map only for matched attributes' do\n    swap SimpleForm, input_mappings: { /lock_version/ => :hidden } do\n      with_form_for @user, :post_count\n      assert_no_select 'form input#user_post_count.hidden'\n      assert_select 'form input#user_post_count.string'\n    end\n  end\n\n  test 'builder allow to use numbers in the model name' do\n    user = UserNumber1And2.build(tags: [Tag.new(nil, 'Tag1')])\n\n    with_concat_form_for(user, url: '/') do |f|\n      f.simple_fields_for(:tags) do |tags|\n        tags.input :name\n      end\n    end\n\n    assert_select 'form .user_number1_and2_tags_name'\n    assert_no_select 'form .user_number1_and2_tags_1_name'\n  end\n\n  # INPUT TYPES\n  test 'builder generates text fields for string columns' do\n    with_form_for @user, :name\n    assert_select 'form input#user_name.string'\n  end\n\n  test 'builder generates text areas for text columns' do\n    with_form_for @user, :description\n    assert_no_select 'form input#user_description.string'\n    assert_select 'form textarea#user_description.text'\n  end\n\n  test 'builder generates text areas for text columns when hinted' do\n    with_form_for @user, :description, as: :text\n    assert_no_select 'form input#user_description.string'\n    assert_select 'form textarea#user_description.text'\n  end\n\n  test 'builder generates text field for text columns when hinted' do\n    with_form_for @user, :description, as: :string\n    assert_no_select 'form textarea#user_description.text'\n    assert_select 'form input#user_description.string'\n  end\n\n  test 'builder generates text areas for hstore columns' do\n    with_form_for @user, :hstore\n    assert_no_select 'form input#user_hstore.string'\n    assert_select 'form textarea#user_hstore.text'\n  end\n\n  test 'builder generates text areas for json columns' do\n    with_form_for @user, :json\n    assert_no_select 'form input#user_json.string'\n    assert_select 'form textarea#user_json.text'\n  end\n\n  test 'builder generates text areas for jsonb columns' do\n    with_form_for @user, :jsonb\n    assert_no_select 'form input#user_jsonb.string'\n    assert_select 'form textarea#user_jsonb.text'\n  end\n\n  test 'builder generates a checkbox for boolean columns' do\n    with_form_for @user, :active\n    assert_select 'form input[type=checkbox]#user_active.boolean'\n  end\n\n  test 'builder uses integer text field for integer columns' do\n    with_form_for @user, :age\n    assert_select 'form input#user_age.numeric.integer'\n  end\n\n  test 'builder generates decimal text field for decimal columns' do\n    with_form_for @user, :credit_limit\n    assert_select 'form input#user_credit_limit.numeric.decimal'\n  end\n\n  test 'builder generates uuid fields for uuid columns' do\n    with_form_for @user, :uuid\n    if defined? ActiveModel::Type\n      assert_select 'form input#user_uuid.string.string'\n    else\n      assert_select 'form input#user_uuid.string.uuid'\n    end\n  end\n\n  test 'builder generates string fields for citext columns' do\n    with_form_for @user, :citext\n    assert_select 'form input#user_citext.string'\n  end\n\n  test 'builder generates password fields for columns that matches password' do\n    with_form_for @user, :password\n    assert_select 'form input#user_password.password'\n  end\n\n  test 'builder generates country fields for columns that matches country' do\n    with_form_for @user, :residence_country\n    assert_select 'form select#user_residence_country.country'\n  end\n\n  test 'builder generates time_zone fields for columns that matches time_zone' do\n    with_form_for @user, :time_zone\n    assert_select 'form select#user_time_zone.time_zone'\n  end\n\n  test 'builder generates email fields for columns that matches email' do\n    with_form_for @user, :email\n    assert_select 'form input#user_email.string.email'\n  end\n\n  test 'builder generates tel fields for columns that matches phone' do\n    with_form_for @user, :phone_number\n    assert_select 'form input#user_phone_number.string.tel'\n  end\n\n  test 'builder generates url fields for columns that matches url' do\n    with_form_for @user, :url\n    assert_select 'form input#user_url.string.url'\n  end\n\n  test 'builder generates date select for date columns' do\n    with_form_for @user, :born_at\n    assert_select 'form select#user_born_at_1i.date'\n  end\n\n  test 'builder generates time select for time columns' do\n    with_form_for @user, :delivery_time\n    assert_select 'form select#user_delivery_time_4i.time'\n  end\n\n  test 'builder generates datetime select for datetime columns' do\n    with_form_for @user, :created_at\n    assert_select 'form select#user_created_at_1i.datetime'\n  end\n\n  test 'builder generates datetime select for timestamp columns' do\n    with_form_for @user, :updated_at\n    assert_select 'form select#user_updated_at_1i.datetime'\n  end\n\n  test 'builder generates file input for ActiveStorage >= 5.2 and Refile >= 0.2.0 <= 0.4.0' do\n    with_form_for UserWithAttachment.build, :avatar\n    assert_select 'form input#user_with_attachment_avatar.file'\n  end\n\n  test 'builder generates file input for ActiveStorage::Attached::Many' do\n    with_form_for UserWithAttachment.build, :avatars\n    assert_select 'form input#user_with_attachment_avatars.file'\n  end\n\n  test 'builder generates file input for Refile >= 0.3.0 and CarrierWave >= 0.2.2' do\n    with_form_for UserWithAttachment.build, :cover\n    assert_select 'form input#user_with_attachment_cover.file'\n  end\n\n  test 'builder generates file input for Refile >= 0.4.0 and Shrine >= 0.9.0' do\n    with_form_for UserWithAttachment.build, :profile_image\n    assert_select 'form input#user_with_attachment_profile_image.file'\n  end\n\n  test 'builder generates file input for Paperclip ~> 2.0' do\n    with_form_for UserWithAttachment.build, :portrait\n    assert_select 'form input#user_with_attachment_portrait.file'\n  end\n\n  test 'build generates select if a collection is given' do\n    with_form_for @user, :age, collection: 1..60\n    assert_select 'form select#user_age.select'\n  end\n\n  test 'builder does not generate url fields for columns that contain only the letters url' do\n    with_form_for @user, :hourly\n    assert_no_select 'form input#user_url.string.url'\n    assert_select 'form input#user_hourly.string'\n  end\n\n  test 'builder allows overriding default input type for text' do\n    with_form_for @user, :name, as: :text\n    assert_no_select 'form input#user_name'\n    assert_select 'form textarea#user_name.text'\n  end\n\n  test 'builder allows overriding default input type for radio_buttons' do\n    with_form_for @user, :active, as: :radio_buttons\n    assert_no_select 'form input[type=checkbox]'\n    assert_select 'form input.radio_buttons[type=radio]', count: 2\n  end\n\n  test 'builder allows overriding default input type for string' do\n    with_form_for @user, :born_at, as: :string\n    assert_no_select 'form select'\n    assert_select 'form input#user_born_at.string'\n  end\n\n  # COMMON OPTIONS\n  # Remove this test when SimpleForm.form_class is removed in 4.x\n  test 'builder adds chosen form class' do\n    SimpleForm.deprecator.silence do\n      swap SimpleForm, form_class: :my_custom_class do\n        with_form_for @user, :name\n        assert_select 'form.my_custom_class'\n      end\n    end\n  end\n\n  # Remove this test when SimpleForm.form_class is removed in 4.x\n  test 'builder adds chosen form class and default form class' do\n    SimpleForm.deprecator.silence do\n      swap SimpleForm, form_class: \"my_custom_class\", default_form_class: \"my_default_class\" do\n        with_form_for @user, :name\n        assert_select 'form.my_custom_class.my_default_class'\n      end\n    end\n  end\n\n  test 'builder adds default form class' do\n    swap SimpleForm, default_form_class: \"default_class\" do\n      with_form_for @user, :name\n      assert_select 'form.default_class'\n    end\n  end\n\n  test 'builder allows passing options to input' do\n    with_form_for @user, :name, input_html: { class: 'my_input', id: 'my_input' }\n    assert_select 'form input#my_input.my_input.string'\n  end\n\n  test 'builder does not propagate input options to wrapper' do\n    with_form_for @user, :name, input_html: { class: 'my_input', id: 'my_input' }\n    assert_no_select 'form div.input.my_input.string'\n    assert_select 'form input#my_input.my_input.string'\n  end\n\n  test 'builder does not propagate input options to wrapper with custom wrapper' do\n    swap_wrapper :default, custom_wrapper_with_wrapped_input do\n      with_form_for @user, :name, input_html: { class: 'my_input' }\n      assert_no_select 'form div.input.my_input'\n      assert_select 'form input.my_input.string'\n    end\n  end\n\n  test 'builder does not propagate label options to wrapper with custom wrapper' do\n    swap_wrapper :default, custom_wrapper_with_wrapped_label do\n      with_form_for @user, :name, label_html: { class: 'my_label' }\n      assert_no_select 'form div.label.my_label'\n      assert_select 'form label.my_label.string'\n    end\n  end\n\n  test 'builder generates an input with label' do\n    with_form_for @user, :name\n    assert_select 'form label.string[for=user_name]', /Name/\n  end\n\n  test 'builder is able to disable the label for an input' do\n    with_form_for @user, :name, label: false\n    assert_no_select 'form label'\n  end\n\n  test 'builder is able to disable the label for an input and return a html safe string' do\n    with_form_for @user, :name, label: false, wrapper: custom_wrapper_with_wrapped_label_input\n    assert_select 'form input#user_name'\n  end\n\n  test 'builder uses custom label' do\n    with_form_for @user, :name, label: 'Yay!'\n    assert_select 'form label', /Yay!/\n  end\n\n  test 'builder passes options to label' do\n    with_form_for @user, :name, label_html: { id: \"cool\" }\n    assert_select 'form label#cool', /Name/\n  end\n\n  test 'builder does not generate hints for an input' do\n    with_form_for @user, :name\n    assert_no_select 'span.hint'\n  end\n\n  test 'builder is able to add a hint for an input' do\n    with_form_for @user, :name, hint: 'test'\n    assert_select 'span.hint', 'test'\n  end\n\n  test 'builder is able to disable a hint even if it exists in i18n' do\n    store_translations(:en, simple_form: { hints: { name: 'Hint test' } }) do\n      stub_any_instance(SimpleForm::Inputs::Base, :hint, -> { raise 'Never' }) do\n        with_form_for @user, :name, hint: false\n        assert_no_select 'span.hint'\n      end\n    end\n  end\n\n  test 'builder passes options to hint' do\n    with_form_for @user, :name, hint: 'test', hint_html: { id: \"cool\" }\n    assert_select 'span.hint#cool', 'test'\n  end\n\n  test 'builder generates errors for attribute without errors' do\n    with_form_for @user, :credit_limit\n    assert_no_select 'span.errors'\n  end\n\n  test 'builder generates errors for attribute with errors' do\n    with_form_for @user, :name\n    assert_select 'span.error', \"cannot be blank\"\n  end\n\n  test 'builder is able to disable showing errors for an input' do\n    with_form_for @user, :name, error: false\n    assert_no_select 'span.error'\n  end\n\n  test 'builder passes options to errors' do\n    with_form_for @user, :name, error_html: { id: \"cool\" }\n    assert_select 'span.error#cool', \"cannot be blank\"\n  end\n\n  test 'placeholder does not be generated when set to false' do\n    store_translations(:en, simple_form: { placeholders: { user: {\n      name: 'Name goes here'\n    } } }) do\n      with_form_for @user, :name, placeholder: false\n      assert_no_select 'input[placeholder]'\n    end\n  end\n\n  # DEFAULT OPTIONS\n  %i[input input_field].each do |method|\n    test \"builder receives a default argument and pass it to the inputs when calling '#{method}'\" do\n      with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|\n        f.public_send(method, :name)\n      end\n      assert_select 'input.default_class'\n    end\n\n    test \"builder receives a default argument and pass it to the inputs without changing the defaults when calling '#{method}'\" do\n      with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|\n        concat(f.public_send(method, :name))\n        concat(f.public_send(method, :credit_limit))\n      end\n\n      assert_select \"input.string.default_class[name='user[name]']\"\n      assert_no_select \"input.string[name='user[credit_limit]']\"\n    end\n\n    test \"builder receives a default argument and pass it to the inputs and nested form when calling '#{method}'\" do\n      @user.company = Company.new(1, 'Empresa')\n\n      with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|\n        concat(f.public_send(method, :name))\n        concat(f.simple_fields_for(:company) do |company_form|\n          concat(company_form.public_send(method, :name))\n        end)\n      end\n\n      assert_select \"input.string.default_class[name='user[name]']\"\n      assert_select \"input.string.default_class[name='user[company_attributes][name]']\"\n    end\n  end\n\n  test \"builder receives a default argument and pass it to the inputs when calling 'input', respecting the specific options\" do\n    with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|\n      f.input :name, input_html: { id: 'specific_id' }\n    end\n    assert_select 'input.default_class#specific_id'\n  end\n\n  test \"builder receives a default argument and pass it to the inputs when calling 'input_field', respecting the specific options\" do\n    with_concat_form_for @user, defaults: { input_html: { class: 'default_class' } } do |f|\n      f.input_field :name, id: 'specific_id'\n    end\n    assert_select 'input.default_class#specific_id'\n  end\n\n  test \"builder receives a default argument and pass it to the inputs when calling 'input', overwriting the defaults with specific options\" do\n    with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|\n      f.input :name, input_html: { id: 'specific_id' }\n    end\n    assert_select 'input.default_class#specific_id'\n  end\n\n  test \"builder receives a default argument and pass it to the inputs when calling 'input_field', overwriting the defaults with specific options\" do\n    with_concat_form_for @user, defaults: { input_html: { class: 'default_class', id: 'default_id' } } do |f|\n      f.input_field :name, id: 'specific_id'\n    end\n    assert_select 'input.default_class#specific_id'\n  end\n\n  # WITHOUT OBJECT\n  test 'builder generates properly when object is not present' do\n    with_form_for :project, :name\n    assert_select 'form input.string#project_name'\n  end\n\n  test 'builder generates password fields based on attribute name when object is not present' do\n    with_form_for :project, :password_confirmation\n    assert_select 'form input[type=password].password#project_password_confirmation'\n  end\n\n  test 'builder generates text fields by default for all attributes when object is not present' do\n    with_form_for :project, :created_at\n    assert_select 'form input.string#project_created_at'\n    with_form_for :project, :budget\n    assert_select 'form input.string#project_budget'\n  end\n\n  test 'builder allows overriding input type when object is not present' do\n    with_form_for :project, :created_at, as: :datetime\n    assert_select 'form select.datetime#project_created_at_1i'\n    with_form_for :project, :budget, as: :decimal\n    assert_select 'form input.decimal#project_budget'\n  end\n\n  # CUSTOM FORM BUILDER\n  test 'custom builder inherits mappings' do\n    with_custom_form_for @user, :email\n    assert_select 'form input[type=email]#user_email.custom'\n  end\n\n  test 'form with CustomMapTypeFormBuilder uses custom map type builder' do\n    with_concat_custom_mapping_form_for(:user) do |user|\n      assert user.instance_of?(CustomMapTypeFormBuilder)\n    end\n  end\n\n  test 'form with CustomMapTypeFormBuilder uses custom mapping' do\n    with_concat_custom_mapping_form_for(:user) do |user|\n      assert_equal SimpleForm::Inputs::StringInput, user.class.mappings[:custom_type]\n    end\n  end\n\n  test 'form without CustomMapTypeFormBuilder does not use custom mapping' do\n    with_concat_form_for(:user) do |user|\n      assert_nil user.class.mappings[:custom_type]\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/hint_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.hint\nclass HintTest < ActionView::TestCase\n  def with_hint_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.hint(*args)\n    end\n  end\n\n  test 'hint does not be generated by default' do\n    with_hint_for @user, :name\n    assert_no_select 'span.hint'\n  end\n\n  test 'hint is generated with optional text' do\n    with_hint_for @user, :name, hint: 'Use with care...'\n    assert_select 'span.hint', 'Use with care...'\n  end\n\n  test 'hint is generated with decorated object responsive to #to_model' do\n    with_hint_for @decorated_user, :name, hint: 'Use with care...'\n    assert_select 'span.hint', 'Use with care...'\n  end\n\n  test 'hint does not modify the options hash' do\n    options = { hint: 'Use with care...' }\n    with_hint_for @user, :name, options\n    assert_select 'span.hint', 'Use with care...'\n    assert_equal({ hint: 'Use with care...' }, options)\n  end\n\n  test 'hint is generated cleanly with optional text' do\n    with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :span\n    assert_no_select 'span.hint[hint]'\n    assert_no_select 'span.hint[hint_tag]'\n    assert_no_select 'span.hint[hint_html]'\n  end\n\n  test 'hint uses the current component tag set' do\n    with_hint_for @user, :name, hint: 'Use with care...', hint_tag: :p\n    assert_select 'p.hint', 'Use with care...'\n  end\n\n  test 'hint is able to pass html options' do\n    with_hint_for @user, :name, hint: 'Yay!', id: 'hint', class: 'yay'\n    assert_select 'span#hint.hint.yay'\n  end\n\n  test 'hint is output as html_safe' do\n    with_hint_for @user, :name, hint: '<b>Bold</b> and not...'.html_safe\n    assert_select 'span.hint', 'Bold and not...'\n    assert_select 'span.hint b', 'Bold'\n  end\n\n  test 'builder escapes hint text' do\n    with_hint_for @user, :name, hint: '<script>alert(1337)</script>'\n    assert_no_select 'span.hint script'\n  end\n\n  # Without attribute name\n\n  test 'hint without attribute name' do\n    with_hint_for @validating_user, 'Hello World!'\n    assert_select 'span.hint', 'Hello World!'\n  end\n\n  test 'hint without attribute name generates component tag with a clean HTML' do\n    with_hint_for @validating_user, 'Hello World!'\n    assert_no_select 'span.hint[hint]'\n    assert_no_select 'span.hint[hint_html]'\n  end\n\n  test 'hint without attribute name uses the current component tag set' do\n    with_hint_for @user, 'Hello World!', hint_tag: :p\n    assert_no_select 'p.hint[hint]'\n    assert_no_select 'p.hint[hint_html]'\n    assert_no_select 'p.hint[hint_tag]'\n  end\n\n  test 'hint without attribute name is able to pass html options' do\n    with_hint_for @user, 'Yay', id: 'hint', class: 'yay'\n    assert_select 'span#hint.hint.yay', 'Yay'\n  end\n\n  # I18n\n\n  test 'hint uses i18n based on model, action, and attribute to lookup translation' do\n    store_translations(:en, simple_form: { hints: { user: {\n      edit: { name: 'Content of this input will be truncated...' }\n    } } }) do\n      with_hint_for @user, :name\n      assert_select 'span.hint', 'Content of this input will be truncated...'\n    end\n  end\n\n  test 'hint uses i18n with model and attribute to lookup translation' do\n    store_translations(:en, simple_form: { hints: { user: {\n      name: 'Content of this input will be capitalized...'\n    } } }) do\n      with_hint_for @user, :name\n      assert_select 'span.hint', 'Content of this input will be capitalized...'\n    end\n  end\n\n  test 'hint uses i18n under defaults namespace to lookup translation' do\n    store_translations(:en, simple_form: {\n      hints: { defaults: { name: 'Content of this input will be downcased...' } }\n    }) do\n      with_hint_for @user, :name\n      assert_select 'span.hint', 'Content of this input will be downcased...'\n    end\n  end\n\n  test 'hint uses i18n with lookup for association name' do\n    store_translations(:en, simple_form: { hints: {\n      user: { company: 'My company!' }\n    } } ) do\n      with_hint_for @user, :company_id, as: :string, reflection: Association.new(Company, :company, {})\n      assert_select 'span.hint', /My company!/\n    end\n  end\n\n  test 'hint outputs translations as html_safe' do\n    store_translations(:en, simple_form: { hints: { user: {\n      edit: { name: '<b>This is bold</b> and this is not...' }\n    } } }) do\n      with_hint_for @user, :name\n      assert_select 'span.hint', 'This is bold and this is not...'\n    end\n  end\n\n\n  # No object\n\n  test 'hint generates properly when object is not present' do\n    with_hint_for :project, :name, hint: 'Test without object'\n    assert_select 'span.hint', 'Test without object'\n  end\n\n  # Custom wrappers\n\n  test 'hint with custom wrappers works' do\n    swap_wrapper do\n      with_hint_for @user, :name, hint: \"cannot be blank\"\n      assert_select 'div.omg_hint', \"cannot be blank\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/input_field_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\n# Tests for f.input_field\nclass InputFieldTest < ActionView::TestCase\n  test \"builder input_field only renders the input tag, nothing else\" do\n    with_input_field_for @user, :name\n\n    assert_select 'form > input.required.string'\n    assert_no_select 'div.string'\n    assert_no_select 'label'\n    assert_no_select '.hint'\n  end\n\n  test 'builder input_field allows overriding default input type' do\n    with_input_field_for @user, :name, as: :text\n\n    assert_no_select 'input#user_name'\n    assert_select 'textarea#user_name.text'\n  end\n\n  test 'builder input_field generates input type based on column type' do\n    with_input_field_for @user, :age\n\n    assert_select 'input[type=number].integer#user_age'\n  end\n\n  test 'builder input_field is able to disable any component' do\n    with_input_field_for @user, :age, html5: false\n\n    assert_no_select 'input[html5=false]#user_age'\n    assert_select 'input[type=text].integer#user_age'\n  end\n\n  test 'builder input_field allows passing options to input tag' do\n    with_input_field_for @user, :name, id: 'name_input', class: 'name'\n\n    assert_select 'input.string.name#name_input'\n  end\n\n  test 'builder input_field does not modify the options hash' do\n    options = { id: 'name_input', class: 'name' }\n    with_input_field_for @user, :name, options\n\n    assert_select 'input.string.name#name_input'\n    assert_equal({ id: 'name_input', class: 'name' }, options)\n  end\n\n\n  test 'builder input_field generates an input tag with a clean HTML' do\n    with_input_field_for @user, :name, as: :integer, class: 'name'\n\n    assert_no_select 'input.integer[input_html]'\n    assert_no_select 'input.integer[as]'\n  end\n\n  test 'builder input_field uses i18n to translate placeholder text' do\n    store_translations(:en, simple_form: { placeholders: { user: {\n      name: 'Name goes here'\n    } } }) do\n      with_input_field_for @user, :name\n\n      assert_select 'input.string[placeholder=\"Name goes here\"]'\n    end\n  end\n\n  test 'builder input_field uses min_max component' do\n    with_input_field_for @other_validating_user, :age, as: :integer\n\n    assert_select 'input[min=\"18\"]'\n  end\n\n  test 'builder input_field does not use pattern component by default' do\n    with_input_field_for @other_validating_user, :country, as: :string\n\n    assert_no_select 'input[pattern=\"\\w+\"]'\n  end\n\n  test 'builder input_field infers pattern from attributes' do\n    with_input_field_for @other_validating_user, :country, as: :string, pattern: true\n\n    assert_select \"input:match('pattern', ?)\", /\\w+/\n  end\n\n  test 'builder input_field accepts custom pattern' do\n    with_input_field_for @other_validating_user, :country, as: :string, pattern: '\\d+'\n\n    assert_select \"input:match('pattern', ?)\", /\\\\d+/\n  end\n\n  test 'builder input_field uses readonly component' do\n    with_input_field_for @other_validating_user, :age, as: :integer, readonly: true\n\n    assert_select 'input.integer.readonly[readonly]'\n  end\n\n  test 'builder input_field uses maxlength component' do\n    with_input_field_for @validating_user, :name, as: :string\n\n    assert_select 'input.string[maxlength=\"25\"]'\n  end\n\n  test 'builder input_field uses minlength component' do\n    with_input_field_for @validating_user, :name, as: :string\n\n    assert_select 'input.string[minlength=\"5\"]'\n  end\n\n  test 'builder collection input_field generates input tag with a clean HTML' do\n    with_input_field_for @user, :status, collection: %w[Open Closed],\n      class: 'status', label_method: :to_s, value_method: :to_s\n\n    assert_no_select 'select.status[input_html]'\n    assert_no_select 'select.status[collection]'\n    assert_no_select 'select.status[label_method]'\n    assert_no_select 'select.status[value_method]'\n  end\n\n  test 'build input_field does not treat \"boolean_style\" as a HTML attribute' do\n    with_input_field_for @user, :active, boolean_style: :nested\n\n    assert_no_select 'input.boolean[boolean_style]'\n  end\n\n  test 'build input_field does not treat \"prompt\" as a HTML attribute' do\n    with_input_field_for @user, :attempts, collection: [1,2,3,4,5], prompt: :translate\n\n    assert_no_select 'select[prompt]'\n  end\n\n  test 'build input_field without pattern component use the pattern string' do\n    swap_wrapper :default, custom_wrapper_with_html5_components do\n      with_input_field_for @user, :name, pattern: '\\w+'\n\n      assert_select \"input:match('pattern', ?)\", /\\w+/\n    end\n  end\n\n  test 'build input_field without placeholder component use the placeholder string' do\n    swap_wrapper :default, custom_wrapper_with_html5_components do\n      with_input_field_for @user, :name, placeholder: 'Placeholder'\n\n      assert_select 'input[placeholder=\"Placeholder\"]'\n    end\n  end\n\n  test 'build input_field without maxlength component use the maxlength string' do\n    swap_wrapper :default, custom_wrapper_with_html5_components do\n      with_input_field_for @user, :name, maxlength: 5\n\n      assert_select 'input[maxlength=\"5\"]'\n    end\n  end\n\n  test 'build input_field without minlength component use the minlength string' do\n    swap_wrapper :default, custom_wrapper_with_html5_components do\n      with_input_field_for @user, :name, minlength: 5\n\n      assert_select 'input[minlength=\"5\"]'\n    end\n  end\n\n  test 'build input_field without readonly component use the readonly string' do\n    swap_wrapper :default, custom_wrapper_with_html5_components do\n      with_input_field_for @user, :name, readonly: true\n\n      assert_select 'input[readonly=\"readonly\"]'\n    end\n  end\n\n  test 'adds valid class to input_field when it is configured' do\n    swap SimpleForm, input_field_valid_class: 'is-valid' do\n      @user.instance_eval { undef errors }\n      with_input_field_for @user, :name\n\n      assert_select 'input.string.required.is-valid'\n    end\n  end\n\n  test 'adds error class to input_field when it is configured' do\n    swap SimpleForm, input_field_error_class: 'is-invalid' do\n      with_input_field_for @user, :name\n\n      assert_select 'input.string.required.is-invalid'\n    end\n  end\n\n  test 'does not add validation classes to input_field when it is not configured' do\n    swap SimpleForm, input_field_error_class: nil, input_field_valid_class: nil do\n      with_input_field_for @user, :name\n\n      assert_select 'input.string.required'\n    end\n  end\nend\n"
  },
  {
    "path": "test/form_builder/label_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass LabelTest < ActionView::TestCase\n  def with_label_for(object, *args, &block)\n    with_concat_form_for(object) do |f|\n      f.label(*args, &block)\n    end\n  end\n\n  test 'builder generates a label for the attribute' do\n    with_label_for @user, :name\n    assert_select 'label.string[for=user_name]', /Name/\n  end\n\n  test 'builder generates a label for the attribute with decorated object responsive to #to_model' do\n    with_label_for @decorated_user, :name\n    assert_select 'label.string[for=user_name]', /Name/\n  end\n\n  test 'builder generates a label for the boolean attribute' do\n    with_label_for @user, :name, as: :boolean\n    assert_select 'label.boolean[for=user_name]', /Name/\n    assert_no_select 'label[as=boolean]'\n  end\n\n  test 'builder generates a label component tag with a clean HTML' do\n    with_label_for @user, :name\n    assert_no_select 'label.string[label_html]'\n  end\n\n  test 'builder adds a required class to label if the attribute is required' do\n    with_label_for @validating_user, :name\n    assert_select 'label.string.required[for=validating_user_name]', /Name/\n  end\n\n  test 'builder adds a disabled class to label if the attribute is disabled' do\n    with_label_for @validating_user, :name, disabled: true\n    assert_select 'label.string.disabled[for=validating_user_name]', /Name/\n  end\n\n  test 'builder does not add a disabled class to label if the attribute is not disabled' do\n    with_label_for @validating_user, :name, disabled: false\n    assert_no_select 'label.string.disabled[for=validating_user_name]', /Name/\n  end\n\n  test 'builder escapes label text' do\n    with_label_for @user, :name, label: '<script>alert(1337)</script>', required: false\n    assert_no_select 'label.string script'\n  end\n\n  test 'builder does not escape label text if it is safe' do\n    with_label_for @user, :name, label: '<script>alert(1337)</script>'.html_safe, required: false\n    assert_select 'label.string script', \"alert(1337)\"\n  end\n\n  test 'builder allows passing options to label tag' do\n    with_label_for @user, :name, label: 'My label', id: 'name_label'\n    assert_select 'label.string#name_label', /My label/\n  end\n\n  test 'builder label generates label tag with clean HTML' do\n    with_label_for @user, :name, label: 'My label', required: true, id: 'name_label'\n    assert_select 'label.string#name_label', /My label/\n    assert_no_select 'label[label]'\n    assert_no_select 'label[required]'\n  end\n\n  test 'builder does not modify the options hash' do\n    options = { label: 'My label', id: 'name_label' }\n    with_label_for @user, :name, options\n    assert_select 'label.string#name_label', /My label/\n    assert_equal({ label: 'My label', id: 'name_label' }, options)\n  end\n\n  test 'builder fallbacks to default label when string is given' do\n    with_label_for @user, :name, 'Nome do usuário'\n    assert_select 'label', 'Nome do usuário'\n    assert_no_select 'label.string'\n  end\n\n  test 'builder fallbacks to default label when block is given' do\n    with_label_for @user, :name do\n      'Nome do usuário'\n    end\n    assert_select 'label', 'Nome do usuário'\n    assert_no_select 'label.string'\n  end\n\n  test 'builder allows label order to be changed' do\n    swap SimpleForm, label_text: proc { |l, r| \"#{l}:\" } do\n      with_label_for @user, :age\n      assert_select 'label.integer[for=user_age]', \"Age:\"\n    end\n  end\n\n  test 'configuration allow set label text for wrappers' do\n    swap_wrapper :default, custom_wrapper_with_label_text do\n      with_concat_form_for(@user) do |f|\n        concat f.input :age\n      end\n      assert_select \"label.integer[for=user_age]\", \"**Age**\"\n    end\n  end\n\n  test 'configuration allow set rewritten label tag for wrappers' do\n    swap_wrapper :default, custom_wrapper_with_custom_label_component do\n      with_concat_form_for(@user) do |f|\n        concat f.input :age\n      end\n      assert_select \"span.integer.user_age\", /Age/\n    end\n  end\n\n  test 'builder allows custom formatting when label is explicitly specified' do\n    swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : \"#{l.titleize}:\" } do\n      with_label_for @user, :time_zone, 'What is your home time zone?'\n      assert_select 'label[for=user_time_zone]', 'What is your home time zone?'\n    end\n  end\n\n  test 'builder allows custom formatting when label is generated' do\n    swap SimpleForm, label_text: ->(l, r, explicit_label) { explicit_label ? l : \"#{l.titleize}:\" } do\n      with_label_for @user, :time_zone\n      assert_select 'label[for=user_time_zone]', 'Time Zone:'\n    end\n  end\n\n  test 'builder allows label specific `label_text` option' do\n    with_label_for @user, :time_zone, label_text: ->(l, _, _) { \"#{l.titleize}:\" }\n\n    assert_no_select 'label[label_text]'\n    assert_select 'label[for=user_time_zone]', 'Time Zone:'\n  end\nend\n"
  },
  {
    "path": "test/form_builder/wrapper_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass WrapperTest < ActionView::TestCase\n  test 'wrapper does not have error class for attribute without errors' do\n    with_form_for @user, :active\n    assert_no_select 'div.field_with_errors'\n  end\n\n  test 'wrapper does not have error class when object is not present' do\n    with_form_for :project, :name\n    assert_no_select 'div.field_with_errors'\n  end\n\n  test 'wrapper adds the attribute name class' do\n    with_form_for @user, :name\n    assert_select 'div.user_name'\n  end\n\n  test 'wrapper adds the attribute name class for nested forms' do\n    @user.company = Company.new(1, 'Empresa')\n    with_concat_form_for @user do |f|\n      concat(f.simple_fields_for(:company) do |company_form|\n        concat(company_form.input :name)\n      end)\n    end\n\n    assert_select 'div.user_company_name'\n  end\n\n  test 'wrapper adds the association name class' do\n    with_form_for @user, :company\n    assert_select 'div.user_company'\n  end\n\n  test 'wrapper adds error class for attribute with errors' do\n    with_form_for @user, :name\n    assert_select 'div.field_with_errors'\n  end\n\n  test 'wrapper adds error class to input for attribute with errors' do\n    with_form_for @user, :name, wrapper: custom_wrapper_with_input_error_class\n    assert_select 'div.field_with_errors'\n    assert_select 'input.is-invalid'\n  end\n\n  test 'wrapper does not add error class to input when the attribute is valid' do\n    with_form_for @user, :phone_number, wrapper: custom_wrapper_with_input_error_class\n    assert_no_select 'div.field_with_errors'\n    assert_no_select 'input.is-invalid'\n  end\n\n  test 'wrapper adds valid class for present attribute without errors' do\n    @user.instance_eval { undef errors }\n    with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class\n    assert_select 'div.field_without_errors'\n    assert_select 'input.is-valid'\n    assert_no_select 'div.field_with_errors'\n    assert_no_select 'input.is-invalid'\n  end\n\n  test 'wrapper does not determine if valid class is needed when it is set to nil' do\n    @user.instance_eval { undef errors }\n    with_form_for @user, :name, wrapper: custom_wrapper_with_input_valid_class(valid_class: nil)\n\n    assert_no_select 'div.field_without_errors'\n  end\n\n  test 'wrapper adds hint class for attribute with a hint' do\n    with_form_for @user, :name, hint: 'hint'\n    assert_select 'div.field_with_hint'\n  end\n\n  test 'wrapper does not have disabled class by default' do\n    with_form_for @user, :active\n    assert_no_select 'div.disabled'\n  end\n\n  test 'wrapper has disabled class when input is disabled' do\n    with_form_for @user, :active, disabled: true\n    assert_select 'div.disabled'\n  end\n\n  test 'wrapper supports no wrapping when wrapper is false' do\n    with_form_for @user, :name, wrapper: false\n    assert_select 'form > label[for=user_name]'\n    assert_select 'form > input#user_name.string'\n  end\n\n  test 'wrapper supports no wrapping when wrapper tag is false' do\n    with_form_for @user, :name, wrapper: custom_wrapper_without_top_level\n    assert_select 'form > label[for=user_name]'\n    assert_select 'form > input#user_name.string'\n  end\n\n  test 'wrapper wraps tag adds required/optional css classes' do\n    with_form_for @user, :name\n    assert_select 'form div.input.required.string'\n\n    with_form_for @user, :age, required: false\n    assert_select 'form div.input.optional.integer'\n  end\n\n  test 'wrapper allows custom options to be given' do\n    with_form_for @user, :name, wrapper_html: { id: \"super_cool\", class: 'yay' }\n    assert_select 'form #super_cool.required.string.yay'\n  end\n\n  test 'wrapper allows tag to be given on demand' do\n    with_form_for @user, :name, wrapper_tag: :b\n    assert_select 'form b.required.string'\n  end\n\n  test 'wrapper allows wrapper class to be given on demand' do\n    with_form_for @user, :name, wrapper_class: :wrapper\n    assert_select 'form div.wrapper.required.string'\n  end\n\n  test 'wrapper skips additional classes when configured' do\n    swap SimpleForm, generate_additional_classes_for: %i[input label] do\n      with_form_for @user, :name, wrapper_class: :wrapper\n      assert_select 'form div.wrapper'\n      assert_no_select 'div.required'\n      assert_no_select 'div.string'\n      assert_no_select 'div.user_name'\n    end\n  end\n\n  test 'wrapper does not generate empty css class' do\n    swap SimpleForm, generate_additional_classes_for: %i[input label] do\n      swap_wrapper :default, custom_wrapper_without_class do\n        with_form_for @user, :name\n        assert_no_select 'div#custom_wrapper_without_class[class]'\n      end\n    end\n  end\n\n  # Custom wrapper test\n\n  test 'custom wrappers works' do\n    swap_wrapper do\n      with_form_for @user, :name, hint: \"cool\"\n      assert_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n      assert_no_select \"section.custom_wrapper div.another_wrapper span.omg_error\"\n      assert_select \"section.custom_wrapper div.error_wrapper span.omg_error\"\n      assert_select \"section.custom_wrapper > div.omg_hint\", \"cool\"\n    end\n  end\n\n  test 'custom wrappers can be turned off' do\n    swap_wrapper do\n      with_form_for @user, :name, another: false\n      assert_no_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_no_select \"section.custom_wrapper div.another_wrapper input.string\"\n      assert_select \"section.custom_wrapper div.error_wrapper span.omg_error\"\n    end\n  end\n\n  test 'custom wrappers can have additional attributes' do\n    swap_wrapper :default, custom_wrapper_with_additional_attributes do\n      with_form_for @user, :name\n\n      assert_select \"div.custom_wrapper[title='some title'][data-wrapper='test']\"\n    end\n  end\n\n  test 'custom wrappers can have full error message on attributes' do\n    swap_wrapper :default, custom_wrapper_with_full_error do\n      with_form_for @user, :name\n      assert_select 'span.error', \"Super User Name! cannot be blank\"\n    end\n  end\n\n  test 'custom wrappers on a form basis' do\n    swap_wrapper :another do\n      with_concat_form_for(@user) do |f|\n        f.input :name\n      end\n\n      assert_no_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_no_select \"section.custom_wrapper div.another_wrapper input.string\"\n\n      with_concat_form_for(@user, wrapper: :another) do |f|\n        f.input :name\n      end\n\n      assert_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n    end\n  end\n\n  test 'custom wrappers on input basis' do\n    swap_wrapper :another do\n      with_form_for @user, :name\n      assert_no_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_no_select \"section.custom_wrapper div.another_wrapper input.string\"\n      output_buffer.to_s.replace \"\"\n\n      with_form_for @user, :name, wrapper: :another\n      assert_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n      output_buffer.to_s.replace \"\"\n    end\n\n    with_form_for @user, :name, wrapper: custom_wrapper\n    assert_select \"section.custom_wrapper div.another_wrapper label\"\n    assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n  end\n\n  test 'access wrappers with indifferent access' do\n    swap_wrapper :another do\n      with_form_for @user, :name, wrapper: \"another\"\n      assert_select \"section.custom_wrapper div.another_wrapper label\"\n      assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n    end\n  end\n\n  test 'does not duplicate label classes for different inputs' do\n    swap_wrapper :default, custom_wrapper_with_label_html_option do\n      with_concat_form_for(@user) do |f|\n        concat f.input :name, required: false\n        concat f.input :email, as: :email, required: true\n      end\n\n      assert_select \"label.string.optional.extra-label-class[for='user_name']\"\n      assert_select \"label.email.required.extra-label-class[for='user_email']\"\n      assert_no_select \"label.string.optional.extra-label-class[for='user_email']\"\n    end\n  end\n\n  test 'raise error when wrapper not found' do\n    assert_raise SimpleForm::WrapperNotFound do\n      with_form_for @user, :name, wrapper: :not_found\n    end\n  end\n\n  test 'uses wrapper for specified in config mapping' do\n    swap_wrapper :another do\n      swap SimpleForm, wrapper_mappings: { string: :another } do\n        with_form_for @user, :name\n        assert_select \"section.custom_wrapper div.another_wrapper label\"\n        assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n      end\n    end\n  end\n\n  test 'uses custom wrapper mapping per form basis' do\n    swap_wrapper :another do\n      with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|\n        concat f.input :name\n      end\n    end\n\n    assert_select \"section.custom_wrapper div.another_wrapper label\"\n    assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n  end\n\n  test 'simple_fields_form reuses custom wrapper mapping per form basis' do\n    @user.company = Company.new(1, 'Empresa')\n\n    swap_wrapper :another do\n      with_concat_form_for @user, wrapper_mappings: { string: :another } do |f|\n        concat(f.simple_fields_for(:company) do |company_form|\n          concat(company_form.input(:name))\n        end)\n      end\n    end\n\n    assert_select \"section.custom_wrapper div.another_wrapper label\"\n    assert_select \"section.custom_wrapper div.another_wrapper input.string\"\n  end\n\n  test \"input attributes class will merge with wrapper_options' classes\" do\n    swap_wrapper :default, custom_wrapper_with_input_class do\n      with_concat_form_for @user do |f|\n        concat f.input :name, input_html: { class: 'another-class' }\n      end\n    end\n\n    assert_select \"div.custom_wrapper input.string.inline-class.another-class\"\n  end\n\n  test \"input with data attributes will merge with wrapper_options' data\" do\n    swap_wrapper :default, custom_wrapper_with_input_data_modal do\n      with_concat_form_for @user do |f|\n        concat f.input :name, input_html: { data: { modal: 'another-data', target: 'merge-data' } }\n      end\n    end\n\n    assert_select \"input[data-wrapper='data-wrapper'][data-modal='another-data'][data-target='merge-data']\"\n  end\n\n  test \"input with aria attributes will merge with wrapper_options' aria\" do\n    swap_wrapper :default, custom_wrapper_with_input_aria_modal do\n      with_concat_form_for @user do |f|\n        concat f.input :name, input_html: { aria: { modal: 'another-aria', target: 'merge-aria' } }\n      end\n    end\n\n    assert_select \"input[aria-wrapper='aria-wrapper'][aria-modal='another-aria'][aria-target='merge-aria']\"\n  end\n\n  test 'input accepts attributes in the DSL' do\n    swap_wrapper :default, custom_wrapper_with_input_class do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n      end\n    end\n\n    assert_select \"div.custom_wrapper input.string.inline-class\"\n  end\n\n  test 'label accepts attributes in the DSL' do\n    swap_wrapper :default, custom_wrapper_with_label_class do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n      end\n    end\n\n    assert_select \"div.custom_wrapper label.string.inline-class\"\n  end\n\n  test 'label_input accepts attributes in the DSL' do\n    swap_wrapper :default, custom_wrapper_with_label_input_class do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n      end\n    end\n\n    assert_select \"div.custom_wrapper label.string.inline-class\"\n    assert_select \"div.custom_wrapper input.string.inline-class\"\n  end\n\n  test 'input accepts data attributes in the DSL' do\n    swap_wrapper :default, custom_wrapper_with_input_attributes do\n      with_concat_form_for @user do |f|\n        concat f.input :name\n      end\n    end\n\n    assert_select \"div.custom_wrapper input.string[data-modal=true]\"\n  end\n\n  test 'inline wrapper displays when there is content' do\n    swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do\n      with_form_for @user, :name, hint: \"cannot be blank\"\n      assert_select 'section.custom_wrapper div.no_output_wrapper p.omg_hint', \"cannot be blank\"\n      assert_select 'p.omg_hint'\n    end\n  end\n\n  test 'inline wrapper does not display when there is no content' do\n    swap_wrapper :default, custom_wrapper_with_wrapped_optional_component do\n      with_form_for @user, :name\n      assert_select 'section.custom_wrapper div.no_output_wrapper'\n      assert_no_select 'p.omg_hint'\n    end\n  end\n\n  test 'optional wrapper does not display when there is content' do\n    swap_wrapper :default, custom_wrapper_with_unless_blank do\n      with_form_for @user, :name, hint: \"can't be blank\"\n      assert_select 'section.custom_wrapper div.no_output_wrapper'\n      assert_select 'div.no_output_wrapper'\n      assert_select 'p.omg_hint'\n    end\n  end\n\n  test 'optional wrapper does not display when there is no content' do\n    swap_wrapper :default, custom_wrapper_with_unless_blank do\n      with_form_for @user, :name\n      assert_no_select 'section.custom_wrapper div.no_output_wrapper'\n      assert_no_select 'div.no_output_wrapper'\n      assert_no_select 'p.omg_hint'\n    end\n  end\nend\n"
  },
  {
    "path": "test/generators/simple_form_generator_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass SimpleFormGeneratorTest < Rails::Generators::TestCase\n  tests SimpleForm::Generators::InstallGenerator\n  destination File.expand_path('../../tmp', __FILE__)\n  setup :prepare_destination\n  teardown { rm_rf(destination_root) }\n\n  test 'generates example locale file' do\n    run_generator\n    assert_file 'config/locales/simple_form.en.yml'\n  end\n\n  test 'generates the simple_form initializer' do\n    run_generator\n    assert_file 'config/initializers/simple_form.rb',\n      /config\\.default_wrapper = :default/, /config\\.boolean_style = :nested/\n  end\n\n  test 'generates the simple_form initializer with the bootstrap wrappers' do\n    run_generator %w[--bootstrap]\n    assert_file 'config/initializers/simple_form.rb',\n      /config\\.default_wrapper = :default/, /config\\.boolean_style = :nested/\n    assert_file 'config/initializers/simple_form_bootstrap.rb', /config\\.wrappers :vertical_form/,\n      /config\\.wrappers :horizontal_form/, /config\\.default_wrapper = :vertical_form/\n  end\n\n  test 'generates the simple_form initializer with the foundation wrappers' do\n    run_generator %w[--foundation]\n    assert_file 'config/initializers/simple_form.rb',\n      /config\\.default_wrapper = :default/, /config\\.boolean_style = :nested/\n    assert_file 'config/initializers/simple_form_foundation.rb', /config\\.wrappers :vertical_form/,\n      /config\\.default_wrapper = :vertical_form/, /config\\.item_wrapper_tag = :div/\n  end\n\n  %w[erb haml slim].each do |engine|\n    test \"generates the scaffold template when using #{engine}\" do\n      run_generator ['-e', engine]\n      assert_file \"lib/templates/#{engine}/scaffold/_form.html.#{engine}\"\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/boolean_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass BooleanInputTest < ActionView::TestCase\n  test 'input generates a checkbox by default for boolean attributes' do\n    with_input_for @user, :active, :boolean\n    assert_select 'input[type=checkbox].boolean#user_active'\n    assert_select 'label.boolean.optional', 'Active'\n  end\n\n  test 'input does not generate the label with the checkbox when label option is false' do\n    with_input_for @user, :active, :boolean, label: false\n    assert_select 'input[type=checkbox].boolean#user_active'\n    assert_no_select 'label'\n  end\n\n  test 'input uses custom checked value' do\n    @user.action = 'on'\n    with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'\n    assert_select 'input[type=checkbox][value=on][checked=checked]'\n  end\n\n  test 'input uses custom unchecked value' do\n    @user.action = 'off'\n    with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'\n    assert_select 'input[type=checkbox][value=on]'\n    assert_no_select 'input[checked=checked][value=on]'\n  end\n\n  test 'input generates hidden input with custom unchecked value' do\n    with_input_for @user, :action, :boolean, checked_value: 'on', unchecked_value: 'off'\n    assert_select 'input[type=hidden][value=off]'\n  end\n\n  test 'input allows skipping hidden input when setting :include_hidden to false' do\n    with_input_for @user, :active, :boolean, include_hidden: false\n    assert_no_select \"input[type=hidden][name='user[active]']\"\n  end\n\n  test 'input uses inline boolean style by default' do\n    with_input_for @user, :active, :boolean\n    assert_select 'input.boolean + label.boolean.optional'\n    assert_no_select 'label > input'\n  end\n\n  test 'input allows changing default boolean style config to nested, generating a default label and a manual hidden field for checkbox' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean\n      assert_select 'label[for=user_active]', 'Active'\n      assert_select 'label.boolean > input.boolean'\n      assert_no_select 'input[type=checkbox] + label'\n    end\n  end\n\n  test 'input boolean with nested allows :inline_label' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: 'I am so inline.'\n      assert_select 'label.checkbox', text: ' I am so inline.'\n    end\n  end\n\n  test 'input boolean with nested escapes :inline_label with HTML' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'\n      assert_no_select 'label.checkbox b'\n    end\n  end\n\n  test 'input boolean with nested allows :inline_label with HTML when safe' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: '<b>I am so inline.</b>'.html_safe\n      assert_select 'label.checkbox b', text: 'I am so inline.'\n    end\n  end\n\n  test 'input boolean with nested style creates an inline label using the default label text when inline_label option set to true' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: true\n      assert_select 'label.checkbox', text: ' Active'\n    end\n  end\n\n  test 'input boolean with nested style creates an inline label using the label text when inline_label option set to true' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { 'New Active' }\n      assert_select 'label.checkbox', text: ' New Active'\n    end\n  end\n\n  test 'input boolean with nested style creates an inline label using the label html when inline_label option set to true' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, inline_label: true, label_text: proc { '<b>New Active</b>' }\n      assert_select 'label.checkbox', text: ' New Active'\n    end\n  end\n\n  test 'input boolean with nested generates a manual hidden field for checkbox outside the label, to recreate Rails functionality with valid html5' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean\n\n      assert_select \"input[type=hidden][name='user[active]'] + label.boolean > input.boolean\"\n      assert_no_select 'input[type=checkbox] + label'\n    end\n  end\n\n  test 'input boolean with nested generates a disabled hidden field for checkbox outside the label, if the field is disabled' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, disabled: true\n\n      assert_select \"input[type=hidden][name='user[active]'][disabled] + label.boolean > input.boolean[disabled]\"\n    end\n  end\n\n  test 'input boolean with nested generates a disabled hidden field with the form attribute when it is given' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, input_html: { form: 'form_id' }\n\n      assert_select \"input[type=hidden][form=form_id]+ label.boolean > input.boolean\"\n    end\n  end\n\n  test 'input accepts changing boolean style to nested through given options' do\n    with_input_for @user, :active, :boolean, boolean_style: :nested\n    assert_select 'label[for=user_active]', 'Active'\n    assert_select 'label.boolean > input.boolean'\n    assert_no_select 'input[type=checkbox] + label'\n  end\n\n  test 'input accepts changing boolean style to inline through given options, when default is nested' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, boolean_style: :inline\n      assert_select 'label[for=user_active]', 'Active'\n      assert_select 'input.boolean + label.boolean'\n      assert_no_select 'label > input'\n    end\n  end\n\n  test 'input with nested style allows disabling label' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, label: false\n      assert_select 'input.boolean'\n      assert_no_select 'label.boolean'\n    end\n  end\n\n  test 'input with nested style allows customizing input_html' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, input_html: { name: 'active_user' }\n      assert_select \"input[type=hidden][name=active_user] + label.boolean > input.boolean[name=active_user]\"\n    end\n  end\n\n  test 'input with nested style allows disabling hidden field' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, include_hidden: false\n      assert_select \"label.boolean > input.boolean\"\n      assert_no_select \"input[type=hidden] + label.boolean\"\n    end\n  end\n\n  test 'input with nested style and with single wrapper allows disabling hidden field' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, include_hidden: false, wrapper: custom_wrapper_with_wrapped_label_input\n      assert_select \"label.boolean > input.boolean\"\n      assert_no_select \"input[type=hidden] + label.boolean\"\n    end\n  end\n\n  test 'input with nested style does not include hidden field when unchecked_value is false' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :boolean, unchecked_value: false\n      assert_select \"label.boolean > input.boolean\"\n      assert_no_select \"input[type=hidden] + label.boolean\"\n    end\n  end\n\n  test 'input boolean works using :input only in wrapper config (no label_input)' do\n    swap_wrapper do\n      with_input_for @user, :active, :boolean\n\n      assert_select 'label.boolean + input[type=hidden] + input.boolean'\n      assert_no_select 'label.checkbox'\n    end\n  end\n\n  test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra \"checkbox\" label wrapper' do\n    swap_wrapper do\n      swap SimpleForm, boolean_style: :nested do\n        with_input_for @user, :active, :boolean\n\n        assert_select 'label.boolean + input[type=hidden] + label.checkbox > input.boolean'\n      end\n    end\n  end\n\n  test 'input boolean allows specifying boolean_label_class on a per-input basis' do\n    swap_wrapper do\n      swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do\n        with_input_for @user, :active, :boolean, boolean_label_class: 'baz'\n\n        assert_select 'label.boolean + input[type=hidden] + label.baz > input.boolean'\n      end\n    end\n  end\n\n  test 'input boolean with nested style works using :input only in wrapper config (no label_input), adding the extra label wrapper with custom class' do\n    swap_wrapper do\n      swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do\n        with_input_for @user, :active, :boolean\n\n        assert_select 'label.boolean + input[type=hidden] + label.foo > input.boolean'\n      end\n    end\n  end\n\n  test 'input boolean with nested style works using :label_input in wrapper config, adding \"checkbox\" class to label' do\n    swap_wrapper :default, self.custom_wrapper_without_top_level do\n      swap SimpleForm, boolean_style: :nested do\n        with_input_for @user, :active, :boolean\n\n        assert_select 'input[type=hidden] + label.boolean.checkbox > input.boolean'\n      end\n    end\n  end\n\n  test 'input boolean with nested style works using :label_input in wrapper config, adding custom class to label' do\n    swap_wrapper :default, self.custom_wrapper_without_top_level do\n      swap SimpleForm, boolean_style: :nested, boolean_label_class: 'foo' do\n        with_input_for @user, :active, :boolean\n\n        assert_select 'input[type=hidden] + label.boolean.foo > input.boolean'\n      end\n    end\n  end\n\n  test 'input boolean without additional classes adds \"checkbox\" class to label' do\n    swap_wrapper :default, self.custom_wrapper_without_top_level do\n      swap SimpleForm, boolean_style: :nested, generate_additional_classes_for: [:input] do\n        with_input_for @user, :active, :boolean\n\n        assert_select 'label'\n        assert_select 'label.checkbox'\n        assert_no_select 'label.boolean'\n      end\n    end\n  end\n\n  test 'input boolean works with wrapper config defining a class for the input' do\n    swap_wrapper :default, self.custom_wrapper_with_input_class do\n      with_input_for @user, :active, :boolean\n\n      assert_select 'input.boolean.inline-class'\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/collection_check_boxes_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionCheckBoxesInputTest < ActionView::TestCase\n  test 'input check boxes does not include for attribute by default' do\n    with_input_for @user, :gender, :check_boxes, collection: %i[male female]\n    assert_select 'label'\n    assert_no_select 'label[for=user_gender]'\n  end\n\n  test 'input check boxes includes for attribute when giving as html option' do\n    with_input_for @user, :gender, :check_boxes, collection: %i[male female], label_html: { for: 'gender' }\n    assert_select 'label[for=gender]'\n  end\n\n  test 'collection input with check_boxes type does not generate required html attribute' do\n    with_input_for @user, :name, :check_boxes, collection: %w[Jose Carlos]\n    assert_select 'input.required'\n    assert_no_select 'input[required]'\n  end\n\n  test 'input does automatic collection translation for check_box types using defaults key' do\n    store_translations(:en, simple_form: { options: { defaults: {\n      gender: { male: 'Male', female: 'Female' }\n    } } } ) do\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female]\n      assert_select 'input[type=checkbox][value=male]'\n      assert_select 'input[type=checkbox][value=female]'\n      assert_select 'label.collection_check_boxes', 'Male'\n      assert_select 'label.collection_check_boxes', 'Female'\n    end\n  end\n\n  test 'input does automatic collection translation for check_box types using specific object key' do\n    store_translations(:en, simple_form: { options: { user: {\n      gender: { male: 'Male', female: 'Female' }\n    } } } ) do\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female]\n      assert_select 'input[type=checkbox][value=male]'\n      assert_select 'input[type=checkbox][value=female]'\n      assert_select 'label.collection_check_boxes', 'Male'\n      assert_select 'label.collection_check_boxes', 'Female'\n    end\n  end\n\n  test 'input that uses automatic collection translation for check_boxes properly sets checked values' do\n    store_translations(:en, simple_form: { options: { defaults: {\n      gender: { male: 'Male', female: 'Female' }\n    } } } ) do\n      @user.gender = 'male'\n\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female]\n      assert_select 'input[type=checkbox][value=male][checked=checked]'\n      assert_select 'input[type=checkbox][value=female]'\n      assert_select 'label.collection_check_boxes', 'Male'\n      assert_select 'label.collection_check_boxes', 'Female'\n    end\n  end\n\n  test 'input check boxes does not wrap the collection by default' do\n    with_input_for @user, :active, :check_boxes\n\n    assert_select 'form input[type=checkbox]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test 'input check boxes accepts html options as the last element of collection' do\n    with_input_for @user, :name, :check_boxes, collection: [['Jose', 'jose', class: 'foo']]\n    assert_select 'input.foo[type=checkbox][value=jose]'\n  end\n\n  test 'input check boxes wraps the collection in the configured collection wrapper tag' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form ul input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes does not wrap the collection when configured with falsy values' do\n    swap SimpleForm, collection_wrapper_tag: false do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form input[type=checkbox]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input check boxes allows overriding the collection wrapper tag at input level' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :check_boxes, collection_wrapper_tag: :section\n\n      assert_select 'form section input[type=checkbox]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input check boxes allows disabling the collection wrapper tag at input level' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :check_boxes, collection_wrapper_tag: false\n\n      assert_select 'form input[type=checkbox]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input check boxes renders the wrapper tag with the configured wrapper class' do\n    swap SimpleForm, collection_wrapper_tag: :ul, collection_wrapper_class: 'inputs-list' do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form ul.inputs-list input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes allows giving wrapper class at input level only' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :check_boxes, collection_wrapper_class: 'items-list'\n\n      assert_select 'form ul.items-list input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes uses both configured and given wrapper classes for wrapper tag' do\n    swap SimpleForm, collection_wrapper_tag: :ul, collection_wrapper_class: 'inputs-list' do\n      with_input_for @user, :active, :check_boxes, collection_wrapper_class: 'items-list'\n\n      assert_select 'form ul.inputs-list.items-list input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes wraps each item in the configured item wrapper tag' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form li input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes does not wrap items when configured with falsy values' do\n    swap SimpleForm, item_wrapper_tag: false do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form input[type=checkbox]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input check boxes allows overriding the item wrapper tag at input level' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :check_boxes, item_wrapper_tag: :dl\n\n      assert_select 'form dl input[type=checkbox]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input check boxes allows disabling the item wrapper tag at input level' do\n    swap SimpleForm, item_wrapper_tag: :ul do\n      with_input_for @user, :active, :check_boxes, item_wrapper_tag: false\n\n      assert_select 'form input[type=checkbox]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input check boxes wraps items in a span tag by default' do\n    with_input_for @user, :active, :check_boxes\n\n    assert_select 'form span input[type=checkbox]', count: 2\n  end\n\n  test 'input check boxes renders the item wrapper tag with a default class \"checkbox\"' do\n    with_input_for @user, :active, :check_boxes, item_wrapper_tag: :li\n\n    assert_select 'form li.checkbox input[type=checkbox]', count: 2\n  end\n\n  test 'input check boxes renders the item wrapper tag with the configured item wrapper class' do\n    swap SimpleForm, item_wrapper_tag: :li, item_wrapper_class: 'item' do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'form li.checkbox.item input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes allows giving item wrapper class at input level only' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :check_boxes, item_wrapper_class: 'item'\n\n      assert_select 'form li.checkbox.item input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes uses both configured and given item wrapper classes for item wrapper tag' do\n    swap SimpleForm, item_wrapper_tag: :li, item_wrapper_class: 'item' do\n      with_input_for @user, :active, :check_boxes, item_wrapper_class: 'inline'\n\n      assert_select 'form li.checkbox.item.inline input[type=checkbox]', count: 2\n    end\n  end\n\n  test 'input check boxes respects the nested boolean style config, generating nested label > input' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'span.checkbox > label > input#user_active_true[type=checkbox]'\n      assert_select 'span.checkbox > label', 'Yes'\n      assert_select 'span.checkbox > label > input#user_active_false[type=checkbox]'\n      assert_select 'span.checkbox > label', 'No'\n      assert_no_select 'label.collection_radio_buttons'\n    end\n  end\n\n  test 'input check boxes with nested style does not overrides configured item wrapper tag' do\n    swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do\n      with_input_for @user, :active, :check_boxes\n\n      assert_select 'li.checkbox > label > input'\n    end\n  end\n\n  test 'input check boxes with nested style does not overrides given item wrapper tag' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :check_boxes, item_wrapper_tag: :li\n\n      assert_select 'li.checkbox > label > input'\n    end\n  end\n\n  test 'input check boxes with nested style accepts giving extra wrapper classes' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :check_boxes, item_wrapper_class: \"inline\"\n\n      assert_select 'span.checkbox.inline > label > input'\n    end\n  end\n\n  test 'input check boxes with nested style renders item labels with specified class' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :check_boxes, item_label_class: \"test\"\n\n      assert_select 'span.checkbox > label.test > input'\n    end\n  end\n\n  test 'input check boxes with nested style and falsey input wrapper renders item labels with specified class' do\n    swap SimpleForm, boolean_style: :nested, item_wrapper_tag: false do\n      with_input_for @user, :active, :check_boxes, item_label_class: \"checkbox-inline\"\n\n      assert_select 'label.checkbox-inline > input'\n      assert_no_select 'span.checkbox'\n    end\n  end\n\n  test 'input check boxes wrapper class are not included when set to falsey' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female]\n\n      assert_no_select 'label.checkbox'\n    end\n  end\n\n  test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female], item_wrapper_class: 'custom'\n\n      assert_no_select 'label.checkbox'\n      assert_select 'span.custom'\n    end\n  end\n\n  test 'input check boxes with nested style and namespace uses the right for attribute' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_concat_form_for @user, namespace: :foo do |f|\n        concat f.input :gender, as: :check_boxes, collection: %i[male female]\n      end\n\n      assert_select 'label[for=foo_user_gender_male]'\n      assert_select 'label[for=foo_user_gender_female]'\n    end\n  end\n\n  test 'input check boxes with nested style and index uses the right for attribute' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_concat_form_for @user, index: 1 do |f|\n        concat f.input :gender, as: :check_boxes, collection: %i[male female]\n      end\n\n      assert_select 'label[for=user_1_gender_male]'\n      assert_select 'label[for=user_1_gender_female]'\n    end\n  end\n\n  test 'input check boxes with nested style accepts non-string attribute as label' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :amount,\n                            :check_boxes,\n                            collection: { 100 => 'hundred', 200 => 'two_hundred' },\n                            label_method: :first,\n                            value_method: :second\n\n      assert_select 'input[type=checkbox][value=hundred]'\n      assert_select 'input[type=checkbox][value=two_hundred]'\n      assert_select 'span.checkbox > label', '100'\n      assert_select 'span.checkbox > label', '200'\n    end\n  end\n\n  test 'input check boxes with inline style support label custom classes' do\n    swap SimpleForm, boolean_style: :inline do\n      with_input_for @user, :gender, :check_boxes, collection: %i[male female], item_label_class: 'beautiful-label'\n\n      assert_select 'label.beautiful-label', count: 2\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/collection_radio_buttons_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionRadioButtonsInputTest < ActionView::TestCase\n  test 'input generates boolean radio buttons by default for radio types' do\n    with_input_for @user, :active, :radio_buttons\n    assert_select 'input[type=radio][value=true].radio_buttons#user_active_true'\n    assert_select 'input[type=radio][value=false].radio_buttons#user_active_false'\n  end\n\n  test 'input as radio generates internal labels by default' do\n    with_input_for @user, :active, :radio_buttons\n    assert_select 'label[for=user_active_true]', 'Yes'\n    assert_select 'label[for=user_active_false]', 'No'\n  end\n\n  test 'input as radio generates internal labels with accurate `for` values with nested boolean style' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons\n      assert_select 'label[for=user_active_true]', 'Yes'\n      assert_select 'label[for=user_active_false]', 'No'\n    end\n  end\n\n  test 'nested label does not duplicate input id' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons, id: 'nested_id'\n      assert_select 'input#user_active_true'\n      assert_no_select 'label#user_active_true'\n    end\n  end\n\n  test 'input as radio uses i18n to translate internal labels' do\n    store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do\n      with_input_for @user, :active, :radio_buttons\n      assert_select 'label[for=user_active_true]', 'Sim'\n      assert_select 'label[for=user_active_false]', 'Não'\n    end\n  end\n\n  test 'input radio does not include for attribute by default' do\n    with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n    assert_select 'label'\n    assert_no_select 'label[for=user_gender]'\n  end\n\n  test 'input radio includes for attribute when giving as html option' do\n    with_input_for @user, :gender, :radio_buttons, collection: %i[male female], label_html: { for: 'gender' }\n    assert_select 'label[for=gender]'\n  end\n\n  test 'input marks the checked value when using boolean and radios' do\n    @user.active = false\n    with_input_for @user, :active, :radio_buttons\n    assert_no_select 'input[type=radio][value=true][checked]'\n    assert_select 'input[type=radio][value=false][checked]'\n  end\n\n  test 'input allows overriding collection for radio types' do\n    with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]\n    assert_select 'input[type=radio][value=Jose]'\n    assert_select 'input[type=radio][value=Carlos]'\n    assert_select 'label.collection_radio_buttons[for=user_name_jose]', 'Jose'\n    assert_select 'label.collection_radio_buttons[for=user_name_carlos]', 'Carlos'\n  end\n\n  test 'input does automatic collection translation for radio types using defaults key' do\n    store_translations(:en, simple_form: { options: { defaults: {\n      gender: { male: 'Male', female: 'Female' }\n    } } } ) do\n      with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n      assert_select 'input[type=radio][value=male]'\n      assert_select 'input[type=radio][value=female]'\n      assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'\n      assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'\n    end\n  end\n\n  test 'input does automatic collection translation for radio types using specific object key' do\n    store_translations(:en, simple_form: { options: { user: {\n      gender: { male: 'Male', female: 'Female' }\n    } } } ) do\n      with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n      assert_select 'input[type=radio][value=male]'\n      assert_select 'input[type=radio][value=female]'\n      assert_select 'label.collection_radio_buttons[for=user_gender_male]', 'Male'\n      assert_select 'label.collection_radio_buttons[for=user_gender_female]', 'Female'\n    end\n  end\n\n  test 'input does automatic collection translation and preserve html markup' do\n    swap SimpleForm, boolean_style: :nested do\n      store_translations(:en, simple_form: { options: { user: {\n        gender: { male_html: '<strong>Male</strong>', female_html: '<strong>Female</strong>' }\n      } } } ) do\n        with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n        assert_select 'input[type=radio][value=male]'\n        assert_select 'input[type=radio][value=female]'\n        assert_select 'label[for=user_gender_male] strong', 'Male'\n        assert_select 'label[for=user_gender_female] strong', 'Female'\n      end\n    end\n  end\n\n  test 'input does automatic collection translation with keys prefixed with _html and a string value' do\n    swap SimpleForm, boolean_style: :nested do\n      store_translations(:en, simple_form: { options: { user: {\n        gender: { male_html: 'Male', female_html: 'Female' }\n      } } } ) do\n        with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n        assert_select 'input[type=radio][value=male]'\n        assert_select 'input[type=radio][value=female]'\n        assert_select 'label[for=user_gender_male]', 'Male'\n        assert_select 'label[for=user_gender_female]', 'Female'\n      end\n    end\n  end\n\n  test 'input marks the current radio value by default' do\n    @user.name = \"Carlos\"\n    with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]\n    assert_select 'input[type=radio][value=Carlos][checked=checked]'\n  end\n\n  test 'input accepts html options as the last element of collection' do\n    with_input_for @user, :name, :radio_buttons, collection: [['Jose', 'jose', class: 'foo']]\n    assert_select 'input.foo[type=radio][value=jose]'\n  end\n\n  test 'input allows using a collection with text/value arrays' do\n    with_input_for @user, :name, :radio_buttons, collection: [%w[Jose jose], %w[Carlos carlos]]\n    assert_select 'input[type=radio][value=jose]'\n    assert_select 'input[type=radio][value=carlos]'\n    assert_select 'label.collection_radio_buttons', 'Jose'\n    assert_select 'label.collection_radio_buttons', 'Carlos'\n  end\n\n  test 'input allows using a collection with a Proc' do\n    with_input_for @user, :name, :radio_buttons, collection: proc { %w[Jose Carlos] }\n    assert_select 'label.collection_radio_buttons', 'Jose'\n    assert_select 'label.collection_radio_buttons', 'Carlos'\n  end\n\n  test 'input allows overriding only label method for collections' do\n    with_input_for @user, :name, :radio_buttons,\n                          collection: %w[Jose Carlos],\n                          label_method: :upcase\n    assert_select 'label.collection_radio_buttons', 'JOSE'\n    assert_select 'label.collection_radio_buttons', 'CARLOS'\n  end\n\n  test 'input allows overriding only value method for collections' do\n    with_input_for @user, :name, :radio_buttons,\n                          collection: %w[Jose Carlos],\n                          value_method: :upcase\n    assert_select 'input[type=radio][value=JOSE]'\n    assert_select 'input[type=radio][value=CARLOS]'\n  end\n\n  test 'input allows overriding label and value method for collections' do\n    with_input_for @user, :name, :radio_buttons,\n                          collection: %w[Jose Carlos],\n                          label_method: :upcase,\n                          value_method: :downcase\n    assert_select 'input[type=radio][value=jose]'\n    assert_select 'input[type=radio][value=carlos]'\n    assert_select 'label.collection_radio_buttons', 'JOSE'\n    assert_select 'label.collection_radio_buttons', 'CARLOS'\n  end\n\n  test 'input allows overriding label and value method using a lambda for collections' do\n    with_input_for @user, :name, :radio_buttons,\n                          collection: %w[Jose Carlos],\n                          label_method: ->(i) { i.upcase },\n                          value_method: ->(i) { i.downcase }\n    assert_select 'input[type=radio][value=jose]'\n    assert_select 'input[type=radio][value=carlos]'\n    assert_select 'label.collection_radio_buttons', 'JOSE'\n    assert_select 'label.collection_radio_buttons', 'CARLOS'\n  end\n\n  test 'collection input with radio type generates required html attribute' do\n    with_input_for @user, :name, :radio_buttons, collection: %w[Jose Carlos]\n    assert_select 'input[type=radio].required'\n    assert_select 'input[type=radio][required]'\n  end\n\n  test 'input radio does not wrap the collection by default' do\n    with_input_for @user, :active, :radio_buttons\n\n    assert_select 'form input[type=radio]', count: 2\n    assert_no_select 'form ul'\n  end\n\n  test 'input radio wraps the collection in the configured collection wrapper tag' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form ul input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio does not wrap the collection when configured with falsy values' do\n    swap SimpleForm, collection_wrapper_tag: false do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form input[type=radio]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input radio allows overriding the collection wrapper tag at input level' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :radio_buttons, collection_wrapper_tag: :section\n\n      assert_select 'form section input[type=radio]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input radio allows disabling the collection wrapper tag at input level' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :radio_buttons, collection_wrapper_tag: false\n\n      assert_select 'form input[type=radio]', count: 2\n      assert_no_select 'form ul'\n    end\n  end\n\n  test 'input radio renders the wrapper tag with the configured wrapper class' do\n    swap SimpleForm, collection_wrapper_tag: :ul, collection_wrapper_class: 'inputs-list' do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form ul.inputs-list input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio allows giving wrapper class at input level only' do\n    swap SimpleForm, collection_wrapper_tag: :ul do\n      with_input_for @user, :active, :radio_buttons, collection_wrapper_class: 'items-list'\n\n      assert_select 'form ul.items-list input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio uses both configured and given wrapper classes for wrapper tag' do\n    swap SimpleForm, collection_wrapper_tag: :ul, collection_wrapper_class: 'inputs-list' do\n      with_input_for @user, :active, :radio_buttons, collection_wrapper_class: 'items-list'\n\n      assert_select 'form ul.inputs-list.items-list input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio wraps each item in the configured item wrapper tag' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form li input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio does not wrap items when configured with falsy values' do\n    swap SimpleForm, item_wrapper_tag: false do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form input[type=radio]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input radio allows overriding the item wrapper tag at input level' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :dl\n\n      assert_select 'form dl input[type=radio]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input radio allows disabling the item wrapper tag at input level' do\n    swap SimpleForm, item_wrapper_tag: :ul do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_tag: false\n\n      assert_select 'form input[type=radio]', count: 2\n      assert_no_select 'form li'\n    end\n  end\n\n  test 'input radio wraps items in a span tag by default' do\n    with_input_for @user, :active, :radio_buttons\n\n    assert_select 'form span input[type=radio]', count: 2\n  end\n\n  test 'input radio renders the item wrapper tag with a default class \"radio\"' do\n    with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :li\n\n    assert_select 'form li.radio input[type=radio]', count: 2\n  end\n\n  test 'input radio renders the item wrapper tag with the configured item wrapper class' do\n    swap SimpleForm, item_wrapper_tag: :li, item_wrapper_class: 'item' do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'form li.radio.item input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio allows giving item wrapper class at input level only' do\n    swap SimpleForm, item_wrapper_tag: :li do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_class: 'item'\n\n      assert_select 'form li.radio.item input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio uses both configured and given item wrapper classes for item wrapper tag' do\n    swap SimpleForm, item_wrapper_tag: :li, item_wrapper_class: 'item' do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_class: 'inline'\n\n      assert_select 'form li.radio.item.inline input[type=radio]', count: 2\n    end\n  end\n\n  test 'input radio respects the nested boolean style config, generating nested label > input' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'span.radio > label > input#user_active_true[type=radio]'\n      assert_select 'span.radio > label', 'Yes'\n      assert_select 'span.radio > label > input#user_active_false[type=radio]'\n      assert_select 'span.radio > label', 'No'\n      assert_no_select 'label.collection_radio_buttons'\n    end\n  end\n\n  test 'input radio with nested style does not overrides configured item wrapper tag' do\n    swap SimpleForm, boolean_style: :nested, item_wrapper_tag: :li do\n      with_input_for @user, :active, :radio_buttons\n\n      assert_select 'li.radio > label > input'\n    end\n  end\n\n  test 'input radio with nested style does not overrides given item wrapper tag' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_tag: :li\n\n      assert_select 'li.radio > label > input'\n    end\n  end\n\n  test 'input radio with nested style accepts giving extra wrapper classes' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons, item_wrapper_class: \"inline\"\n\n      assert_select 'span.radio.inline > label > input'\n    end\n  end\n\n  test 'input radio with nested style renders item labels with specified class' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :active, :radio_buttons, item_label_class: \"test\"\n\n      assert_select 'span.radio > label.test > input'\n    end\n  end\n\n  test 'input radio with nested style and falsey input wrapper renders item labels with specified class' do\n    swap SimpleForm, boolean_style: :nested, item_wrapper_tag: false do\n      with_input_for @user, :active, :radio_buttons, item_label_class: \"radio-inline\"\n\n      assert_select 'label.radio-inline > input'\n      assert_no_select 'span.radio'\n    end\n  end\n\n  test 'input radio wrapper class are not included when set to falsey' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_input_for @user, :gender, :radio_buttons, collection: %i[male female]\n\n      assert_no_select 'label.radio'\n    end\n  end\n\n  test 'input radio custom wrapper class is included when include input wrapper class is falsey' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_input_for @user, :gender, :radio_buttons, collection: %i[male female], item_wrapper_class: 'custom'\n\n      assert_no_select 'label.radio'\n      assert_select 'span.custom'\n    end\n  end\n\n  test 'input radio with nested style and namespace uses the right for attribute' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_concat_form_for @user, namespace: :foo do |f|\n        concat f.input :gender, as: :radio_buttons, collection: %i[male female]\n      end\n\n      assert_select 'label[for=foo_user_gender_male]'\n      assert_select 'label[for=foo_user_gender_female]'\n    end\n  end\n\n  test 'input radio with nested style and index uses the right for attribute' do\n    swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do\n      with_concat_form_for @user, index: 1 do |f|\n        concat f.input :gender, as: :radio_buttons, collection: %i[male female]\n      end\n\n      assert_select 'label[for=user_1_gender_male]'\n      assert_select 'label[for=user_1_gender_female]'\n    end\n  end\n\n  test 'input radio with nested style accetps non-string attribute as label' do\n    swap SimpleForm, boolean_style: :nested do\n      with_input_for @user, :amount,\n                            :radio_buttons,\n                            collection: { 100 => 'hundred', 200 => 'two_hundred' },\n                            label_method: :first,\n                            value_method: :second\n\n      assert_select 'input[type=radio][value=hundred]'\n      assert_select 'input[type=radio][value=two_hundred]'\n      assert_select 'span.radio > label', '100'\n      assert_select 'span.radio > label', '200'\n    end\n  end\n\n  test 'input check boxes with inline style support label custom classes' do\n    swap SimpleForm, boolean_style: :inline do\n      with_input_for @user, :gender, :radio_buttons, collection: %i[male female], item_label_class: 'beautiful-label'\n\n      assert_select 'label.beautiful-label', count: 2\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/collection_select_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CollectionSelectInputTest < ActionView::TestCase\n  test 'input generates a boolean select with options by default for select types' do\n    with_input_for @user, :active, :select\n    assert_select 'select.select#user_active'\n    assert_select 'select option[value=true]', 'Yes'\n    assert_select 'select option[value=false]', 'No'\n  end\n\n  test 'input as select uses i18n to translate select boolean options' do\n    store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do\n      with_input_for @user, :active, :select\n      assert_select 'select option[value=true]', 'Sim'\n      assert_select 'select option[value=false]', 'Não'\n    end\n  end\n\n  test 'input allows overriding collection for select types' do\n    with_input_for @user, :name, :select, collection: %w[Jose Carlos]\n    assert_select 'select.select#user_name'\n    assert_select 'select option', 'Jose'\n    assert_select 'select option', 'Carlos'\n  end\n\n  test 'input does automatic collection translation for select types using defaults key' do\n    store_translations(:en, simple_form: { options: { defaults: {\n      gender: { male: 'Male', female: 'Female' }\n    } } }) do\n      with_input_for @user, :gender, :select, collection: %i[male female]\n      assert_select 'select.select#user_gender'\n      assert_select 'select option', 'Male'\n      assert_select 'select option', 'Female'\n    end\n  end\n\n  test 'input does automatic collection translation for select types using specific object key' do\n    store_translations(:en, simple_form: { options: { user: {\n      gender: { male: 'Male', female: 'Female' }\n    } } }) do\n      with_input_for @user, :gender, :select, collection: %i[male female]\n      assert_select 'select.select#user_gender'\n      assert_select 'select option', 'Male'\n      assert_select 'select option', 'Female'\n    end\n  end\n\n  test 'input marks the selected value by default' do\n    @user.name = \"Carlos\"\n    with_input_for @user, :name, :select, collection: %w[Jose Carlos]\n    assert_select 'select option[selected=selected]', 'Carlos'\n  end\n\n  test 'input accepts html options as the last element of collection' do\n    with_input_for @user, :name, :select, collection: [['Jose', class: 'foo']]\n    assert_select 'select.select#user_name'\n    assert_select 'select option.foo', 'Jose'\n  end\n\n  test 'input marks the selected value also when using integers' do\n    @user.age = 18\n    with_input_for @user, :age, :select, collection: 18..60\n    assert_select 'select option[selected=selected]', '18'\n  end\n\n  test 'input marks the selected value when using booleans and select' do\n    @user.active = false\n    with_input_for @user, :active, :select\n    assert_no_select 'select option[selected][value=true]', 'Yes'\n    assert_select 'select option[selected][value=false]', 'No'\n  end\n\n  test 'input sets the correct value when using a collection that includes floats' do\n    with_input_for @user, :age, :select, collection: [2.0, 2.5, 3.0, 3.5, 4.0, 4.5]\n    assert_select 'select option[value=\"2.0\"]'\n    assert_select 'select option[value=\"2.5\"]'\n  end\n\n  test 'input sets the correct values when using a collection that uses mixed values' do\n    with_input_for @user, :age, :select, collection: [\"Hello Kitty\", 2, 4.5, :johnny, nil, true, false]\n    assert_select 'select option[value=\"Hello Kitty\"]'\n    assert_select 'select option[value=\"2\"]'\n    assert_select 'select option[value=\"4.5\"]'\n    assert_select 'select option[value=\"johnny\"]'\n    assert_select 'select option[value=\"\"]'\n    assert_select 'select option[value=\"true\"]'\n    assert_select 'select option[value=\"false\"]'\n  end\n\n  test 'input includes a blank option even if :include_blank is set to false if the collection includes a nil value' do\n    with_input_for @user, :age, :select, collection: [nil], include_blank: false\n    assert_select 'select option[value=\"\"]'\n  end\n\n  test 'input automatically sets include blank' do\n    with_input_for @user, :age, :select, collection: 18..30\n    assert_select 'select option[value=\"\"]', ''\n  end\n\n  test 'input translates include blank when set to :translate' do\n    store_translations(:en, simple_form: { include_blanks: { user: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate\n      assert_select 'select option[value=\"\"]', 'Rather not say'\n    end\n  end\n\n  test 'input translates include blank with a default' do\n    store_translations(:en, simple_form: { include_blanks: { defaults: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, include_blank: :translate\n      assert_select 'select option[value=\"\"]', 'Rather not say'\n    end\n  end\n\n  test 'input does not translate include blank when set to a string' do\n    store_translations(:en, simple_form: { include_blanks: { user: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, include_blank: 'Young at heart'\n      assert_select 'select option[value=\"\"]', 'Young at heart'\n    end\n  end\n\n  test 'input does not translate include blank when automatically set' do\n    store_translations(:en, simple_form: { include_blanks: { user: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30\n      assert_select 'select option[value=\"\"]', ''\n    end\n  end\n\n  test 'input does not translate include blank when set to true' do\n    store_translations(:en, simple_form: { include_blanks: { user: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, include_blank: true\n      assert_select 'select option[value=\"\"]', ''\n    end\n  end\n\n  test 'input does not translate include blank when set to false' do\n    store_translations(:en, simple_form: { include_blanks: { user: {\n      age: 'Rather not say'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, include_blank: false\n      assert_no_select 'select option[value=\"\"]'\n    end\n  end\n\n  test 'input does not set include blank if otherwise is told' do\n    with_input_for @user, :age, :select, collection: 18..30, include_blank: false\n    assert_no_select 'select option[value=\"\"]'\n  end\n\n  test 'input does not set include blank if prompt is given' do\n    with_input_for @user, :age, :select, collection: 18..30, prompt: \"Please select foo\"\n    assert_no_select 'select option[value=\"\"]', ''\n  end\n\n  test 'input does not set include blank if multiple is given' do\n    with_input_for @user, :age, :select, collection: 18..30, input_html: { multiple: true }\n    assert_no_select 'select option[value=\"\"]', ''\n  end\n\n  test 'input translates prompt when set to :translate' do\n    store_translations(:en, simple_form: { prompts: { user: {\n      age: 'Select age:'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, prompt: :translate\n      assert_select 'select option[value=\"\"]', 'Select age:'\n    end\n  end\n\n  test 'input translates prompt with a default' do\n    store_translations(:en, simple_form: { prompts: { defaults: {\n      age: 'Select age:'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, prompt: :translate\n      assert_select 'select option[value=\"\"]', 'Select age:'\n    end\n  end\n\n  test 'input does not translate prompt when set to a string' do\n    store_translations(:en, simple_form: { prompts: { user: {\n      age: 'Select age:'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, prompt: 'Do it:'\n      assert_select 'select option[value=\"\"]', 'Do it:'\n    end\n  end\n\n  test 'input does not translate prompt when set to false' do\n    store_translations(:en, simple_form: { prompts: { user: {\n      age: 'Select age:'\n    } } }) do\n      with_input_for @user, :age, :select, collection: 18..30, prompt: false\n      assert_no_select 'select option[value=\"\"]'\n    end\n  end\n\n  test 'input uses Rails prompt translation as a fallback' do\n    store_translations(:en, helpers: { select: {\n      prompt: 'Select value:'\n    } }) do\n      with_input_for @user, :age, :select, collection: 18..30, prompt: :translate\n      assert_select 'select option[value=\"\"]', \"Select value:\"\n    end\n  end\n\n  test 'input detects label and value on collections' do\n    users = [User.build(id: 1, name: \"Jose\"), User.build(id: 2, name: \"Carlos\")]\n    with_input_for @user, :description, :select, collection: users\n    assert_select 'select option[value=\"1\"]', 'Jose'\n    assert_select 'select option[value=\"2\"]', 'Carlos'\n  end\n\n  test 'input disables the entire select and no specific options when given `true`' do\n    with_input_for @user, :description, :select, collection: %w[Jose Carlos], disabled: true\n    assert_no_select 'select option[value=Jose][disabled=disabled]', 'Jose'\n    assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'\n    assert_select 'select[disabled=disabled]'\n    assert_select 'div.disabled'\n  end\n\n  test 'input allows disabling only a single given option' do\n    with_input_for @user, :description, :select, collection: %w[Jose Carlos], disabled: 'Jose'\n    assert_select 'select option[value=Jose][disabled=disabled]', 'Jose'\n    assert_no_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'\n    assert_no_select 'select[disabled=disabled]'\n    assert_no_select 'div.disabled'\n  end\n\n  test 'input allows disabling multiple given options' do\n    with_input_for @user, :description, :select, collection: %w[Jose Carlos], disabled: %w[Jose Carlos]\n    assert_select 'select option[value=Jose][disabled=disabled]', 'Jose'\n    assert_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'\n    assert_no_select 'select[disabled=disabled]'\n    assert_no_select 'div.disabled'\n  end\n\n  test 'input allows overriding label and value method using a lambda for collection selects' do\n    with_input_for @user, :name, :select,\n                          collection: %w[Jose Carlos],\n                          label_method: ->(i) { i.upcase },\n                          value_method: ->(i) { i.downcase }\n    assert_select 'select option[value=jose]', \"JOSE\"\n    assert_select 'select option[value=carlos]', \"CARLOS\"\n  end\n\n  test 'input allows overriding only label but not value method using a lambda for collection select' do\n    with_input_for @user, :name, :select,\n                          collection: %w[Jose Carlos],\n                          label_method: ->(i) { i.upcase }\n    assert_select 'select option[value=Jose]', \"JOSE\"\n    assert_select 'select option[value=Carlos]', \"CARLOS\"\n  end\n\n  test 'input allows overriding only value but not label method using a lambda for collection select' do\n    with_input_for @user, :name, :select,\n                          collection: %w[Jose Carlos],\n                          value_method: ->(i) { i.downcase }\n    assert_select 'select option[value=jose]', \"Jose\"\n    assert_select 'select option[value=carlos]', \"Carlos\"\n  end\n\n  test 'input allows symbols for collections' do\n    with_input_for @user, :name, :select, collection: %i[jose carlos]\n    assert_select 'select.select#user_name'\n    assert_select 'select option[value=jose]', 'jose'\n    assert_select 'select option[value=carlos]', 'carlos'\n  end\n\n  test 'collection input with select type generates required html attribute only with blank option' do\n    with_input_for @user, :name, :select, include_blank: true, collection: %w[Jose Carlos]\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\n\n  test 'collection input with select type generates required html attribute only with blank option or prompt' do\n    with_input_for @user, :name, :select, prompt: 'Name...', collection: %w[Jose Carlos]\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\n\n  test \"collection input generated aria-label should contain 'true'\" do\n    with_input_for @user, :age, :select, collection: 18..30, prompt: \"Please select foo\"\n    assert_select 'select.required'\n  end\n\n  test 'collection input with select type does not generate required html attribute without blank option' do\n    with_input_for @user, :name, :select, include_blank: false, collection: %w[Jose Carlos]\n    assert_select 'select.required'\n    assert_no_select 'select[required]'\n  end\n\n  test 'collection input with select type with multiple attribute generates required html attribute without blank option' do\n    with_input_for @user, :name, :select, include_blank: false, input_html: { multiple: true }, collection: %w[Jose Carlos]\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\n\n  test 'collection input with select type with multiple attribute generates required html attribute with blank option' do\n    with_input_for @user, :name, :select, include_blank: true, input_html: { multiple: true }, collection: %w[Jose Carlos]\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\n\n  test 'input allows disabled options with a lambda for collection select' do\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      disabled: ->(x) { x == \"Carlos\" }\n    assert_select 'select option[value=Carlos][disabled=disabled]', 'Carlos'\n    assert_select 'select option[value=Antonio]', 'Antonio'\n    assert_no_select 'select option[value=Antonio][disabled]'\n  end\n\n  test 'input allows disabled and label method with lambdas for collection select' do\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      disabled: ->(x) { x == \"Carlos\" }, label_method: ->(x) { x.upcase }\n    assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'\n    assert_select 'select option[value=Antonio]', 'ANTONIO'\n    assert_no_select 'select option[value=Antonio][disabled]'\n  end\n\n  test 'input allows a non lambda disabled option with lambda label method for collections' do\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      disabled: \"Carlos\", label_method: ->(x) { x.upcase }\n    assert_select 'select option[value=Carlos][disabled=disabled]', 'CARLOS'\n    assert_select 'select option[value=Antonio]', 'ANTONIO'\n    assert_no_select 'select option[value=Antonio][disabled]'\n  end\n\n  test 'input allows selected and label method with lambdas for collection select' do\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      selected: ->(x) { x == \"Carlos\" }, label_method: ->(x) { x.upcase }\n    assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'\n    assert_select 'select option[value=Antonio]', 'ANTONIO'\n    assert_no_select 'select option[value=Antonio][selected]'\n  end\n\n  test 'input allows a non lambda selected option with lambda label method for collection select' do\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      selected: \"Carlos\", label_method: ->(x) { x.upcase }\n    assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'\n    assert_select 'select option[value=Antonio]', 'ANTONIO'\n    assert_no_select 'select option[value=Antonio][selected]'\n  end\n\n  test 'input does not override default selection through attribute value with label method as lambda for collection select' do\n    @user.name = \"Carlos\"\n    with_input_for @user, :name, :select, collection: %w[Carlos Antonio],\n      label_method: ->(x) { x.upcase }\n    assert_select 'select option[value=Carlos][selected=selected]', 'CARLOS'\n    assert_select 'select option[value=Antonio]', 'ANTONIO'\n    assert_no_select 'select option[value=Antonio][selected]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/color_input_test.rb",
    "content": "# frozen_string_literal: true\n\nrequire 'test_helper'\n\nclass ColorInputTest < ActionView::TestCase\n  test 'input generates a color field' do\n    with_input_for @user, :favorite_color, :color\n    assert_select 'input[type=color].color#user_favorite_color'\n  end\nend\n"
  },
  {
    "path": "test/inputs/country_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass CountryInputTest < ActionView::TestCase\n  COUNTRY_SELECT_SEPARATOR =\n    if Gem::Version.new(CountrySelect::VERSION) >= Gem::Version.new(\"11.0.0\")\n      \"hr\"\n    else\n      'option[value=\"---------------\"][disabled=disabled]'\n    end\n\n  test 'input generates a country select field' do\n    with_input_for @user, :country, :country\n    assert_select 'select#user_country'\n    assert_select 'select option[value=BR]', 'Brazil'\n    assert_no_select 'select option[value=\"\"][disabled=disabled]'\n    assert_no_select \"select #{COUNTRY_SELECT_SEPARATOR}\"\n  end\n\n  test 'input generates a country select with SimpleForm default' do\n    swap SimpleForm, country_priority: [ 'Brazil' ] do\n      with_input_for @user, :country, :country\n      assert_select %(select option[value=\"BR\"] + #{COUNTRY_SELECT_SEPARATOR})\n    end\n  end\n\n  test 'input generates a country select using options priority' do\n    with_input_for @user, :country, :country, priority: [ 'Ukraine' ]\n    assert_select %(select option[value=\"UA\"] + #{COUNTRY_SELECT_SEPARATOR})\n  end\n\n  test 'input does generate select element with required html attribute' do\n    with_input_for @user, :country, :country\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/datetime_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\n# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.\nclass DateTimeInputWithHtml5Test < ActionView::TestCase\n  test 'input generates a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do\n    with_input_for @user, :created_at, :datetime, html5: true\n    assert_select 'input[type=\"datetime-local\"]'\n  end\n\n  test 'input generates a datetime select for datetime attributes' do\n    with_input_for @user, :created_at, :datetime\n\n    assert_select 'select.datetime'\n  end\n\n  test 'input generates a date input for date attributes if HTML5 compatibility is explicitly enbled' do\n    with_input_for @user, :born_at, :date, html5: true\n\n    assert_select 'input[type=\"date\"]'\n  end\n\n  test 'input generates a date select for date attributes' do\n    with_input_for @user, :born_at, :date\n\n    assert_select 'select.date'\n  end\n\n  test 'input generates a time input for time attributes if HTML5 compatibility is explicitly enbled' do\n    with_input_for @user, :delivery_time, :time, html5: true\n\n    assert_select 'input[type=\"time\"]'\n  end\n\n  test 'input generates a time select for time attributes' do\n    with_input_for @user, :delivery_time, :time\n\n    assert_select 'select.time'\n  end\n\n  test 'input generates required html attribute' do\n    with_input_for @user, :delivery_time, :time, required: true, html5: true\n    assert_select 'input.required'\n    assert_select 'input[required]'\n  end\nend\n\n# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.\nclass DateTimeInputWithoutHtml5Test < ActionView::TestCase\n  test 'input generates a datetime select by default for datetime attributes' do\n    swap_wrapper do\n      with_input_for @user, :created_at, :datetime\n      1.upto(5) do |i|\n        assert_select \"form select.datetime#user_created_at_#{i}i\"\n      end\n    end\n  end\n\n  test 'input is able to pass options to datetime select' do\n    with_input_for @user, :created_at, :datetime, html5: false,\n      disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }\n\n    assert_select 'select.datetime[disabled=disabled]'\n    assert_select 'select.datetime option', 'ano'\n    assert_select 'select.datetime option', 'mês'\n    assert_select 'select.datetime option', 'dia'\n  end\n\n  test 'input generates a datetime input for datetime attributes if HTML5 compatibility is explicitly enabled' do\n    swap_wrapper do\n      with_input_for @user, :created_at, :datetime, html5: true\n      assert_select 'input[type=\"datetime-local\"]'\n    end\n  end\n\n  test 'input generates a date select for date attributes' do\n    swap_wrapper do\n      with_input_for @user, :born_at, :date\n      assert_select 'select.date#user_born_at_1i'\n      assert_select 'select.date#user_born_at_2i'\n      assert_select 'select.date#user_born_at_3i'\n      assert_no_select 'select.date#user_born_at_4i'\n    end\n  end\n\n  test 'input is able to pass options to date select' do\n    with_input_for @user, :born_at, :date, as: :date, html5: false,\n      disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }\n\n    assert_select 'select.date[disabled=disabled]'\n    assert_select 'select.date option', 'ano'\n    assert_select 'select.date option', 'mês'\n    assert_select 'select.date option', 'dia'\n  end\n\n  test 'input is able to pass :default to date select' do\n    with_input_for @user, :born_at, :date, default: Date.today, html5: false\n    assert_select \"select.date option[value='#{Date.today.year}'][selected=selected]\"\n  end\n\n  test 'input generates a date input for date attributes if HTML5 compatibility is explicitly enabled' do\n    swap_wrapper do\n      with_input_for @user, :born_at, :date, html5: true\n\n      assert_select 'input[type=\"date\"]'\n    end\n  end\n\n  test 'input generates a time select for time attributes' do\n    swap_wrapper do\n      with_input_for @user, :delivery_time, :time\n      assert_select 'input[type=hidden]#user_delivery_time_1i'\n      assert_select 'input[type=hidden]#user_delivery_time_2i'\n      assert_select 'input[type=hidden]#user_delivery_time_3i'\n      assert_select 'select.time#user_delivery_time_4i'\n      assert_select 'select.time#user_delivery_time_5i'\n    end\n  end\n\n  test 'input is able to pass options to time select' do\n    with_input_for @user, :delivery_time, :time, required: true, html5: false,\n      disabled: true, prompt: { hour: 'hora', minute: 'minuto' }\n\n    assert_select 'select.time[disabled=disabled]'\n    assert_select 'select.time option', 'hora'\n    assert_select 'select.time option', 'minuto'\n  end\n\n  test 'input generates a time input for time attributes if HTML5 compatibility is explicitly enabled' do\n    swap_wrapper do\n      with_input_for @user, :delivery_time, :time, html5: true\n\n      assert_select 'input[type=\"time\"]'\n    end\n  end\n\n  test 'label uses i18n to get target for date input type' do\n    store_translations(:en, date: { order: %w[month day year] }) do\n      with_input_for :project, :created_at, :date, html5: false\n      assert_select 'label[for=project_created_at_2i]'\n    end\n  end\n\n  test 'label uses i18n to get target for datetime input type' do\n    store_translations(:en, date: { order: %w[month day year] }) do\n      with_input_for :project, :created_at, :datetime, html5: false\n      assert_select 'label[for=project_created_at_2i]'\n    end\n  end\n\n  test 'label uses order to get target when date input type' do\n    with_input_for :project, :created_at, :date, order: %w[month year day], html5: false\n    assert_select 'label[for=project_created_at_2i]'\n  end\n\n  test 'label uses order to get target when datetime input type' do\n    with_input_for :project, :created_at, :datetime, order: %w[month year day], html5: false\n    assert_select 'label[for=project_created_at_2i]'\n  end\n\n  test 'label points to first option when time input type' do\n    with_input_for :project, :created_at, :time, html5: false\n    assert_select 'label[for=project_created_at_4i]'\n  end\n\n  test 'label points to attribute name if HTML5 compatibility is explicitly enabled' do\n    with_input_for :project, :created_at, :date, html5: true\n    assert_select 'label[for=project_created_at]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/disabled_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass DisabledTest < ActionView::TestCase\n  test 'string input is disabled when disabled option is true' do\n    with_input_for @user, :name, :string, disabled: true\n    assert_select 'input.string.disabled[disabled]'\n  end\n\n  test 'text input is disabled when disabled option is true' do\n    with_input_for @user, :description, :text, disabled: true\n    assert_select 'textarea.text.disabled[disabled]'\n  end\n\n  test 'numeric input is disabled when disabled option is true' do\n    with_input_for @user, :age, :integer, disabled: true\n    assert_select 'input.integer.disabled[disabled]'\n  end\n\n  test 'date input is disabled when disabled option is true' do\n    with_input_for @user, :born_at, :date, disabled: true\n    assert_select 'select.date.disabled[disabled]'\n  end\n\n  test 'datetime input is disabled when disabled option is true' do\n    with_input_for @user, :created_at, :datetime, disabled: true\n    assert_select 'select.datetime.disabled[disabled]'\n  end\n\n  test 'string input does not be disabled when disabled option is false' do\n    with_input_for @user, :name, :string, disabled: false\n    assert_no_select 'input.string.disabled[disabled]'\n  end\n\n  test 'text input does not be disabled when disabled option is false' do\n    with_input_for @user, :description, :text, disabled: false\n    assert_no_select 'textarea.text.disabled[disabled]'\n  end\n\n  test 'numeric input does not be disabled when disabled option is false' do\n    with_input_for @user, :age, :integer, disabled: false\n    assert_no_select 'input.integer.disabled[disabled]'\n  end\n\n  test 'date input does not be disabled when disabled option is false' do\n    with_input_for @user, :born_at, :date, disabled: false\n    assert_no_select 'select.date.disabled[disabled]'\n  end\n\n  test 'datetime input does not be disabled when disabled option is false' do\n    with_input_for @user, :created_at, :datetime, disabled: false\n    assert_no_select 'select.datetime.disabled[disabled]'\n  end\n\n  test 'string input does not be disabled when disabled option is not present' do\n    with_input_for @user, :name, :string\n    assert_no_select 'input.string.disabled[disabled]'\n  end\n\n  test 'text input does not be disabled when disabled option is not present' do\n    with_input_for @user, :description, :text\n    assert_no_select 'textarea.text.disabled[disabled]'\n  end\n\n  test 'numeric input does not be disabled when disabled option is not present' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input.integer.disabled[disabled]'\n  end\n\n  test 'date input does not be disabled when disabled option is not present' do\n    with_input_for @user, :born_at, :date\n    assert_no_select 'select.date.disabled[disabled]'\n  end\n\n  test 'datetime input does not be disabled when disabled option is not present' do\n    with_input_for @user, :created_at, :datetime\n    assert_no_select 'select.datetime.disabled[disabled]'\n  end\n\n  test 'input_field collection allows disabled select' do\n    with_input_field_for @user, :description, collection: ['foo', 'bar'], disabled: true\n    assert_select 'select[disabled]'\n    assert_no_select 'option[disabled]'\n  end\n\n  test 'input_field collection allows individual disabled options' do\n    with_input_field_for @user, :description, collection: ['foo', 'bar'], disabled: 'bar'\n    assert_no_select 'select[disabled]'\n    assert_no_select 'option[disabled][value=foo]'\n    assert_select 'option[disabled][value=bar]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/discovery_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass DiscoveryTest < ActionView::TestCase\n  # Setup new inputs and remove them after the test.\n  def discovery(value = false)\n    swap SimpleForm, cache_discovery: value do\n      begin\n        load \"support/discovery_inputs.rb\"\n        yield\n      ensure\n        SimpleForm::FormBuilder.discovery_cache.clear\n        Object.send :remove_const, :StringInput\n        Object.send :remove_const, :NumericInput\n        Object.send :remove_const, :CustomizedInput\n        Object.send :remove_const, :DeprecatedInput\n        Object.send :remove_const, :CollectionSelectInput\n        Object.send :remove_const, :FileInput\n        CustomInputs.send :remove_const, :CustomizedInput\n        CustomInputs.send :remove_const, :PasswordInput\n        CustomInputs.send :remove_const, :NumericInput\n      end\n    end\n  end\n\n  test 'builder does not discover new inputs if cached' do\n    with_form_for @user, :name\n    assert_select 'form input#user_name.string'\n\n    discovery(true) do\n      with_form_for @user, :name\n      assert_no_select 'form section input#user_name.string'\n    end\n  end\n\n  test 'builder discovers new inputs' do\n    discovery do\n      with_form_for @user, :name, as: :customized\n      assert_select 'form section input#user_name.string'\n    end\n  end\n\n  test 'builder does not discover new inputs if discovery is off' do\n    with_form_for @user, :name\n    assert_select 'form input#user_name.string'\n\n    swap SimpleForm, inputs_discovery: false do\n      discovery do\n        with_form_for @user, :name\n        assert_no_select 'form section input#user_name.string'\n      end\n    end\n  end\n\n  test 'builder discovers new inputs from mappings if not cached' do\n    discovery do\n      with_form_for @user, :name\n      assert_select 'form section input#user_name.string'\n    end\n  end\n\n  test 'builder discovers new inputs from internal fallbacks if not cached' do\n    discovery do\n      with_form_for @user, :age\n      assert_select 'form section input#user_age.numeric.integer'\n    end\n  end\n\n  test 'builder discovers new mapped inputs from configured namespaces if not cached' do\n    discovery do\n      swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do\n        with_form_for @user, :password\n        assert_select 'form input#user_password.password-custom-input'\n      end\n    end\n  end\n\n  test 'builder discovers new mapped inputs from configured namespaces before the ones from top level namespace' do\n    discovery do\n      swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do\n        with_form_for @user, :age\n        assert_select 'form input#user_age.numeric-custom-input'\n      end\n    end\n  end\n\n  test 'builder discovers new custom inputs from configured namespace before the ones from top level namespace' do\n    discovery do\n      swap SimpleForm, custom_inputs_namespaces: ['CustomInputs'] do\n        with_form_for @user, :name, as: 'customized'\n        assert_select 'form input#user_name.customized-namespace-custom-input'\n      end\n    end\n  end\n\n  test 'raises error when configured namespace does not exists' do\n    discovery do\n      swap SimpleForm, custom_inputs_namespaces: ['InvalidNamespace'] do\n        assert_raise NameError do\n          with_form_for @user, :age\n        end\n      end\n    end\n  end\n\n  test 'new inputs can override the input_html_options' do\n    discovery do\n      with_form_for @user, :active, as: :select\n      assert_select 'form select#user_active.select.chosen'\n    end\n  end\n\n  test 'does not duplicate the html classes giving a extra class' do\n    discovery do\n      swap SimpleForm, input_class: 'custom-default-input-class' do\n        with_form_for @user, :active, as: :select\n        assert_select 'form select#user_active.select' do\n          # Make sure class list contains 'chosen' only once.\n          assert_select \":match('class', ?)\", /^(?!.*\\bchosen\\b.*\\bchosen\\b).*\\bchosen\\b.*$/\n        end\n      end\n    end\n  end\n\n  test 'new inputs can override the default input_html_classes' do\n    discovery do\n      with_form_for @user, :avatar, as: :file\n      assert_no_select 'form input[type=file]#user_avatar.file.file-upload'\n      assert_select 'form input[type=file]#user_avatar.file-upload'\n    end\n  end\n\n  test 'inputs method without wrapper_options are deprecated' do\n    discovery do\n      assert_deprecated('input method now accepts a `wrapper_options` argument.', SimpleForm.deprecator) do\n        with_form_for @user, :name, as: :deprecated\n      end\n\n      assert_select 'form section input#user_name.string'\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/file_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass FileInputTest < ActionView::TestCase\n  test 'input generates a file field' do\n    with_input_for @user, :name, :file\n    assert_select 'input#user_name[type=file]'\n  end\n\n  test \"input generates a file field that doesn't accept placeholder\" do\n    store_translations(:en, simple_form: { placeholders: { user: { name: \"text\" } } }) do\n      with_input_for @user, :name, :file\n      assert_no_select 'input[placeholder]'\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/general_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass InputTest < ActionView::TestCase\n  test 'input generates css class based on default input type' do\n    with_input_for @user, :name, :string\n    assert_select 'input.string'\n    with_input_for @user, :description, :text\n    assert_select 'textarea.text'\n    with_input_for @user, :age, :integer\n    assert_select 'input.integer'\n    with_input_for @user, :born_at, :date\n    assert_select 'select.date'\n    with_input_for @user, :created_at, :datetime\n    assert_select 'select.datetime'\n  end\n\n  test 'string input generates autofocus attribute when autofocus option is true' do\n    with_input_for @user, :name, :string, autofocus: true\n    assert_select 'input.string[autofocus]'\n  end\n\n  test 'input accepts input_class configuration' do\n    swap SimpleForm, input_class: :xlarge do\n      with_input_for @user, :name, :string\n      assert_select 'input.xlarge'\n      assert_no_select 'div.xlarge'\n    end\n  end\n\n  test 'input does not add input_class when configured to not generate additional classes for input' do\n    swap SimpleForm, input_class: 'xlarge', generate_additional_classes_for: [:wrapper] do\n      with_input_for @user, :name, :string\n      assert_select 'input'\n      assert_no_select '.xlarge'\n    end\n  end\n\n  test 'text input generates autofocus attribute when autofocus option is true' do\n    with_input_for @user, :description, :text, autofocus: true\n    assert_select 'textarea.text[autofocus]'\n  end\n\n  test 'numeric input generates autofocus attribute when autofocus option is true' do\n    with_input_for @user, :age, :integer, autofocus: true\n    assert_select 'input.integer[autofocus]'\n  end\n\n  test 'date input generates autofocus attribute when autofocus option is true' do\n    with_input_for @user, :born_at, :date, autofocus: true\n    assert_select 'select.date[autofocus]'\n  end\n\n  test 'datetime input generates autofocus attribute when autofocus option is true' do\n    with_input_for @user, :created_at, :datetime, autofocus: true\n    assert_select 'select.datetime[autofocus]'\n  end\n\n  test 'string input generates autofocus attribute when autofocus option is false' do\n    with_input_for @user, :name, :string, autofocus: false\n    assert_no_select 'input.string[autofocus]'\n  end\n\n  test 'text input generates autofocus attribute when autofocus option is false' do\n    with_input_for @user, :description, :text, autofocus: false\n    assert_no_select 'textarea.text[autofocus]'\n  end\n\n  test 'numeric input generates autofocus attribute when autofocus option is false' do\n    with_input_for @user, :age, :integer, autofocus: false\n    assert_no_select 'input.integer[autofocus]'\n  end\n\n  test 'date input generates autofocus attribute when autofocus option is false' do\n    with_input_for @user, :born_at, :date, autofocus: false\n    assert_no_select 'select.date[autofocus]'\n  end\n\n  test 'datetime input generates autofocus attribute when autofocus option is false' do\n    with_input_for @user, :created_at, :datetime, autofocus: false\n    assert_no_select 'select.datetime[autofocus]'\n  end\n\n  test 'string input generates autofocus attribute when autofocus option is not present' do\n    with_input_for @user, :name, :string\n    assert_no_select 'input.string[autofocus]'\n  end\n\n  test 'text input generates autofocus attribute when autofocus option is not present' do\n    with_input_for @user, :description, :text\n    assert_no_select 'textarea.text[autofocus]'\n  end\n\n  test 'numeric input generates autofocus attribute when autofocus option is not present' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input.integer[autofocus]'\n  end\n\n  test 'date input generates autofocus attribute when autofocus option is not present' do\n    with_input_for @user, :born_at, :date\n    assert_no_select 'select.date[autofocus]'\n  end\n\n  test 'datetime input generates autofocus attribute when autofocus option is not present' do\n    with_input_for @user, :created_at, :datetime\n    assert_no_select 'select.datetime[autofocus]'\n  end\n\n  # With no object\n  test 'input is generated properly when object is not present' do\n    with_input_for :project, :name, :string\n    assert_select 'input.string.required#project_name'\n  end\n\n  test 'input as radio is generated properly when object is not present ' do\n    with_input_for :project, :name, :radio_buttons\n    assert_select 'input.radio_buttons#project_name_true'\n    assert_select 'input.radio_buttons#project_name_false'\n  end\n\n  test 'input as select with collection is generated properly when object is not present' do\n    with_input_for :project, :name, :select, collection: %w[Jose Carlos]\n    assert_select 'select.select#project_name'\n  end\n\n  test 'input does not generate empty css class' do\n    swap SimpleForm, generate_additional_classes_for: %i[wrapper label] do\n      with_input_for :project, :name, :string\n      assert_no_select 'input#project_name[class]'\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/grouped_collection_select_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass GroupedCollectionSelectInputTest < ActionView::TestCase\n  test 'grouped collection accepts array collection form' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: [['Authors', %w[Jose Carlos]], ['General', %w[Bob John]]],\n      group_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option', 'Jose'\n        assert_select 'option', 'Carlos'\n      end\n\n      assert_select 'optgroup[label=General]' do\n        assert_select 'option', 'Bob'\n        assert_select 'option', 'John'\n      end\n    end\n  end\n\n  test 'grouped collection accepts empty array collection form' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: [],\n      group_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids'\n  end\n\n\n  test 'grouped collection accepts proc as collection' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: proc { [['Authors', %w[Jose Carlos]], ['General', %w[Bob John]]] },\n      group_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option', 'Jose'\n        assert_select 'option', 'Carlos'\n      end\n\n      assert_select 'optgroup[label=General]' do\n        assert_select 'option', 'Bob'\n        assert_select 'option', 'John'\n      end\n    end\n  end\n\n  test 'grouped collection accepts hash collection form' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: { Authors: %w[Jose Carlos], General: %w[Bob John] },\n      group_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option', 'Jose'\n        assert_select 'option', 'Carlos'\n      end\n\n      assert_select 'optgroup[label=General]' do\n        assert_select 'option', 'Bob'\n        assert_select 'option', 'John'\n      end\n    end\n  end\n\n  test 'grouped collection allows overriding group_method using a lambda' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: { Authors: %w[Jose Carlos] },\n      group_method: ->(i) { i.last }\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option[value=Jose]', 'Jose'\n        assert_select 'option[value=Carlos]', 'Carlos'\n      end\n    end\n  end\n\n  test 'grouped collection accepts group_label_method option' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: { %w[Jose Carlos] => 'Authors' },\n      group_method: :first,\n      group_label_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option', 'Jose'\n        assert_select 'option', 'Carlos'\n      end\n    end\n  end\n\n  test 'grouped collection finds default label methods on the group objects' do\n    option_list = %w[Jose Carlos]\n\n    GroupedClass = Struct.new(:to_label, :options)\n    group = GroupedClass.new(\"Authors\", option_list)\n\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: [group],\n      group_method: :options\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option', 'Jose'\n        assert_select 'option', 'Carlos'\n      end\n    end\n  end\n\n  test 'grouped collections finds the default label method from the first non-empty object' do\n    Agent = Struct.new(:id, :name)\n    agents = [[\"First\", []], [\"Second\", [Agent.new(7, 'Bond'), Agent.new(47, 'Hitman')]]]\n\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: agents,\n      group_label_method: :first,\n      group_method: :last,\n      include_blank: false\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Second]' do\n        assert_select 'option[value=\"7\"]', 'Bond'\n        assert_select 'option[value=\"47\"]', 'Hitman'\n      end\n    end\n  end\n\n  test 'grouped collection accepts label and value methods options' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: { Authors: %w[Jose Carlos] },\n      group_method: :last,\n      label_method: :upcase,\n      value_method: :downcase\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option[value=jose]', 'JOSE'\n        assert_select 'option[value=carlos]', 'CARLOS'\n      end\n    end\n  end\n\n  test 'grouped collection allows overriding label and value methods using a lambda' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: { Authors: %w[Jose Carlos] },\n      group_method: :last,\n      label_method: ->(i) { i.upcase },\n      value_method: ->(i) { i.downcase }\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option[value=jose]', 'JOSE'\n        assert_select 'option[value=carlos]', 'CARLOS'\n      end\n    end\n  end\n\n  test 'grouped collection with associations' do\n    tag_groups = [\n      TagGroup.new(1, \"Group of Tags\", [Tag.new(1, \"Tag 1\"), Tag.new(2, \"Tag 2\")]),\n      TagGroup.new(2, \"Other group\", [Tag.new(3, \"Tag 3\"), Tag.new(4, \"Tag 4\")])\n    ]\n\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: tag_groups, group_method: :tags\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=\"Group of Tags\"]' do\n        assert_select 'option[value=\"1\"]', 'Tag 1'\n        assert_select 'option[value=\"2\"]', 'Tag 2'\n      end\n\n      assert_select 'optgroup[label=\"Other group\"]' do\n        assert_select 'option[value=\"3\"]', 'Tag 3'\n        assert_select 'option[value=\"4\"]', 'Tag 4'\n      end\n    end\n  end\n\n  test 'grouped collection accepts html options as the last element of collection' do\n    with_input_for @user, :tag_ids, :grouped_select,\n      collection: [['Authors', [['Jose', 'jose', class: 'foo'], ['Carlos', 'carlos', class: 'bar']]]],\n      group_method: :last\n\n    assert_select 'select.grouped_select#user_tag_ids' do\n      assert_select 'optgroup[label=Authors]' do\n        assert_select 'option.foo', 'Jose'\n        assert_select 'option.bar', 'Carlos'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/hidden_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass HiddenInputTest < ActionView::TestCase\n  test 'input generates a hidden field' do\n    with_input_for @user, :name, :hidden\n    assert_no_select 'input[type=text]'\n    assert_select 'input#user_name[type=hidden]'\n  end\n\n  test 'hint does not be generated for hidden fields' do\n    store_translations(:en, simple_form: { hints: { user: { name: \"text\" } } }) do\n      with_input_for @user, :name, :hidden\n      assert_no_select 'span.hint'\n    end\n  end\n\n  test 'label does not be generated for hidden inputs' do\n    with_input_for @user, :name, :hidden\n    assert_no_select 'label'\n  end\n\n  test 'required/optional options does not be generated for hidden inputs' do\n    with_input_for @user, :name, :hidden\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_no_select 'input.optional'\n    assert_select 'input.hidden#user_name'\n  end\nend\n"
  },
  {
    "path": "test/inputs/numeric_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass NumericInputTest < ActionView::TestCase\n  test 'input generates an integer text field for integer attributes ' do\n    with_input_for @user, :age, :integer\n    assert_select 'input[type=number].integer#user_age'\n  end\n\n  test 'input generates a float text field for float attributes ' do\n    with_input_for @user, :age, :float\n    assert_select 'input[type=number].float#user_age'\n  end\n\n  test 'input generates a decimal text field for decimal attributes ' do\n    with_input_for @user, :age, :decimal\n    assert_select 'input[type=number].decimal#user_age'\n  end\n\n  test 'input does not generate min attribute by default' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input[min]'\n  end\n\n  test 'input does not generate max attribute by default' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input[max]'\n  end\n\n  test 'input infers min value from integer attributes with greater than validation' do\n    with_input_for @other_validating_user, :age, :float\n    assert_no_select 'input[min]'\n\n    with_input_for @other_validating_user, :age, :integer\n    assert_select 'input[min=\"18\"]'\n  end\n\n  test 'input infers min value from integer attributes with greater than validation using symbol' do\n    with_input_for @validating_user, :amount, :float\n    assert_no_select 'input[min]'\n\n    with_input_for @validating_user, :amount, :integer\n    assert_select 'input[min=\"11\"]'\n  end\n\n  test 'input infers min value from integer attributes with greater than or equal to validation using symbol' do\n    with_input_for @validating_user, :attempts, :float\n    assert_select 'input[min=\"1\"]'\n\n    with_input_for @validating_user, :attempts, :integer\n    assert_select 'input[min=\"1\"]'\n  end\n\n  test 'input infers min value from integer attributes with greater than validation using proc' do\n    with_input_for @other_validating_user, :amount, :float\n    assert_no_select 'input[min]'\n\n    with_input_for @other_validating_user, :amount, :integer\n    assert_select 'input[min=\"20\"]'\n  end\n\n  test 'input infers min value from integer attributes with greater than or equal to validation using proc' do\n    with_input_for @other_validating_user, :attempts, :float\n    assert_select 'input[min=\"19\"]'\n\n    with_input_for @other_validating_user, :attempts, :integer\n    assert_select 'input[min=\"19\"]'\n  end\n\n  test 'input infers max value from attributes with less than validation' do\n    with_input_for @other_validating_user, :age, :float\n    assert_no_select 'input[max]'\n\n    with_input_for @other_validating_user, :age, :integer\n    assert_select 'input[max=\"99\"]'\n  end\n\n  test 'input infers max value from attributes with less than validation using symbol' do\n    with_input_for @validating_user, :amount, :float\n    assert_no_select 'input[max]'\n\n    with_input_for @validating_user, :amount, :integer\n    assert_select 'input[max=\"99\"]'\n  end\n\n  test 'input infers max value from attributes with less than or equal to validation using symbol' do\n    with_input_for @validating_user, :attempts, :float\n    assert_select 'input[max=\"100\"]'\n\n    with_input_for @validating_user, :attempts, :integer\n    assert_select 'input[max=\"100\"]'\n  end\n\n  test 'input infers max value from attributes with less than validation using proc' do\n    with_input_for @other_validating_user, :amount, :float\n    assert_no_select 'input[max]'\n\n    with_input_for @other_validating_user, :amount, :integer\n    assert_select 'input[max=\"118\"]'\n  end\n\n  test 'input infers max value from attributes with less than or equal to validation using proc' do\n    with_input_for @other_validating_user, :attempts, :float\n    assert_select 'input[max=\"119\"]'\n\n    with_input_for @other_validating_user, :attempts, :integer\n    assert_select 'input[max=\"119\"]'\n  end\n\n  test 'input has step value of any except for integer attribute' do\n    with_input_for @validating_user, :age, :float\n    assert_select 'input[step=\"any\"]'\n\n    with_input_for @validating_user, :age, :integer\n    assert_select 'input[step=\"1\"]'\n\n    with_input_for @validating_user, :age, :integer, as: :decimal, input_html: { step: 0.5 }\n    assert_select 'input[step=\"0.5\"]'\n  end\n\n  test 'numeric input does not generate placeholder by default' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input[placeholder]'\n  end\n\n  test 'numeric input accepts the placeholder option' do\n    with_input_for @user, :age, :integer, placeholder: 'Put in your age'\n    assert_select 'input.integer[placeholder=\"Put in your age\"]'\n  end\n\n  test 'numeric input uses i18n to translate placeholder text' do\n    store_translations(:en, simple_form: { placeholders: { user: {\n      age: 'Age goes here'\n    } } }) do\n      with_input_for @user, :age, :integer\n      assert_select 'input.integer[placeholder=\"Age goes here\"]'\n    end\n  end\n\n  # Numeric input but HTML5 disabled\n  test 'when not using HTML5 input does not generate field with type number and use text instead' do\n    swap_wrapper do\n      with_input_for @user, :age, :integer\n      assert_no_select \"input[type=number]\"\n      assert_no_select \"input#user_age[text]\"\n    end\n  end\n\n  test 'when not using HTML5 input does not use min or max or step attributes' do\n    swap_wrapper do\n      with_input_for @validating_user, :age, :integer\n      assert_no_select \"input[type=number]\"\n      assert_no_select \"input[min]\"\n      assert_no_select \"input[max]\"\n      assert_no_select \"input[step]\"\n    end\n  end\n\n  %i[integer float decimal].each do |type|\n    test \"#{type} input infers min value from attributes with greater than or equal validation\" do\n      with_input_for @validating_user, :age, type\n      assert_select 'input[min=\"18\"]'\n    end\n\n    test \"#{type} input infers the max value from attributes with less than or equal to validation\" do\n      with_input_for @validating_user, :age, type\n      assert_select 'input[max=\"99\"]'\n    end\n  end\n\n  test 'min_max does not emit max value as bare string' do\n    with_input_for @other_validating_user, :age, :integer\n    assert_select 'input[max]'\n    assert_no_select 'div', %r{^99}\n  end\nend\n"
  },
  {
    "path": "test/inputs/readonly_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass ReadonlyTest < ActionView::TestCase\n  test 'string input generates readonly elements when readonly option is true' do\n    with_input_for @user, :name, :string, readonly: true\n    assert_select 'input.string.readonly[readonly]'\n  end\n\n  test 'text input generates readonly elements when readonly option is true' do\n    with_input_for @user, :description, :text, readonly: true\n    assert_select 'textarea.text.readonly[readonly]'\n  end\n\n  test 'numeric input generates readonly elements when readonly option is true' do\n    with_input_for @user, :age, :integer, readonly: true\n    assert_select 'input.integer.readonly[readonly]'\n  end\n\n  test 'date input generates readonly elements when readonly option is true' do\n    with_input_for @user, :born_at, :date, readonly: true\n    assert_select 'select.date.readonly[readonly]'\n  end\n\n  test 'datetime input generates readonly elements when readonly option is true' do\n    with_input_for @user, :created_at, :datetime, readonly: true\n    assert_select 'select.datetime.readonly[readonly]'\n  end\n\n  test 'string input generates readonly elements when readonly option is false' do\n    with_input_for @user, :name, :string, readonly: false\n    assert_no_select 'input.string.readonly[readonly]'\n  end\n\n  test 'text input generates readonly elements when readonly option is false' do\n    with_input_for @user, :description, :text, readonly: false\n    assert_no_select 'textarea.text.readonly[readonly]'\n  end\n\n  test 'numeric input generates readonly elements when readonly option is false' do\n    with_input_for @user, :age, :integer, readonly: false\n    assert_no_select 'input.integer.readonly[readonly]'\n  end\n\n  test 'date input generates readonly elements when readonly option is false' do\n    with_input_for @user, :born_at, :date, readonly: false\n    assert_no_select 'select.date.readonly[readonly]'\n  end\n\n  test 'datetime input generates readonly elements when readonly option is false' do\n    with_input_for @user, :created_at, :datetime, readonly: false\n    assert_no_select 'select.datetime.readonly[readonly]'\n  end\n\n  test 'string input generates readonly elements when readonly option is not present' do\n    with_input_for @user, :name, :string\n    assert_no_select 'input.string.readonly[readonly]'\n  end\n\n  test 'text input generates readonly elements when readonly option is not present' do\n    with_input_for @user, :description, :text\n    assert_no_select 'textarea.text.readonly[readonly]'\n  end\n\n  test 'numeric input generates readonly elements when readonly option is not present' do\n    with_input_for @user, :age, :integer\n    assert_no_select 'input.integer.readonly[readonly]'\n  end\n\n  test 'date input generates readonly elements when readonly option is not present' do\n    with_input_for @user, :born_at, :date\n    assert_no_select 'select.date.readonly[readonly]'\n  end\n\n  test 'datetime input generates readonly elements when readonly option is not present' do\n    with_input_for @user, :created_at, :datetime\n    assert_no_select 'select.datetime.readonly[readonly]'\n  end\n\n  test 'input generates readonly attribute when the field is readonly and the object is persisted' do\n    with_input_for @user, :credit_card, :string, readonly: :lookup\n    assert_select 'input.string.readonly[readonly]'\n  end\n\n  test 'input does not generate readonly attribute when the field is readonly and the object is not persisted' do\n    @user.new_record!\n    with_input_for @user, :credit_card, :string, readonly: :lookup\n    assert_no_select 'input.string.readonly[readonly]'\n  end\n\n  test 'input does not generate readonly attribute when the field is not readonly and the object is persisted' do\n    with_input_for @user, :name, :string\n    assert_no_select 'input.string.readonly[readonly]'\n  end\n\n  test 'input does not generate readonly attribute when the component is not used' do\n    swap_wrapper do\n      with_input_for @user, :credit_card, :string\n      assert_no_select 'input.string.readonly[readonly]'\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/required_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass RequiredTest < ActionView::TestCase\n  # REQUIRED AND PRESENCE VALIDATION\n  test 'builder input obtains required from ActiveModel::Validations when it is included' do\n    with_form_for @validating_user, :name\n    assert_select 'input.required[required]#validating_user_name'\n    with_form_for @validating_user, :status\n    assert_select 'input.optional#validating_user_status'\n  end\n\n  test 'builder input allows overriding required when ActiveModel::Validations is included' do\n    with_form_for @validating_user, :name, required: false\n    assert_select 'input.optional#validating_user_name'\n    with_form_for @validating_user, :status, required: true\n    assert_select 'input.required[required]#validating_user_status'\n  end\n\n  test 'builder input is required by default when ActiveModel::Validations is not included' do\n    with_form_for @user, :name\n    assert_select 'input.required[required]#user_name'\n  end\n\n  test 'builder input does not be required by default when ActiveModel::Validations is not included if option is set to false' do\n    swap SimpleForm, required_by_default: false do\n      with_form_for @user, :name\n      assert_select 'input.optional#user_name'\n      assert_no_select 'input[required]'\n    end\n  end\n\n  test 'when not using browser validations, input does not generate required html attribute' do\n    swap SimpleForm, browser_validations: false do\n      with_input_for @user, :name, :string\n      assert_select 'input[type=text].required'\n      assert_no_select 'input[type=text][required]'\n    end\n  end\n\n  test 'when not using browser validations, when required option is set to false, input does not generate required html attribute' do\n    swap SimpleForm, browser_validations: false do\n      with_input_for @user, :name, :string, required: false\n      assert_no_select 'input[type=text].required'\n      assert_no_select 'input[type=text][required]'\n    end\n  end\n\n  test 'when not using browser validations, when required option is set to true, input generates required html attribute' do\n    swap SimpleForm, browser_validations: false do\n      with_input_for @user, :name, :string, required: true\n      assert_select 'input[type=text].required'\n      assert_select 'input[type=text][required]'\n    end\n  end\n\n  test 'when not using browser validations, when required option is true in the wrapper, input does not generate required html attribute' do\n    swap SimpleForm, browser_validations: false do\n      swap_wrapper :default, self.custom_wrapper_with_required_input do\n        with_concat_form_for(@user) do |f|\n          concat f.input :name\n        end\n        assert_select 'input[type=text].required'\n        assert_no_select 'input[type=text][required]'\n      end\n    end\n  end\n\n  test 'builder input allows disabling required when ActiveModel::Validations is not included' do\n    with_form_for @user, :name, required: false\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_select 'input.optional#user_name'\n  end\n\n  test 'when not the required component the input does not have the required attribute but has the required class' do\n    swap_wrapper do\n      with_input_for @user, :name, :string\n      assert_select 'input[type=text].required'\n      assert_no_select 'input[type=text][required]'\n    end\n  end\n\n  # VALIDATORS :if :unless\n  test 'builder input does not be required when ActiveModel::Validations is included and if option is present' do\n    with_form_for @validating_user, :age\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_select 'input.optional#validating_user_age'\n  end\n\n  test 'builder input does not be required when ActiveModel::Validations is included and unless option is present' do\n    with_form_for @validating_user, :amount\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_select 'input.optional#validating_user_amount'\n  end\n\n  # VALIDATORS :on\n  test 'builder input is required when validation is on create and is not persisted' do\n    @validating_user.new_record!\n    with_form_for @validating_user, :action\n    assert_select 'input.required'\n    assert_select 'input[required]'\n    assert_select 'input.required[required]#validating_user_action'\n  end\n\n  test 'builder input does not be required when validation is on create and is persisted' do\n    with_form_for @validating_user, :action\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_select 'input.optional#validating_user_action'\n  end\n\n  test 'builder input is required when validation is on save' do\n    with_form_for @validating_user, :credit_limit\n    assert_select 'input.required'\n    assert_select 'input[required]'\n    assert_select 'input.required[required]#validating_user_credit_limit'\n\n    @validating_user.new_record!\n    with_form_for @validating_user, :credit_limit\n    assert_select 'input.required'\n    assert_select 'input[required]'\n    assert_select 'input.required[required]#validating_user_credit_limit'\n  end\n\n  test 'builder input is required when validation is on update and is persisted' do\n    with_form_for @validating_user, :phone_number\n    assert_select 'input.required'\n    assert_select 'input[required]'\n    assert_select 'input.required[required]#validating_user_phone_number'\n  end\n\n  test 'builder input does not be required when validation is on update and is not persisted' do\n    @validating_user.new_record!\n    with_form_for @validating_user, :phone_number\n    assert_no_select 'input.required'\n    assert_no_select 'input[required]'\n    assert_select 'input.optional#validating_user_phone_number'\n  end\n\n  test 'builder input does not generate required html attribute when option is set to false when it is set to true in wrapper' do\n    swap SimpleForm, browser_validations: true do\n      swap_wrapper :default, self.custom_wrapper_with_required_input do\n        with_concat_form_for(@user) do |f|\n          concat f.input :name, required: false\n        end\n        assert_no_select 'input[type=text][required]'\n      end\n    end\n  end\nend\n"
  },
  {
    "path": "test/inputs/rich_text_area_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass RichTextAreaInputTest < ActionView::TestCase\n  test 'input generates a text area for text attributes' do\n    with_input_for @user, :description, :text\n    assert_select 'textarea.text#user_description'\n  end\n\n  test 'input generates a text area for text attributes that accept placeholder' do\n    with_input_for @user, :description, :text, placeholder: 'Put in some text'\n    assert_select 'textarea.text[placeholder=\"Put in some text\"]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/string_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass StringInputTest < ActionView::TestCase\n  test 'input maps text field to string attribute' do\n    with_input_for @user, :name, :string\n    assert_select \"input#user_name[type=text][name='user[name]'][value='New in SimpleForm!']\"\n  end\n\n  test 'input maps text field to citext attribute' do\n    with_input_for @user, :name, :citext\n    assert_select \"input#user_name[type=text][name='user[name]'][value='New in SimpleForm!']\"\n  end\n\n  test 'input generates a password field for password attributes' do\n    with_input_for @user, :password, :password\n    assert_select \"input#user_password.password[type=password][name='user[password]']\"\n  end\n\n  test 'input gets maxlength from column definition for string attributes' do\n    with_input_for @user, :name, :string\n    assert_select 'input.string[maxlength=\"100\"]'\n  end\n\n  test 'input does not get maxlength from column without size definition for string attributes' do\n    with_input_for @user, :action, :string\n    assert_no_select 'input.string[maxlength]'\n  end\n\n  test 'input gets maxlength from column definition for password attributes' do\n    with_input_for @user, :password, :password\n    assert_select 'input.password[type=password][maxlength=\"100\"]'\n  end\n\n  test 'input infers maxlength from validation when present' do\n    with_input_for @validating_user, :name, :string\n    assert_select 'input.string[maxlength=\"25\"]'\n  end\n\n  test 'input infers minlength from validation when present' do\n    with_input_for @validating_user, :name, :string\n    assert_select 'input.string[minlength=\"5\"]'\n  end\n\n  test 'input infers maxlength from validation proc when present' do\n    with_input_for @validating_user, :username, :string\n    assert_select 'input.string[maxlength=\"30\"]'\n  end\n\n  test 'input infers minlength from validation proc when present' do\n    with_input_for @validating_user, :username, :string\n    assert_select 'input.string[minlength=\"10\"]'\n  end\n\n  test 'input gets maxlength from validation when :is option present' do\n    with_input_for @validating_user, :home_picture, :string\n    assert_select 'input.string[maxlength=\"12\"]'\n  end\n\n  test 'input gets minlength from validation when :is option present' do\n    with_input_for @validating_user, :home_picture, :string\n    assert_select 'input.string[minlength=\"12\"]'\n  end\n\n  test 'input maxlength is the column limit plus one to make room for decimal point' do\n    with_input_for @user, :credit_limit, :string\n\n    assert_select 'input.string[maxlength=\"16\"]'\n  end\n\n  test 'input does not generate placeholder by default' do\n    with_input_for @user, :name, :string\n    assert_no_select 'input[placeholder]'\n  end\n\n  test 'input accepts the placeholder option' do\n    with_input_for @user, :name, :string, placeholder: 'Put in some text'\n    assert_select 'input.string[placeholder=\"Put in some text\"]'\n  end\n\n  test 'input generates a password field for password attributes that accept placeholder' do\n    with_input_for @user, :password, :password, placeholder: 'Password Confirmation'\n    assert_select 'input[type=password].password[placeholder=\"Password Confirmation\"]#user_password'\n  end\n\n  test 'input does not infer pattern from attributes by default' do\n    with_input_for @other_validating_user, :country, :string\n    assert_no_select 'input[pattern=\"\\w+\"]'\n  end\n\n  test 'input infers pattern from attributes' do\n    with_input_for @other_validating_user, :country, :string, pattern: true\n    assert_select \"input:match('pattern', ?)\", /\\w+/\n  end\n\n  test 'input infers pattern from attributes using proc' do\n    with_input_for @other_validating_user, :name, :string, pattern: true\n    assert_select \"input:match('pattern', ?)\", /\\w+/\n  end\n\n  test 'input does not infer pattern from attributes if root default is false' do\n    swap_wrapper do\n      with_input_for @other_validating_user, :country, :string\n      assert_no_select 'input[pattern=\"\\w+\"]'\n    end\n  end\n\n  test 'input uses given pattern from attributes' do\n    with_input_for @other_validating_user, :country, :string, input_html: { pattern: \"\\\\d+\" }\n    assert_select \"input:match('pattern', ?)\", /\\\\d+/\n  end\n\n  test 'input does not use pattern if model has :without validation option' do\n    with_input_for @other_validating_user, :description, :string, pattern: true\n    assert_no_select 'input[pattern=\"\\d+\"]'\n  end\n\n  test 'input uses i18n to translate placeholder text' do\n    store_translations(:en, simple_form: { placeholders: { user: {\n      name: 'Name goes here'\n    } } }) do\n      with_input_for @user, :name, :string\n      assert_select 'input.string[placeholder=\"Name goes here\"]'\n    end\n  end\n\n  test 'input uses custom i18n scope to translate placeholder text' do\n    store_translations(:en, my_scope: { placeholders: { user: {\n      name: 'Name goes here'\n    } } }) do\n      swap SimpleForm, i18n_scope: :my_scope do\n        with_input_for @user, :name, :string\n        assert_select 'input.string[placeholder=\"Name goes here\"]'\n      end\n    end\n  end\n\n  %i[email url search tel].each do |type|\n    test \"input allows type #{type}\" do\n      with_input_for @user, :name, type\n      assert_select \"input.string.#{type}\"\n      assert_select \"input[type=#{type}]\"\n    end\n\n    test \"input does not allow type #{type} if HTML5 compatibility is disabled\" do\n      swap_wrapper do\n        with_input_for @user, :name, type\n        assert_select \"input[type=text]\"\n        assert_no_select \"input[type=#{type}]\"\n      end\n    end\n  end\n\n  test 'input strips extra spaces from class html attribute with default classes' do\n    with_input_for @user, :name, :string\n    assert_select \"input[class='string required']\"\n    assert_no_select \"input[class='string required ']\"\n    assert_no_select \"input[class=' string required']\"\n  end\n\n  test 'input strips extra spaces from class html attribute when giving a custom class' do\n    with_input_for @user, :name, :string, input_html: { class: \"my_input\" }\n    assert_select \"input[class='string required my_input']\"\n    assert_no_select \"input[class='string required my_input ']\"\n    assert_no_select \"input[class=' string required my_input']\"\n  end\nend\n"
  },
  {
    "path": "test/inputs/text_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass TextInputTest < ActionView::TestCase\n  test 'input generates a text area for text attributes' do\n    with_input_for @user, :description, :text\n    assert_select 'textarea.text#user_description'\n  end\n\n  test 'input generates a text area for text attributes that accept placeholder' do\n    with_input_for @user, :description, :text, placeholder: 'Put in some text'\n    assert_select 'textarea.text[placeholder=\"Put in some text\"]'\n  end\n\n  test 'input generates a placeholder from the translations' do\n    store_translations(:en, simple_form: { placeholders: { user: { name: \"placeholder from i18n en.simple_form.placeholders.user.name\" } } }) do\n      with_input_for @user, :name, :text\n      assert_select 'textarea.text[placeholder=\"placeholder from i18n en.simple_form.placeholders.user.name\"]'\n    end\n  end\n\n  test 'input gets maxlength from column definition for text attributes' do\n    with_input_for @user, :description, :text\n    assert_select 'textarea.text[maxlength=\"200\"]'\n  end\n\n  test 'input infers maxlength column definition from validation when present for text attributes' do\n    with_input_for @validating_user, :description, :text\n    assert_select 'textarea.text[maxlength=\"50\"]'\n  end\n\n  test 'input infers minlength column definition from validation when present for text attributes' do\n    with_input_for @validating_user, :description, :text\n    assert_select 'textarea.text[minlength=\"15\"]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/time_zone_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass TimeZoneInputTest < ActionView::TestCase\n  test 'input generates a time zone select field' do\n    with_input_for @user, :time_zone, :time_zone\n    assert_select 'select#user_time_zone'\n    assert_select 'select option[value=Brasilia]', '(GMT-03:00) Brasilia'\n    assert_no_select 'select option[value=\"\"][disabled=disabled]'\n  end\n\n  test 'input generates a time zone select field with default' do\n    with_input_for @user, :time_zone, :time_zone, default: 'Brasilia'\n    assert_select 'select option[value=Brasilia][selected=selected]'\n    assert_no_select 'select option[value=\"\"]'\n  end\n\n  test 'input generates a time zone select using options priority' do\n    with_input_for @user, :time_zone, :time_zone, priority: /Brasilia/\n    assert_select 'select option[value=\"\"][disabled=disabled]'\n    assert_no_select 'select option[value=\"\"]', /^$/\n  end\n\n  test 'input does generate select element with required html attribute' do\n    with_input_for @user, :time_zone, :time_zone\n    assert_select 'select.required'\n    assert_select 'select[required]'\n  end\nend\n"
  },
  {
    "path": "test/inputs/weekday_input_test.rb",
    "content": "# frozen_string_literal: true\n# encoding: UTF-8\nrequire 'test_helper'\n\nclass WeekdayInputTest < ActionView::TestCase\n  test 'input generates a weekday select' do\n    with_input_for @user, :born_at, :weekday\n    assert_select 'select.weekday#user_born_at'\n  end\n\n  test 'input generates a weekday select that accepts placeholder' do\n    with_input_for @user, :born_at, :weekday, placeholder: 'Put in a weekday'\n    assert_select 'select.weekday[placeholder=\"Put in a weekday\"]'\n  end\nend\n"
  },
  {
    "path": "test/simple_form_test.rb",
    "content": "# frozen_string_literal: true\nrequire 'test_helper'\n\nclass SimpleFormTest < ActiveSupport::TestCase\n  test 'setup block yields self' do\n    SimpleForm.setup do |config|\n      assert_equal SimpleForm, config\n    end\n  end\n\n  test 'setup block configure Simple Form' do\n    SimpleForm.setup do |config|\n      assert_equal SimpleForm, config\n    end\n\n    assert_equal true, SimpleForm.configured?\n  end\nend\n"
  },
  {
    "path": "test/support/discovery_inputs.rb",
    "content": "# frozen_string_literal: true\nclass StringInput < SimpleForm::Inputs::StringInput\n  def input(wrapper_options = nil)\n    \"<section>#{super}</section>\".html_safe\n  end\nend\n\nclass NumericInput < SimpleForm::Inputs::NumericInput\n  def input(wrapper_options = nil)\n    \"<section>#{super}</section>\".html_safe\n  end\nend\n\nclass CustomizedInput < SimpleForm::Inputs::StringInput\n  def input(wrapper_options = nil)\n    \"<section>#{super}</section>\".html_safe\n  end\n\n  def input_method\n    :text_field\n  end\nend\n\nclass DeprecatedInput < SimpleForm::Inputs::StringInput\n  def input\n    \"<section>#{super}</section>\".html_safe\n  end\n\n  def input_method\n    :text_field\n  end\nend\n\nclass CollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput\n  def input_html_classes\n    super.push('chosen')\n  end\nend\n\nclass FileInput < SimpleForm::Inputs::FileInput\n  def input_html_classes\n    super.delete_if { |html_class| html_class == :file }\n    super.push('file-upload')\n  end\nend\n\nmodule CustomInputs\n  class CustomizedInput < SimpleForm::Inputs::StringInput\n    def input_html_classes\n      super.push('customized-namespace-custom-input')\n    end\n  end\n\n  class PasswordInput < SimpleForm::Inputs::PasswordInput\n    def input_html_classes\n      super.push('password-custom-input')\n    end\n  end\n\n  class NumericInput < SimpleForm::Inputs::PasswordInput\n    def input_html_classes\n      super.push('numeric-custom-input')\n    end\n  end\nend\n"
  },
  {
    "path": "test/support/misc_helpers.rb",
    "content": "# frozen_string_literal: true\nmodule MiscHelpers\n  def store_translations(locale, translations, &block)\n    I18n.backend.store_translations locale, translations\n    yield\n  ensure\n    I18n.reload!\n    I18n.backend.send :init_translations\n  end\n\n  def assert_no_select(selector, value = nil)\n    assert_select(selector, text: value, count: 0)\n  end\n\n  def swap(object, new_values)\n    old_values = {}\n    new_values.each do |key, value|\n      old_values[key] = object.send key\n      object.send :\"#{key}=\", value\n    end\n    yield\n  ensure\n    old_values.each do |key, value|\n      object.send :\"#{key}=\", value\n    end\n  end\n\n  def stub_any_instance(klass, method, value)\n    klass.class_eval do\n      alias_method :\"new_#{method}\", method\n\n      define_method(method) do\n        if value.respond_to?(:call)\n          value.call\n        else\n          value\n        end\n      end\n    end\n\n    yield\n  ensure\n    klass.class_eval do\n      undef_method method\n      alias_method method, :\"new_#{method}\"\n      undef_method :\"new_#{method}\"\n    end\n  end\n\n  def swap_wrapper(name = :default, wrapper = custom_wrapper)\n    old = SimpleForm.wrappers[name.to_s]\n    SimpleForm.wrappers[name.to_s] = wrapper\n    yield\n  ensure\n    SimpleForm.wrappers[name.to_s] = old\n  end\n\n  def custom_wrapper\n    SimpleForm.build tag: :section, class: \"custom_wrapper\", pattern: false do |b|\n      b.use :pattern\n      b.wrapper :another, class: \"another_wrapper\" do |ba|\n        ba.use :label\n        ba.use :input\n      end\n      b.wrapper :error_wrapper, tag: :div, class: \"error_wrapper\" do |be|\n        be.use :error, wrap_with: { tag: :span, class: \"omg_error\" }\n      end\n      b.use :hint, wrap_with: { class: \"omg_hint\" }\n    end\n  end\n\n  def custom_wrapper_with_wrapped_optional_component\n    SimpleForm.build tag: :section, class: \"custom_wrapper\" do |b|\n      b.wrapper tag: :div, class: 'no_output_wrapper' do |ba|\n        ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }\n      end\n    end\n  end\n\n  def custom_wrapper_with_unless_blank\n    SimpleForm.build tag: :section, class: \"custom_wrapper\" do |b|\n      b.wrapper tag: :div, class: 'no_output_wrapper', unless_blank: true do |ba|\n        ba.optional :hint, wrap_with: { tag: :p, class: 'omg_hint' }\n      end\n    end\n  end\n\n  def custom_wrapper_with_input_class\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :label\n      b.use :input, class: 'inline-class'\n    end\n  end\n\n  def custom_wrapper_with_input_data_modal\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :label\n      b.use :input, data: { modal: 'data-modal', wrapper: 'data-wrapper' }\n    end\n  end\n\n  def custom_wrapper_with_input_aria_modal\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :label\n      b.use :input, aria: { modal: 'aria-modal', wrapper: 'aria-wrapper' }\n    end\n  end\n\n  def custom_wrapper_with_label_class\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :label, class: 'inline-class'\n      b.use :input\n    end\n  end\n\n  def custom_wrapper_with_input_attributes\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :input, data: { modal: true }\n    end\n  end\n\n  def custom_wrapper_with_label_input_class\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.use :label_input, class: 'inline-class'\n    end\n  end\n\n  def custom_wrapper_with_wrapped_input\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.wrapper tag: :div, class: 'elem' do |component|\n        component.use :label\n        component.use :input, wrap_with: { tag: :div, class: 'input' }\n      end\n    end\n  end\n\n  def custom_wrapper_with_wrapped_label\n    SimpleForm.build tag: :div, class: \"custom_wrapper\" do |b|\n      b.wrapper tag: :div, class: 'elem' do |component|\n        component.use :label, wrap_with: { tag: :div, class: 'label' }\n        component.use :input\n      end\n    end\n  end\n\n  def custom_wrapper_without_top_level\n    SimpleForm.build tag: false, class: 'custom_wrapper_without_top_level' do |b|\n      b.use :label_input\n      b.use :hint,  wrap_with: { tag: :span, class: :hint }\n      b.use :error, wrap_with: { tag: :span, class: :error }\n    end\n  end\n\n  def custom_wrapper_without_class\n    SimpleForm.build tag: :div, wrapper_html: { id: 'custom_wrapper_without_class' } do |b|\n      b.use :label_input\n    end\n  end\n\n  def custom_wrapper_with_label_html_option\n    SimpleForm.build tag: :div, class: \"custom_wrapper\", label_html: { class: 'extra-label-class' } do |b|\n      b.use :label_input\n    end\n  end\n\n  def custom_wrapper_with_wrapped_label_input\n    SimpleForm.build tag: :section, class: \"custom_wrapper\", pattern: false do |b|\n      b.use :label_input, wrap_with: { tag: :div, class: :field }\n    end\n  end\n\n  def custom_wrapper_with_additional_attributes\n    SimpleForm.build tag: :div, class: 'custom_wrapper', html: { data: { wrapper: :test }, title: 'some title' } do |b|\n      b.use :label_input\n    end\n  end\n\n  def custom_wrapper_with_full_error\n    SimpleForm.build tag: :div, class: 'custom_wrapper' do |b|\n      b.use :full_error,  wrap_with: { tag: :span, class: :error }\n    end\n  end\n\n  def custom_wrapper_with_label_text\n    SimpleForm.build label_text: proc { |label, required| \"**#{label}**\" } do |b|\n      b.use :label_input\n    end\n  end\n\n  def custom_wrapper_with_custom_label_component\n    SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|\n      b.use :label_text\n    end\n  end\n\n  def custom_wrapper_with_html5_components\n    SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|\n      b.use :label_text\n    end\n  end\n\n  def custom_wrapper_with_required_input\n    SimpleForm.build tag: :span, class: 'custom_wrapper' do |b|\n      b.use :html5\n      b.use :input, required: true\n    end\n  end\n\n  def custom_wrapper_with_input_error_class\n    SimpleForm.build tag: :div, class: \"custom_wrapper\", error_class: :field_with_errors do |b|\n      b.use :label\n      b.use :input, class: 'inline-class', error_class: 'is-invalid'\n    end\n  end\n\n  def custom_wrapper_with_input_valid_class(valid_class: :field_without_errors)\n    SimpleForm.build tag: :div, class: \"custom_wrapper\", valid_class: valid_class do |b|\n      b.use :label\n      b.use :input, class: 'inline-class', valid_class: 'is-valid'\n    end\n  end\n\n  def custom_form_for(object, *args, &block)\n    simple_form_for(object, *args, { builder: CustomFormBuilder }, &block)\n  end\n\n  def custom_mapping_form_for(object, *args, &block)\n    simple_form_for(object, *args, { builder: CustomMapTypeFormBuilder }, &block)\n  end\n\n  def with_concat_form_for(*args, &block)\n    concat simple_form_for(*args, &(block || proc {}))\n  end\n\n  def with_concat_fields_for(*args, &block)\n    concat simple_fields_for(*args, &block)\n  end\n\n  def with_concat_custom_form_for(*args, &block)\n    concat custom_form_for(*args, &block)\n  end\n\n  def with_concat_custom_mapping_form_for(*args, &block)\n    concat custom_mapping_form_for(*args, &block)\n  end\n\n  def with_form_for(object, *args, &block)\n    with_concat_form_for(object) do |f|\n      f.input(*args, &block)\n    end\n  end\n\n  def with_input_for(object, attribute_name, type, options = {})\n    with_concat_form_for(object) do |f|\n      f.input(attribute_name, options.merge(as: type))\n    end\n  end\n\n  def with_input_field_for(object, *args)\n    with_concat_form_for(object) do |f|\n      f.input_field(*args)\n    end\n  end\nend\n\nclass CustomFormBuilder < SimpleForm::FormBuilder\n  def input(attribute_name, *args, &block)\n    super(attribute_name, *args, { input_html: { class: 'custom' } }, &block)\n  end\nend\n\nclass CustomMapTypeFormBuilder < SimpleForm::FormBuilder\n  map_type :custom_type, to: SimpleForm::Inputs::StringInput\nend\n"
  },
  {
    "path": "test/support/mock_controller.rb",
    "content": "# frozen_string_literal: true\nclass MockController\n  attr_writer :action_name\n\n  def _routes\n    self\n  end\n\n  def action_name\n    defined?(@action_name) ? @action_name : \"edit\"\n  end\n\n  def url_for(*)\n    \"http://example.com\"\n  end\n\n  def url_options\n    {}\n  end\n\n  def polymorphic_mappings(*); {}; end\n\n  def hash_for_user_path(*); end\n\n  def hash_for_validating_user_path(*); end\n\n  def hash_for_other_validating_user_path(*); end\n  \n  def hash_for_users_path(*); end\nend\n"
  },
  {
    "path": "test/support/models.rb",
    "content": "# frozen_string_literal: true\nAssociation = Struct.new(:klass, :name, :macro, :scope, :options)\n\nColumn = Struct.new(:name, :type, :limit) do\nend\n\nRelation = Struct.new(:records) do\n  delegate :each, to: :records\n\n  def where(conditions = nil)\n    self.class.new conditions ? [records.first] : records\n  end\n\n  def order(conditions = nil)\n    self.class.new conditions ? records.last : records\n  end\n\n  alias_method :to_a,   :records\n  alias_method :to_ary, :records\nend\n\nDecorator = Struct.new(:object) do\n  def to_model\n    object\n  end\nend\n\nPicture = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n  include ActiveModel::Conversion\n\n  def self.where(conditions = nil)\n    if conditions.is_a?(Hash) && conditions[:name]\n      all.to_a.last\n    else\n      all\n    end\n  end\n\n  def self.all\n    Relation.new((1..3).map { |i| new(i, \"#{name} #{i}\") })\n  end\nend\n\nCompany = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n  include ActiveModel::Conversion\n\n  class << self\n    delegate :order, :where, to: :_relation\n  end\n\n  def self._relation\n    all\n  end\n\n  def self.all\n    Relation.new((1..3).map { |i| new(i, \"#{name} #{i}\") })\n  end\n\n  def persisted?\n    true\n  end\nend\n\nFriend = Struct.new(:id, :name) do\n  extend ActiveModel::Naming\n  include ActiveModel::Conversion\n\n  def self.all\n    (1..3).map { |i| new(i, \"#{name} #{i}\") }\n  end\n\n  def persisted?\n    true\n  end\nend\n\nclass Tag < Company\n  def group_method\n    [\"category-1\"]\n  end\nend\n\nTagGroup = Struct.new(:id, :name, :tags)\n\nclass User\n  extend ActiveModel::Naming\n  include ActiveModel::Conversion\n\n  attr_accessor :id, :name, :username, :company, :company_id, :time_zone, :active, :age,\n    :description, :created_at, :updated_at, :credit_limit, :password, :url,\n    :delivery_time, :born_at, :special_company_id, :country, :tags, :tag_ids,\n    :avatar, :home_picture, :email, :status, :residence_country, :phone_number,\n    :post_count, :lock_version, :amount, :attempts, :action, :credit_card, :gender,\n    :extra_special_company_id, :pictures, :picture_ids, :special_pictures,\n    :special_picture_ids, :uuid, :friends, :friend_ids, :special_tags, :special_tag_ids,\n    :citext, :hstore, :json, :jsonb, :hourly, :favorite_color\n\n  def self.build(extra_attributes = {})\n    attributes = {\n      id: 1,\n      name: 'New in SimpleForm!',\n      description: 'Hello!',\n      created_at: Time.now\n    }.merge! extra_attributes\n\n    new attributes\n  end\n\n  def initialize(options = {})\n    @new_record = false\n    options.each do |key, value|\n      send(\"#{key}=\", value)\n    end if options\n  end\n\n  def new_record!\n    @new_record = true\n  end\n\n  def persisted?\n    !@new_record\n  end\n\n  def company_attributes=(*)\n  end\n\n  def tags_attributes=(*)\n  end\n\n  def column_for_attribute(attribute)\n    column_type, limit = case attribute.to_sym\n      when :name, :status, :password then [:string, 100]\n      when :description   then [:text, 200]\n      when :age           then :integer\n      when :credit_limit  then [:decimal, 15]\n      when :active        then :boolean\n      when :born_at       then :date\n      when :delivery_time then :time\n      when :created_at    then :datetime\n      when :updated_at    then :timestamp\n      when :lock_version  then :integer\n      when :home_picture  then :string\n      when :amount        then :integer\n      when :attempts      then :integer\n      when :action        then :string\n      when :credit_card   then :string\n      else attribute.to_sym\n    end\n    Column.new(attribute, column_type, limit)\n  end\n\n  begin\n    require 'active_model/type'\n    begin\n      ActiveModel::Type.lookup(:text)\n    rescue ArgumentError        # :text is no longer an ActiveModel::Type\n      # But we don't want our tests to depend on ActiveRecord\n      class ::ActiveModel::Type::Text < ActiveModel::Type::String\n        def type; :text; end\n      end\n      ActiveModel::Type.register(:text, ActiveModel::Type::Text)\n    end\n    def type_for_attribute(attribute)\n      column_type, limit = case attribute\n        when 'name', 'status', 'password' then [:string, 100]\n        when 'description'   then [:text, 200]\n        when 'age'           then :integer\n        when 'credit_limit'  then [:decimal, 15]\n        when 'active'        then :boolean\n        when 'born_at'       then :date\n        when 'delivery_time' then :time\n        when 'created_at'    then :datetime\n        when 'updated_at'    then :datetime\n        when 'lock_version'  then :integer\n        when 'home_picture'  then :string\n        when 'amount'        then :integer\n        when 'attempts'      then :integer\n        when 'action'        then :string\n        when 'credit_card'   then :string\n        when 'uuid'          then :string\n        when 'citext'        then :string\n        when 'hstore'        then [:text, 200]\n        when 'json'          then [:text, 200]\n        when 'jsonb'         then [:text, 200]\n      end\n\n      ActiveModel::Type.lookup(column_type, limit: limit)\n    end\n  rescue LoadError\n  end\n\n  def has_attribute?(attribute)\n    case attribute.to_sym\n      when :name, :status, :password, :description, :age,\n        :credit_limit, :active, :born_at, :delivery_time,\n        :created_at, :updated_at, :lock_version, :home_picture,\n        :amount, :attempts, :action, :credit_card, :uuid,\n        :citext, :hstore, :json, :jsonb then true\n      else false\n    end\n  end\n\n  def self.human_attribute_name(attribute, options = {})\n    case attribute\n      when 'name', :name\n        'Super User Name!'\n      when 'description'\n        'User Description!'\n      when 'status'\n        \"[#{options[:base].id}] User Status!\"\n      when 'company'\n        'Company Human Name!'\n      else\n        attribute.to_s.humanize\n    end\n  end\n\n  def self.reflect_on_association(association)\n    case association\n      when :company\n        Association.new(Company, association, :belongs_to, nil, {})\n      when :tags\n        Association.new(Tag, association, :has_many, nil, {})\n      when :special_tags\n        Association.new(Tag, association, :has_many, ->(user) { where(id: user.id) }, {})\n      when :first_company\n        Association.new(Company, association, :has_one, nil, {})\n      when :special_company\n        Association.new(Company, association, :belongs_to, nil, conditions: { id: 1 })\n      when :extra_special_company\n        Association.new(Company, association, :belongs_to, nil, conditions: proc { { id: self.id } })\n      when :pictures\n        Association.new(Picture, association, :has_many, nil, {})\n      when :special_pictures\n        Association.new(Picture, association, :has_many, proc { where(name: self.name) }, {})\n      when :friends\n        Association.new(Friend, association, :has_many, nil, {})\n    end\n  end\n\n  def errors\n    @errors ||= begin\n      errors = ActiveModel::Errors.new(self)\n      errors.add(:name, \"cannot be blank\")\n      errors.add(:description, 'must be longer than 15 characters')\n      errors.add(:age, 'is not a number')\n      errors.add(:age, 'must be greater than 18')\n      errors.add(:company, 'company must be present')\n      errors.add(:company_id, 'must be valid')\n      errors\n    end\n  end\n\n  def self.readonly_attributes\n    [\"credit_card\"]\n  end\nend\n\nclass ValidatingUser < User\n  include ActiveModel::Validations\n  validates :name, presence: true\n  validates :username, presence: true\n  validates :company, presence: true\n  validates :age, presence: true, if: proc { |user| user.name }\n  validates :amount, presence: true, unless: proc { |user| user.age }\n\n  validates :action,            presence: true, on: :create\n  validates :credit_limit,      presence: true, on: :save\n  validates :phone_number,      presence: true, on: :update\n\n  validates_numericality_of :age,\n    greater_than_or_equal_to: 18,\n    less_than_or_equal_to: 99,\n    only_integer: true\n  validates_numericality_of :amount,\n    greater_than: :min_amount,\n    less_than: :max_amount,\n    only_integer: true\n  validates_numericality_of :attempts,\n    greater_than_or_equal_to: :min_attempts,\n    less_than_or_equal_to: :max_attempts,\n    only_integer: true\n  validates_length_of :name, maximum: 25, minimum: 5\n  if ActiveModel.gem_version >= Gem::Version::new(\"7.1.0\")\n    validates_length_of :username, maximum: -> { 30 }, minimum: -> { 10 }\n  else\n    validates_length_of :username, maximum: ->(_) { 30 }, minimum: ->(_) { 10 }\n  end\n  validates_length_of :description, in: 15..50\n  validates_length_of :home_picture, is: 12\n\n  def min_amount\n    10\n  end\n\n  def max_amount\n    100\n  end\n\n  def min_attempts\n    1\n  end\n\n  def max_attempts\n    100\n  end\nend\n\nclass OtherValidatingUser < User\n  include ActiveModel::Validations\n  validates_numericality_of :age,\n    greater_than: 17,\n    less_than: 100,\n    only_integer: true\n  validates_numericality_of :amount,\n    greater_than: proc { |user| user.age },\n    less_than: proc { |user| user.age + 100 },\n    only_integer: true\n  validates_numericality_of :attempts,\n    greater_than_or_equal_to: proc { |user| user.age },\n    less_than_or_equal_to: proc { |user| user.age + 100 },\n    only_integer: true\n\n  validates_format_of :country, with: /\\w+/\n  validates_format_of :name, with: proc { /\\w+/ }\n  validates_format_of :description, without: /\\d+/\nend\n\nclass HashBackedAuthor < Hash\n  extend ActiveModel::Naming\n  include ActiveModel::Conversion\n\n  def persisted?; false; end\n\n  def name\n    'hash backed author'\n  end\nend\n\nclass UserNumber1And2 < User\nend\n\nclass UserWithAttachment < User\n  def avatar_attachment\n    OpenStruct.new\n  end\n\n  def avatars_attachments\n    OpenStruct.new\n  end\n\n  def remote_cover_url\n    \"/uploads/cover.png\"\n  end\n\n  def profile_image_attacher\n    OpenStruct.new\n  end\n\n  def portrait_file_name\n    \"portrait.png\"\n  end\nend\n"
  },
  {
    "path": "test/test_helper.rb",
    "content": "# frozen_string_literal: true\nrequire 'minitest/autorun'\n\nrequire 'active_model'\nrequire 'action_controller'\nrequire 'action_view'\n\nActionView::RoutingUrlFor.include ActionDispatch::Routing::UrlFor\n\nrequire 'action_view/template'\nrequire 'action_view/test_case'\n\nmodule Rails\n  def self.env\n    ActiveSupport::StringInquirer.new(\"test\")\n  end\nend\n\n$:.unshift File.expand_path(\"../../lib\", __FILE__)\nrequire 'simple_form'\n\nrequire \"rails/generators/test_case\"\nrequire 'generators/simple_form/install_generator'\n\nDir[\"#{File.dirname(__FILE__)}/support/*.rb\"].each do |file|\n  require file unless file.end_with?('discovery_inputs.rb')\nend\nI18n.default_locale = :en\n\nrequire 'country_select'\n\nRails::Dom::Testing::Assertions::SelectorAssertions::HTMLSelector::NO_STRIP << \"label\"\n\nif ActiveSupport::TestCase.respond_to?(:test_order=)\n  ActiveSupport::TestCase.test_order = :random\nend\n\nrequire \"rails/test_unit/line_filtering\"\n\nclass ActionView::TestCase\n  include MiscHelpers\n  include SimpleForm::ActionViewExtensions::FormHelper\n\n  extend Rails::LineFiltering\n\n  setup :set_controller\n  setup :setup_users\n\n  def set_controller\n    @controller = MockController.new\n  end\n\n  def setup_users(extra_attributes = {})\n    @user = User.build(extra_attributes)\n    @decorated_user = Decorator.new(@user)\n\n    @validating_user = ValidatingUser.build({\n      name: 'Tester McTesterson',\n      username: 'mctesterson',\n      description: 'A test user of the most distinguished caliber',\n      home_picture: 'Home picture',\n      age: 19,\n      amount: 15,\n      attempts: 1,\n      company: [1]\n    }.merge!(extra_attributes))\n\n    @other_validating_user = OtherValidatingUser.build({\n      age: 19,\n      company: 1\n    }.merge!(extra_attributes))\n  end\n\n  def protect_against_forgery?\n    false\n  end\n\n  def user_path(*args)\n    '/users'\n  end\n\n  def company_user_path(*args)\n    '/company/users'\n  end\n\n  alias :users_path :user_path\n  alias :super_user_path :user_path\n  alias :validating_user_path :user_path\n  alias :validating_users_path :user_path\n  alias :other_validating_user_path :user_path\n  alias :user_with_attachment_path :user_path\nend\n"
  }
]