Merge branch 'master' into kb-ek-change-wraper-collection
Conflicts: CHANGELOG.md lib/simple_form/tags.rb
This commit is contained in:
commit
e8e1973d17
|
@ -2,6 +2,12 @@ language: ruby
|
|||
rvm:
|
||||
- 1.9.3
|
||||
- 2.0.0
|
||||
gemfile:
|
||||
- gemfiles/Gemfile.rails-head
|
||||
- Gemfile
|
||||
matrix:
|
||||
allow_failures:
|
||||
- gemfile: gemfiles/Gemfile.rails-head
|
||||
notifications:
|
||||
email: false
|
||||
campfire:
|
||||
|
|
|
@ -2,12 +2,21 @@
|
|||
|
||||
### enhancements
|
||||
* 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 [@bernardoamc](https://github.com/bernardoamc)
|
||||
* `input_field` uses the same wrapper as input but only with attribute components. [@nashby](https://github.com/nashby)
|
||||
* Add wrapper mapping per form basis [@rcillo](https://github.com/rcillo) and [@bernardoamc](https://github.com/bernardoamc)
|
||||
* 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)
|
||||
* Add `include_default_input_wrapper_class` config [@luizcosta](https://github.com/luizcosta)
|
||||
* Map `datetime`, `date` and `time` input types to their respective HTML5 input tags
|
||||
when the `:html5` is set to `true` [@volmer](https://github.com/volmer)
|
||||
|
||||
### bug fix
|
||||
* Collection input generates `required` attribute if it has `prompt` option. [@nashby](https://github.com/nashby)
|
||||
|
||||
## 3.0.1
|
||||
|
||||
### bug fix
|
||||
* Fix XSS vulnerability on label, hint and error components.
|
||||
|
||||
## 3.0.0
|
||||
|
||||
### enhancements
|
||||
|
|
6
Gemfile
6
Gemfile
|
@ -3,9 +3,9 @@ source 'https://rubygems.org'
|
|||
gemspec
|
||||
|
||||
gem 'country_select', '~> 1.1.1'
|
||||
gem 'railties', '>= 4.0.0', '< 4.1'
|
||||
gem 'activemodel', '>= 4.0.0', '< 4.1'
|
||||
gem 'actionpack', '>= 4.0.0', '< 4.1'
|
||||
gem 'railties', github: 'rails/rails', branch: '4-0-stable'
|
||||
gem 'activemodel', github: 'rails/rails', branch: '4-0-stable'
|
||||
gem 'actionpack', github: 'rails/rails', branch: '4-0-stable'
|
||||
gem 'rake'
|
||||
gem 'rdoc'
|
||||
gem 'tzinfo'
|
||||
|
|
68
Gemfile.lock
68
Gemfile.lock
|
@ -1,60 +1,66 @@
|
|||
GIT
|
||||
remote: git://github.com/rails/rails.git
|
||||
revision: b632a8237745c62747558551c74e32a3bb056e09
|
||||
branch: 4-0-stable
|
||||
specs:
|
||||
actionpack (4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
builder (~> 3.1.0)
|
||||
erubis (~> 2.7.0)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
activemodel (4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
builder (~> 3.1.0)
|
||||
activesupport (4.0.2)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
railties (4.0.2)
|
||||
actionpack (= 4.0.2)
|
||||
activesupport (= 4.0.2)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
simple_form (3.0.0)
|
||||
simple_form (3.0.1)
|
||||
actionpack (>= 4.0.0, < 4.1)
|
||||
activemodel (>= 4.0.0, < 4.1)
|
||||
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionpack (4.0.0)
|
||||
activesupport (= 4.0.0)
|
||||
builder (~> 3.1.0)
|
||||
erubis (~> 2.7.0)
|
||||
rack (~> 1.5.2)
|
||||
rack-test (~> 0.6.2)
|
||||
activemodel (4.0.0)
|
||||
activesupport (= 4.0.0)
|
||||
builder (~> 3.1.0)
|
||||
activesupport (4.0.0)
|
||||
i18n (~> 0.6, >= 0.6.4)
|
||||
minitest (~> 4.2)
|
||||
multi_json (~> 1.3)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 0.3.37)
|
||||
atomic (1.1.9)
|
||||
atomic (1.1.14)
|
||||
builder (3.1.4)
|
||||
country_select (1.1.3)
|
||||
erubis (2.7.0)
|
||||
i18n (0.6.4)
|
||||
json (1.7.7)
|
||||
i18n (0.6.9)
|
||||
json (1.8.1)
|
||||
minitest (4.7.5)
|
||||
multi_json (1.7.7)
|
||||
multi_json (1.8.2)
|
||||
rack (1.5.2)
|
||||
rack-test (0.6.2)
|
||||
rack (>= 1.0)
|
||||
railties (4.0.0)
|
||||
actionpack (= 4.0.0)
|
||||
activesupport (= 4.0.0)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (10.0.4)
|
||||
rake (10.1.0)
|
||||
rdoc (4.0.1)
|
||||
json (~> 1.4)
|
||||
thor (0.18.1)
|
||||
thread_safe (0.1.0)
|
||||
thread_safe (0.1.3)
|
||||
atomic
|
||||
tzinfo (0.3.37)
|
||||
tzinfo (0.3.38)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
actionpack (>= 4.0.0, < 4.1)
|
||||
activemodel (>= 4.0.0, < 4.1)
|
||||
actionpack!
|
||||
activemodel!
|
||||
country_select (~> 1.1.1)
|
||||
railties (>= 4.0.0, < 4.1)
|
||||
railties!
|
||||
rake
|
||||
rdoc
|
||||
simple_form!
|
||||
|
|
|
@ -500,9 +500,9 @@ specifying the helper method in the column `Mapping` as the `as:` option.
|
|||
`float` | `input[type=number]` | `float`
|
||||
`decimal` | `input[type=number]` | `decimal`
|
||||
`range` | `input[type=range]` | -
|
||||
`datetime` | `input[type=datetime]` | `datetime/timestamp`
|
||||
`date` | `input[type=date]` | `date`
|
||||
`time` | `input[type=time]` | `time`
|
||||
`datetime` | `datetime select` | `datetime/timestamp`
|
||||
`date` | `date select` | `date`
|
||||
`time` | `time select` | `time`
|
||||
`select` | `select` | `belongs_to`/`has_many`/`has_and_belongs_to_many` associations
|
||||
`radio_buttons` | collection of `input[type=radio]` | `belongs_to` associations
|
||||
`check_boxes` | collection of `input[type=checkbox]` | `has_many`/`has_and_belongs_to_many` associations
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gemspec :path => '..'
|
||||
|
||||
gem 'country_select', '~> 1.1.1'
|
||||
gem 'railties', github: 'rails/rails'
|
||||
gem 'activemodel', github: 'rails/rails'
|
||||
gem 'actionpack', github: 'rails/rails'
|
||||
gem 'rake'
|
||||
gem 'rdoc'
|
||||
gem 'tzinfo'
|
|
@ -142,4 +142,8 @@ SimpleForm.setup do |config|
|
|||
|
||||
# Default class for inputs
|
||||
# config.input_class = nil
|
||||
|
||||
# Defines if the default input wrapper class should be included in radio
|
||||
# collection wrappers.
|
||||
# config.include_default_input_wrapper_class = true
|
||||
end
|
||||
|
|
|
@ -153,6 +153,10 @@ module SimpleForm
|
|||
mattr_accessor :input_class
|
||||
@@input_class = nil
|
||||
|
||||
# Defines if an input wrapper class should be included or not
|
||||
mattr_accessor :include_default_input_wrapper_class
|
||||
@@include_default_input_wrapper_class = true
|
||||
|
||||
## WRAPPER CONFIGURATION
|
||||
# The default wrapper to be used by the FormBuilder.
|
||||
mattr_accessor :default_wrapper
|
||||
|
|
|
@ -12,7 +12,7 @@ module SimpleForm
|
|||
protected
|
||||
|
||||
def error_text
|
||||
"#{options[:error_prefix]} #{errors.send(error_method)}".lstrip.html_safe
|
||||
"#{html_escape(options[:error_prefix])} #{errors.send(error_method)}".lstrip.html_safe
|
||||
end
|
||||
|
||||
def error_method
|
||||
|
|
|
@ -5,8 +5,13 @@ module SimpleForm
|
|||
def hint
|
||||
@hint ||= begin
|
||||
hint = options[:hint]
|
||||
hint_content = hint.is_a?(String) ? hint : translate(:hints)
|
||||
hint_content.html_safe if hint_content
|
||||
|
||||
if hint.is_a?(String)
|
||||
html_escape(hint)
|
||||
else
|
||||
content = translate(:hints)
|
||||
content.html_safe if content
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ module SimpleForm
|
|||
end
|
||||
|
||||
def label_text
|
||||
SimpleForm.label_text.call(raw_label_text, required_label_text).strip.html_safe
|
||||
SimpleForm.label_text.call(html_escape(raw_label_text), required_label_text).strip.html_safe
|
||||
end
|
||||
|
||||
def label_target
|
||||
|
|
|
@ -108,16 +108,11 @@ module SimpleForm
|
|||
#
|
||||
def input(attribute_name, options={}, &block)
|
||||
options = @defaults.deep_dup.deep_merge(options) if @defaults
|
||||
|
||||
input = find_input(attribute_name, options, &block)
|
||||
wrapper = find_wrapper(input.input_type, options)
|
||||
|
||||
chosen =
|
||||
if name = options[:wrapper] || find_wrapper_mapping(input.input_type)
|
||||
name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
|
||||
else
|
||||
wrapper
|
||||
end
|
||||
|
||||
chosen.render input
|
||||
wrapper.render input
|
||||
end
|
||||
alias :attribute :input
|
||||
|
||||
|
@ -140,7 +135,11 @@ module SimpleForm
|
|||
options[:input_html] = options.except(:as, :collection, :label_method, :value_method, *ATTRIBUTE_COMPONENTS)
|
||||
options = @defaults.deep_dup.deep_merge(options) if @defaults
|
||||
|
||||
SimpleForm::Wrappers::Root.new(ATTRIBUTE_COMPONENTS + [:input], wrapper: false).render find_input(attribute_name, options)
|
||||
input = find_input(attribute_name, options)
|
||||
wrapper = find_wrapper(input.input_type, options)
|
||||
components = (wrapper.components & ATTRIBUTE_COMPONENTS) + [:input]
|
||||
|
||||
SimpleForm::Wrappers::Root.new(components, wrapper.options.merge(wrapper: false)).render input
|
||||
end
|
||||
|
||||
# Helper for dealing with association selects/radios, generating the
|
||||
|
@ -564,6 +563,14 @@ module SimpleForm
|
|||
end
|
||||
end
|
||||
|
||||
def find_wrapper(input_type, options)
|
||||
if name = options[:wrapper] || find_wrapper_mapping(input_type)
|
||||
name.respond_to?(:render) ? name : SimpleForm.wrapper(name)
|
||||
else
|
||||
wrapper
|
||||
end
|
||||
end
|
||||
|
||||
# If cache_discovery is enabled, use the class level cache that persists
|
||||
# between requests, otherwise use the instance one.
|
||||
def discovery_cache #:nodoc:
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
require 'simple_form/i18n_cache'
|
||||
require 'active_support/core_ext/string/output_safety'
|
||||
|
||||
module SimpleForm
|
||||
module Inputs
|
||||
class Base
|
||||
include ERB::Util
|
||||
|
||||
extend I18nCache
|
||||
|
||||
include SimpleForm::Helpers::Autofocus
|
||||
|
|
|
@ -22,7 +22,7 @@ module SimpleForm
|
|||
options[:item_wrapper_tag] ||= options.fetch(:item_wrapper_tag, SimpleForm.item_wrapper_tag)
|
||||
options[:item_wrapper_class] = [
|
||||
item_wrapper_class, options[:item_wrapper_class], SimpleForm.item_wrapper_class
|
||||
].compact.presence
|
||||
].compact.presence if SimpleForm.include_default_input_wrapper_class
|
||||
|
||||
options[:collection_wrapper_tag] ||= options.fetch(:collection_wrapper_tag, SimpleForm.collection_wrapper_tag)
|
||||
options[:collection_wrapper_class] = [
|
||||
|
|
|
@ -2,8 +2,12 @@ module SimpleForm
|
|||
module Inputs
|
||||
class DateTimeInput < Base
|
||||
def input
|
||||
if use_html5_inputs?
|
||||
@builder.send(:"#{input_type}_field", attribute_name, input_html_options)
|
||||
else
|
||||
@builder.send(:"#{input_type}_select", attribute_name, input_options, input_html_options)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
@ -19,6 +23,10 @@ module SimpleForm
|
|||
position = ActionView::Helpers::DateTimeSelector::POSITION[position]
|
||||
"#{attribute_name}_#{position}i"
|
||||
end
|
||||
|
||||
def use_html5_inputs?
|
||||
input_options[:html5]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,7 +17,7 @@ module SimpleForm
|
|||
|
||||
if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
|
||||
label_options = {}
|
||||
add_default_name_and_id_for_value(text, label_options)
|
||||
add_default_name_and_id_for_value(value, label_options)
|
||||
label_options['for'] = label_options['id']
|
||||
rendered_item = content_tag(:label, rendered_item, label_options)
|
||||
end
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module SimpleForm
|
||||
VERSION = "3.0.0".freeze
|
||||
VERSION = "3.0.1".freeze
|
||||
end
|
||||
|
|
|
@ -80,8 +80,13 @@ class ErrorTest < ActionView::TestCase
|
|||
assert_no_select 'p.error[error_method]'
|
||||
end
|
||||
|
||||
test 'error should generate an error message with raw HTML tags' do
|
||||
test 'error should escape error prefix text' do
|
||||
with_error_for @user, :name, error_prefix: '<b>Name</b>'
|
||||
assert_select 'span.error', "<b>Name</b> can't be blank"
|
||||
end
|
||||
|
||||
test 'error should generate an error message with raw HTML tags' do
|
||||
with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
|
||||
assert_select 'span.error', "Name can't be blank"
|
||||
assert_select 'span.error b', "Name"
|
||||
end
|
||||
|
|
|
@ -43,8 +43,14 @@ class HintTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
test 'hint should be output as html_safe' do
|
||||
with_hint_for @user, :name, hint: '<b>Bold</b> and not...'
|
||||
with_hint_for @user, :name, hint: '<b>Bold</b> and not...'.html_safe
|
||||
assert_select 'span.hint', 'Bold and not...'
|
||||
assert_select 'span.hint b', 'Bold'
|
||||
end
|
||||
|
||||
test 'builder should escape hint text' do
|
||||
with_hint_for @user, :name, hint: '<script>alert(1337)</script>'
|
||||
assert_select 'span.hint', "<script>alert(1337)</script>"
|
||||
end
|
||||
|
||||
# Without attribute name
|
||||
|
@ -132,7 +138,7 @@ class HintTest < ActionView::TestCase
|
|||
test 'hint with custom wrappers works' do
|
||||
swap_wrapper do
|
||||
with_hint_for @user, :name, hint: "can't be blank"
|
||||
assert_select 'div.omg_hint', "can't be blank"
|
||||
assert_select 'div.omg_hint', "can't be blank"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,14 +88,30 @@ class InputFieldTest < ActionView::TestCase
|
|||
assert_select 'input[min=18]'
|
||||
end
|
||||
|
||||
test 'builder input_field should use pattern component' do
|
||||
test 'builder input_field should not use pattern component by default' do
|
||||
with_concat_form_for(@other_validating_user) do |f|
|
||||
f.input_field :country, as: :string
|
||||
end
|
||||
|
||||
assert_no_select 'input[pattern="\w+"]'
|
||||
end
|
||||
|
||||
test 'builder input_field should infer pattern from attributes' do
|
||||
with_concat_form_for(@other_validating_user) do |f|
|
||||
f.input_field :country, as: :string, pattern: true
|
||||
end
|
||||
|
||||
assert_select 'input[pattern="\w+"]'
|
||||
end
|
||||
|
||||
test 'builder input_field should accept custom patter' do
|
||||
with_concat_form_for(@other_validating_user) do |f|
|
||||
f.input_field :country, as: :string, pattern: '\d+'
|
||||
end
|
||||
|
||||
assert_select 'input[pattern="\d+"]'
|
||||
end
|
||||
|
||||
test 'builder input_field should use readonly component' do
|
||||
with_concat_form_for(@other_validating_user) do |f|
|
||||
f.input_field :age, as: :integer, readonly: true
|
||||
|
|
|
@ -29,6 +29,16 @@ class LabelTest < ActionView::TestCase
|
|||
assert_select 'label.string.required[for=validating_user_name]', /Name/
|
||||
end
|
||||
|
||||
test 'builder should escape label text' do
|
||||
with_label_for @user, :name, label: '<script>alert(1337)</script>', required: false
|
||||
assert_select 'label.string', "<script>alert(1337)</script>"
|
||||
end
|
||||
|
||||
test 'builder should not escape label text if it is safe' do
|
||||
with_label_for @user, :name, label: '<script>alert(1337)</script>'.html_safe, required: false
|
||||
assert_select 'label.string script', "alert(1337)"
|
||||
end
|
||||
|
||||
test 'builder should allow passing options to label tag' do
|
||||
with_label_for @user, :name, label: 'My label', id: 'name_label'
|
||||
assert_select 'label.string#name_label', /My label/
|
||||
|
|
|
@ -230,4 +230,21 @@ class CollectionCheckBoxesInputTest < ActionView::TestCase
|
|||
assert_select 'span.checkbox.inline > label > input'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input check boxes wrapper class are not included when set to falsey' do
|
||||
swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
|
||||
with_input_for @user, :gender, :check_boxes, collection: [:male, :female]
|
||||
|
||||
assert_no_select 'label.checkbox'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
|
||||
swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
|
||||
with_input_for @user, :gender, :check_boxes, collection: [:male, :female], item_wrapper_class: 'custom'
|
||||
|
||||
assert_no_select 'label.checkbox'
|
||||
assert_select 'label.custom'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,6 +18,14 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
|
|||
assert_select 'label[for=user_active_false]', 'No'
|
||||
end
|
||||
|
||||
test 'input as radio should generate internal labels with accurate `for` values with nested boolean style' do
|
||||
swap SimpleForm, boolean_style: :nested do
|
||||
with_input_for @user, :active, :radio_buttons
|
||||
assert_select 'label[for=user_active_true]', 'Yes'
|
||||
assert_select 'label[for=user_active_false]', 'No'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input as radio should use i18n to translate internal labels' do
|
||||
store_translations(:en, simple_form: { yes: 'Sim', no: 'Não' }) do
|
||||
with_input_for @user, :active, :radio_buttons
|
||||
|
@ -323,4 +331,21 @@ class CollectionRadioButtonsInputTest < ActionView::TestCase
|
|||
assert_select 'span.radio.inline > label > input'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input radio wrapper class are not included when set to falsey' do
|
||||
swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
|
||||
with_input_for @user, :gender, :radio_buttons, collection: [:male, :female]
|
||||
|
||||
assert_no_select 'label.radio'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input check boxes custom wrapper class is included when include input wrapper class is falsey' do
|
||||
swap SimpleForm, include_default_input_wrapper_class: false, boolean_style: :nested do
|
||||
with_input_for @user, :gender, :radio_buttons, collection: [:male, :female], item_wrapper_class: 'custom'
|
||||
|
||||
assert_no_select 'label.radio'
|
||||
assert_select 'label.custom'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,18 +1,69 @@
|
|||
# encoding: UTF-8
|
||||
require 'test_helper'
|
||||
|
||||
# Tests for all different kinds of inputs.
|
||||
class DateTimeInputTest < ActionView::TestCase
|
||||
# DateTime input
|
||||
# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
|
||||
class DateTimeInputWithHtml5Test < ActionView::TestCase
|
||||
test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enbled' do
|
||||
with_input_for @user, :created_at, :datetime, html5: true
|
||||
|
||||
assert_select 'input[type="datetime"]'
|
||||
end
|
||||
|
||||
test 'input should generate a datetime select for datetime attributes' do
|
||||
with_input_for @user, :created_at, :datetime
|
||||
|
||||
assert_select 'select.datetime'
|
||||
end
|
||||
|
||||
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enbled' do
|
||||
with_input_for @user, :born_at, :date, html5: true
|
||||
|
||||
assert_select 'input[type="date"]'
|
||||
end
|
||||
|
||||
test 'input should generate a date select for date attributes' do
|
||||
with_input_for @user, :born_at, :date
|
||||
|
||||
assert_select 'select.date'
|
||||
end
|
||||
|
||||
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enbled' do
|
||||
with_input_for @user, :delivery_time, :time, html5: true
|
||||
|
||||
assert_select 'input[type="time"]'
|
||||
end
|
||||
|
||||
test 'input should generate a time select for time attributes' do
|
||||
with_input_for @user, :delivery_time, :time
|
||||
|
||||
assert_select 'select.time'
|
||||
end
|
||||
|
||||
test 'input should generate required html attribute' do
|
||||
with_input_for @user, :delivery_time, :time, required: true, html5: true
|
||||
assert_select 'input.required'
|
||||
assert_select 'input[required]'
|
||||
end
|
||||
|
||||
test 'input should have an aria-required html attribute' do
|
||||
with_input_for @user, :delivery_time, :time, required: true, html5: true
|
||||
assert_select 'input[aria-required=true]'
|
||||
end
|
||||
end
|
||||
|
||||
# Tests for datetime, date and time inputs when HTML5 compatibility is enabled in the wrapper.
|
||||
class DateTimeInputWithoutHtml5Test < ActionView::TestCase
|
||||
test 'input should generate a datetime select by default for datetime attributes' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :created_at, :datetime
|
||||
1.upto(5) do |i|
|
||||
assert_select "form select.datetime#user_created_at_#{i}i"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test 'input should be able to pass options to datetime select' do
|
||||
with_input_for @user, :created_at, :datetime,
|
||||
with_input_for @user, :created_at, :datetime, html5: false,
|
||||
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
|
||||
|
||||
assert_select 'select.datetime[disabled=disabled]'
|
||||
|
@ -21,16 +72,26 @@ class DateTimeInputTest < ActionView::TestCase
|
|||
assert_select 'select.datetime option', 'dia'
|
||||
end
|
||||
|
||||
test 'input should generate a datetime input for datetime attributes if HTML5 compatibility is explicitly enabled' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :created_at, :datetime, html5: true
|
||||
|
||||
assert_select 'input[type="datetime"]'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input should generate a date select for date attributes' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :born_at, :date
|
||||
assert_select 'select.date#user_born_at_1i'
|
||||
assert_select 'select.date#user_born_at_2i'
|
||||
assert_select 'select.date#user_born_at_3i'
|
||||
assert_no_select 'select.date#user_born_at_4i'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input should be able to pass options to date select' do
|
||||
with_input_for @user, :born_at, :date, as: :date,
|
||||
with_input_for @user, :born_at, :date, as: :date, html5: false,
|
||||
disabled: true, prompt: { year: 'ano', month: 'mês', day: 'dia' }
|
||||
|
||||
assert_select 'select.date[disabled=disabled]'
|
||||
|
@ -40,11 +101,20 @@ class DateTimeInputTest < ActionView::TestCase
|
|||
end
|
||||
|
||||
test 'input should be able to pass :default to date select' do
|
||||
with_input_for @user, :born_at, :date, default: Date.today
|
||||
with_input_for @user, :born_at, :date, default: Date.today, html5: false
|
||||
assert_select "select.date option[value=#{Date.today.year}][selected=selected]"
|
||||
end
|
||||
|
||||
test 'input should generate a date input for date attributes if HTML5 compatibility is explicitly enabled' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :born_at, :date, html5: true
|
||||
|
||||
assert_select 'input[type="date"]'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input should generate a time select for time attributes' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :delivery_time, :time
|
||||
assert_select 'input[type=hidden]#user_delivery_time_1i'
|
||||
assert_select 'input[type=hidden]#user_delivery_time_2i'
|
||||
|
@ -52,9 +122,10 @@ class DateTimeInputTest < ActionView::TestCase
|
|||
assert_select 'select.time#user_delivery_time_4i'
|
||||
assert_select 'select.time#user_delivery_time_5i'
|
||||
end
|
||||
end
|
||||
|
||||
test 'input should be able to pass options to time select' do
|
||||
with_input_for @user, :delivery_time, :time, required: true,
|
||||
with_input_for @user, :delivery_time, :time, required: true, html5: false,
|
||||
disabled: true, prompt: { hour: 'hora', minute: 'minuto' }
|
||||
|
||||
assert_select 'select.time[disabled=disabled]'
|
||||
|
@ -62,44 +133,40 @@ class DateTimeInputTest < ActionView::TestCase
|
|||
assert_select 'select.time option', 'minuto'
|
||||
end
|
||||
|
||||
test 'input should generate a time input for time attributes if HTML5 compatibility is explicitly enabled' do
|
||||
swap_wrapper do
|
||||
with_input_for @user, :delivery_time, :time, html5: true
|
||||
|
||||
assert_select 'input[type="time"]'
|
||||
end
|
||||
end
|
||||
|
||||
test 'label should use i18n to get target for date input type' do
|
||||
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
|
||||
with_input_for :project, :created_at, :date
|
||||
with_input_for :project, :created_at, :date, html5: false
|
||||
assert_select 'label[for=project_created_at_2i]'
|
||||
end
|
||||
end
|
||||
|
||||
test 'label should use i18n to get target for datetime input type' do
|
||||
store_translations(:en, date: { order: ['month', 'day', 'year'] }) do
|
||||
with_input_for :project, :created_at, :datetime
|
||||
with_input_for :project, :created_at, :datetime, html5: false
|
||||
assert_select 'label[for=project_created_at_2i]'
|
||||
end
|
||||
end
|
||||
|
||||
test 'label should use order to get target when date input type' do
|
||||
with_input_for :project, :created_at, :date, order: ['month', 'year', 'day']
|
||||
with_input_for :project, :created_at, :date, order: ['month', 'year', 'day'], html5: false
|
||||
assert_select 'label[for=project_created_at_2i]'
|
||||
end
|
||||
|
||||
test 'label should use order to get target when datetime input type' do
|
||||
with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day']
|
||||
with_input_for :project, :created_at, :datetime, order: ['month', 'year', 'day'], html5: false
|
||||
assert_select 'label[for=project_created_at_2i]'
|
||||
end
|
||||
|
||||
test 'label should point to first option when time input type' do
|
||||
with_input_for :project, :created_at, :time
|
||||
with_input_for :project, :created_at, :time, html5: false
|
||||
assert_select 'label[for=project_created_at_4i]'
|
||||
end
|
||||
|
||||
test 'date time input should generate required html attribute' do
|
||||
with_input_for @user, :delivery_time, :time, required: true
|
||||
assert_select 'select.required'
|
||||
assert_select 'select[required]'
|
||||
end
|
||||
|
||||
test 'date time input has an aria-required html attribute' do
|
||||
with_input_for @user, :delivery_time, :time, required: true
|
||||
assert_select 'select.required'
|
||||
assert_select 'select[aria-required=true]'
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue