simple_form 3.0.4 → 3.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of simple_form might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +32 -43
- data/MIT-LICENSE +1 -1
- data/README.md +146 -71
- data/lib/generators/simple_form/install_generator.rb +2 -2
- data/lib/generators/simple_form/templates/README +3 -4
- data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
- data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
- data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
- data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
- data/lib/simple_form.rb +38 -6
- data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
- data/lib/simple_form/components/errors.rb +27 -5
- data/lib/simple_form/components/hints.rb +2 -2
- data/lib/simple_form/components/html5.rb +1 -1
- data/lib/simple_form/components/label_input.rb +20 -2
- data/lib/simple_form/components/labels.rb +9 -5
- data/lib/simple_form/components/maxlength.rb +1 -1
- data/lib/simple_form/components/min_max.rb +1 -1
- data/lib/simple_form/components/pattern.rb +1 -1
- data/lib/simple_form/components/placeholders.rb +2 -2
- data/lib/simple_form/components/readonly.rb +1 -1
- data/lib/simple_form/form_builder.rb +92 -59
- data/lib/simple_form/helpers.rb +5 -5
- data/lib/simple_form/inputs/base.rb +34 -12
- data/lib/simple_form/inputs/block_input.rb +1 -1
- data/lib/simple_form/inputs/boolean_input.rb +23 -13
- data/lib/simple_form/inputs/collection_input.rb +32 -9
- data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
- data/lib/simple_form/inputs/collection_select_input.rb +4 -2
- data/lib/simple_form/inputs/date_time_input.rb +12 -2
- data/lib/simple_form/inputs/file_input.rb +4 -2
- data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
- data/lib/simple_form/inputs/hidden_input.rb +4 -2
- data/lib/simple_form/inputs/numeric_input.rb +5 -4
- data/lib/simple_form/inputs/password_input.rb +4 -2
- data/lib/simple_form/inputs/priority_input.rb +4 -2
- data/lib/simple_form/inputs/range_input.rb +1 -1
- data/lib/simple_form/inputs/string_input.rb +4 -2
- data/lib/simple_form/inputs/text_input.rb +4 -2
- data/lib/simple_form/railtie.rb +7 -0
- data/lib/simple_form/tags.rb +7 -0
- data/lib/simple_form/version.rb +1 -1
- data/lib/simple_form/wrappers.rb +1 -0
- data/lib/simple_form/wrappers/builder.rb +5 -5
- data/lib/simple_form/wrappers/leaf.rb +28 -0
- data/lib/simple_form/wrappers/many.rb +5 -6
- data/lib/simple_form/wrappers/root.rb +1 -1
- data/lib/simple_form/wrappers/single.rb +5 -3
- data/test/action_view_extensions/builder_test.rb +2 -2
- data/test/components/label_test.rb +1 -1
- data/test/form_builder/association_test.rb +17 -0
- data/test/form_builder/error_notification_test.rb +1 -1
- data/test/form_builder/error_test.rb +51 -32
- data/test/form_builder/general_test.rb +2 -2
- data/test/form_builder/input_field_test.rb +21 -37
- data/test/form_builder/label_test.rb +24 -1
- data/test/form_builder/wrapper_test.rb +67 -0
- data/test/generators/simple_form_generator_test.rb +2 -2
- data/test/inputs/boolean_input_test.rb +50 -2
- data/test/inputs/collection_check_boxes_input_test.rb +40 -11
- data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
- data/test/inputs/collection_select_input_test.rb +108 -3
- data/test/inputs/datetime_input_test.rb +105 -38
- data/test/inputs/discovery_test.rb +12 -1
- data/test/inputs/grouped_collection_select_input_test.rb +36 -0
- data/test/inputs/string_input_test.rb +20 -0
- data/test/simple_form_test.rb +8 -0
- data/test/support/discovery_inputs.rb +12 -2
- data/test/support/misc_helpers.rb +46 -8
- data/test/support/models.rb +49 -24
- metadata +7 -7
data/lib/simple_form/version.rb
CHANGED
data/lib/simple_form/wrappers.rb
CHANGED
@@ -45,20 +45,20 @@ module SimpleForm
|
|
45
45
|
@components = []
|
46
46
|
end
|
47
47
|
|
48
|
-
def use(name, options=
|
48
|
+
def use(name, options = {}, &block)
|
49
49
|
if options && wrapper = options[:wrap_with]
|
50
|
-
@components << Single.new(name, wrapper)
|
50
|
+
@components << Single.new(name, wrapper, options.except(:wrap_with))
|
51
51
|
else
|
52
|
-
@components << name
|
52
|
+
@components << Leaf.new(name, options)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
56
|
-
def optional(name, options=
|
56
|
+
def optional(name, options = {}, &block)
|
57
57
|
@options[name] = false
|
58
58
|
use(name, options, &block)
|
59
59
|
end
|
60
60
|
|
61
|
-
def wrapper(name, options=nil)
|
61
|
+
def wrapper(name, options = nil)
|
62
62
|
if block_given?
|
63
63
|
name, options = nil, name if name.is_a?(Hash)
|
64
64
|
builder = self.class.new(@options)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SimpleForm
|
2
|
+
module Wrappers
|
3
|
+
class Leaf
|
4
|
+
attr_reader :namespace
|
5
|
+
|
6
|
+
def initialize(namespace, options = {})
|
7
|
+
@namespace = namespace
|
8
|
+
@options = options
|
9
|
+
end
|
10
|
+
|
11
|
+
def render(input)
|
12
|
+
method = input.method(@namespace)
|
13
|
+
|
14
|
+
if method.arity == 0
|
15
|
+
ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
|
16
|
+
|
17
|
+
method.call
|
18
|
+
else
|
19
|
+
method.call(@options)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find(name)
|
24
|
+
self if @namespace == name
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module SimpleForm
|
2
2
|
module Wrappers
|
3
3
|
# A wrapper is an object that holds several components and render them.
|
4
|
-
# A component may
|
4
|
+
# A component may be any object that responds to `render`.
|
5
5
|
# This API allows inputs/components to be easily wrapped, removing the
|
6
6
|
# need to modify the code only to wrap input in an extra tag.
|
7
7
|
#
|
@@ -10,9 +10,8 @@ module SimpleForm
|
|
10
10
|
# on demand on input generation.
|
11
11
|
class Many
|
12
12
|
attr_reader :namespace, :defaults, :components
|
13
|
-
alias :to_sym :namespace
|
14
13
|
|
15
|
-
def initialize(namespace, components, defaults={})
|
14
|
+
def initialize(namespace, components, defaults = {})
|
16
15
|
@namespace = namespace
|
17
16
|
@components = components
|
18
17
|
@defaults = defaults
|
@@ -25,8 +24,8 @@ module SimpleForm
|
|
25
24
|
options = input.options
|
26
25
|
|
27
26
|
components.each do |component|
|
28
|
-
next if options[component] == false
|
29
|
-
rendered = component.
|
27
|
+
next if options[component.namespace] == false
|
28
|
+
rendered = component.render(input)
|
30
29
|
content.safe_concat rendered.to_s if rendered
|
31
30
|
end
|
32
31
|
|
@@ -62,7 +61,7 @@ module SimpleForm
|
|
62
61
|
end
|
63
62
|
|
64
63
|
def html_options(options)
|
65
|
-
options[:"#{namespace}_html"] || {}
|
64
|
+
(@defaults[:html] || {}).merge(options[:"#{namespace}_html"] || {})
|
66
65
|
end
|
67
66
|
|
68
67
|
def html_classes(input, options)
|
@@ -2,14 +2,16 @@ module SimpleForm
|
|
2
2
|
module Wrappers
|
3
3
|
# `Single` is an optimization for a wrapper that has only one component.
|
4
4
|
class Single < Many
|
5
|
-
def initialize(name, options={})
|
6
|
-
|
5
|
+
def initialize(name, wrapper_options = {}, options = {})
|
6
|
+
@component = Leaf.new(name, options)
|
7
|
+
|
8
|
+
super(name, [@component], wrapper_options)
|
7
9
|
end
|
8
10
|
|
9
11
|
def render(input)
|
10
12
|
options = input.options
|
11
13
|
if options[namespace] != false
|
12
|
-
content =
|
14
|
+
content = @component.render(input)
|
13
15
|
wrap(input, options, content) if content
|
14
16
|
end
|
15
17
|
end
|
@@ -8,13 +8,13 @@ class BuilderTest < ActionView::TestCase
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
|
11
|
+
def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
12
12
|
with_concat_form_for(object) do |f|
|
13
13
|
f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
|
17
|
+
def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
|
18
18
|
with_concat_form_for(object) do |f|
|
19
19
|
f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
|
20
20
|
end
|
@@ -7,7 +7,7 @@ class IsolatedLabelTest < ActionView::TestCase
|
|
7
7
|
SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
|
8
8
|
end
|
9
9
|
|
10
|
-
def with_label_for(object, attribute_name, type, options={})
|
10
|
+
def with_label_for(object, attribute_name, type, options = {})
|
11
11
|
with_concat_form_for(object) do |f|
|
12
12
|
options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
|
13
13
|
SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
|
@@ -113,6 +113,14 @@ class AssociationTest < ActionView::TestCase
|
|
113
113
|
assert_no_select 'form select option[value=3]'
|
114
114
|
end
|
115
115
|
|
116
|
+
test 'builder allows collection to have a scope' do
|
117
|
+
with_association_for @user, :special_pictures
|
118
|
+
assert_select 'form select.select#user_special_picture_ids'
|
119
|
+
assert_select 'form select option[value=3]', '3'
|
120
|
+
assert_no_select 'form select option[value=1]'
|
121
|
+
assert_no_select 'form select option[value=2]'
|
122
|
+
end
|
123
|
+
|
116
124
|
test 'builder marks the record which already belongs to the user' do
|
117
125
|
@user.company_id = 2
|
118
126
|
with_association_for @user, :company, as: :radio_buttons
|
@@ -146,6 +154,15 @@ class AssociationTest < ActionView::TestCase
|
|
146
154
|
end
|
147
155
|
end
|
148
156
|
|
157
|
+
test 'builder does not call order if the given association does not respond to it' do
|
158
|
+
with_association_for @user, :pictures
|
159
|
+
assert_select 'form select.select#user_picture_ids'
|
160
|
+
assert_select 'form select[multiple=multiple]'
|
161
|
+
assert_select 'form select option[value=1]', 'Picture 1'
|
162
|
+
assert_select 'form select option[value=2]', 'Picture 2'
|
163
|
+
assert_select 'form select option[value=3]', 'Picture 3'
|
164
|
+
end
|
165
|
+
|
149
166
|
test 'builder creates a select with multiple options for collection associations' do
|
150
167
|
with_association_for @user, :tags
|
151
168
|
assert_select 'form select.select#user_tag_ids'
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
|
4
4
|
# Tests for f.error_notification
|
5
5
|
class ErrorNotificationTest < ActionView::TestCase
|
6
|
-
def with_error_notification_for(object, options={}, &block)
|
6
|
+
def with_error_notification_for(object, options = {}, &block)
|
7
7
|
with_concat_form_for(object) do |f|
|
8
8
|
f.error_notification(options)
|
9
9
|
end
|
@@ -14,10 +14,6 @@ class ErrorTest < ActionView::TestCase
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def with_custom_error_for(object, *args)
|
18
|
-
with_form_for(object, *args)
|
19
|
-
end
|
20
|
-
|
21
17
|
test 'error should not generate content for attribute without errors' do
|
22
18
|
with_error_for @user, :active
|
23
19
|
assert_no_select 'span.error'
|
@@ -36,7 +32,7 @@ class ErrorTest < ActionView::TestCase
|
|
36
32
|
|
37
33
|
test 'error should generate messages for attribute with single error' do
|
38
34
|
with_error_for @user, :name
|
39
|
-
assert_select 'span.error', "can
|
35
|
+
assert_select 'span.error', "can't be blank"
|
40
36
|
end
|
41
37
|
|
42
38
|
test 'error should generate messages for attribute with one error when using first' do
|
@@ -86,21 +82,12 @@ class ErrorTest < ActionView::TestCase
|
|
86
82
|
|
87
83
|
test 'error should escape error prefix text' do
|
88
84
|
with_error_for @user, :name, error_prefix: '<b>Name</b>'
|
89
|
-
assert_select 'span.error', "<b>Name</b> can
|
90
|
-
end
|
91
|
-
|
92
|
-
test 'error escapes error text' do
|
93
|
-
@user.errors.merge!(action: ['must not contain <b>markup</b>'])
|
94
|
-
|
95
|
-
with_error_for @user, :action
|
96
|
-
|
97
|
-
assert_select 'span.error'
|
98
|
-
assert_no_select 'span.error b', 'markup'
|
85
|
+
assert_select 'span.error', "<b>Name</b> can't be blank"
|
99
86
|
end
|
100
87
|
|
101
88
|
test 'error should generate an error message with raw HTML tags' do
|
102
89
|
with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
|
103
|
-
assert_select 'span.error', "Name can
|
90
|
+
assert_select 'span.error', "Name can't be blank"
|
104
91
|
assert_select 'span.error b', "Name"
|
105
92
|
end
|
106
93
|
|
@@ -108,7 +95,7 @@ class ErrorTest < ActionView::TestCase
|
|
108
95
|
|
109
96
|
test 'full error should generate an full error tag for the attribute' do
|
110
97
|
with_full_error_for @user, :name
|
111
|
-
assert_select 'span.error', "Super User Name! can
|
98
|
+
assert_select 'span.error', "Super User Name! can't be blank"
|
112
99
|
end
|
113
100
|
|
114
101
|
test 'full error should generate an full error tag with a clean HTML' do
|
@@ -118,13 +105,13 @@ class ErrorTest < ActionView::TestCase
|
|
118
105
|
|
119
106
|
test 'full error should allow passing options to full error tag' do
|
120
107
|
with_full_error_for @user, :name, id: 'name_error', error_prefix: "Your name"
|
121
|
-
assert_select 'span.error#name_error', "Your name can
|
108
|
+
assert_select 'span.error#name_error', "Your name can't be blank"
|
122
109
|
end
|
123
110
|
|
124
111
|
test 'full error should not modify the options hash' do
|
125
112
|
options = { id: 'name_error' }
|
126
113
|
with_full_error_for @user, :name, options
|
127
|
-
assert_select 'span.error#name_error', "Super User Name! can
|
114
|
+
assert_select 'span.error#name_error', "Super User Name! can't be blank"
|
128
115
|
assert_equal({ id: 'name_error' }, options)
|
129
116
|
end
|
130
117
|
|
@@ -133,36 +120,68 @@ class ErrorTest < ActionView::TestCase
|
|
133
120
|
test 'error with custom wrappers works' do
|
134
121
|
swap_wrapper do
|
135
122
|
with_error_for @user, :name
|
136
|
-
assert_select 'span.omg_error', "can
|
123
|
+
assert_select 'span.omg_error', "can't be blank"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# FULL_ERROR_WRAPPER
|
128
|
+
|
129
|
+
test 'full error should find errors on association' do
|
130
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
131
|
+
with_form_for @user, :company_id, as: :select
|
132
|
+
assert_select 'span.error', 'Company must be valid'
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
test 'full error can be disabled' do
|
137
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
138
|
+
with_form_for @user, :company_id, as: :select, full_error: false
|
139
|
+
assert_no_select 'span.error'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
test 'full error can be disabled setting error to false' do
|
144
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
145
|
+
with_form_for @user, :company_id, as: :select, error: false
|
146
|
+
assert_no_select 'span.error'
|
137
147
|
end
|
138
148
|
end
|
139
149
|
|
140
150
|
# CUSTOM ERRORS
|
141
151
|
|
142
152
|
test 'input with custom error works' do
|
143
|
-
|
153
|
+
error_text = "Super User Name! can't be blank"
|
154
|
+
with_form_for @user, :name, error: error_text
|
144
155
|
|
145
|
-
assert_select 'span.error',
|
156
|
+
assert_select 'span.error', error_text
|
157
|
+
end
|
158
|
+
|
159
|
+
test 'input with error option as true does not use custom error' do
|
160
|
+
with_form_for @user, :name, error: true
|
161
|
+
|
162
|
+
assert_select 'span.error', "can't be blank"
|
146
163
|
end
|
147
164
|
|
148
165
|
test 'input with custom error does not generate the error if there is no error on the attribute' do
|
149
|
-
|
150
|
-
with_form_for @user, :active, error: error_text
|
166
|
+
with_form_for @user, :active, error: "Super User Active! can't be blank"
|
151
167
|
|
152
168
|
assert_no_select 'span.error'
|
153
169
|
end
|
154
170
|
|
155
|
-
test 'input with custom error
|
156
|
-
|
171
|
+
test 'input with custom error works when using full_error component' do
|
172
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
173
|
+
error_text = "Super User Name! can't be blank"
|
174
|
+
with_form_for @user, :name, error: error_text
|
157
175
|
|
158
|
-
|
159
|
-
|
176
|
+
assert_select 'span.error', error_text
|
177
|
+
end
|
160
178
|
end
|
161
179
|
|
162
|
-
test 'input with custom error does not
|
163
|
-
|
180
|
+
test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do
|
181
|
+
swap_wrapper :default, self.custom_wrapper_with_full_error do
|
182
|
+
with_form_for @user, :active, error: "Super User Active! can't be blank"
|
164
183
|
|
165
|
-
|
166
|
-
|
184
|
+
assert_no_select 'span.error'
|
185
|
+
end
|
167
186
|
end
|
168
187
|
end
|
@@ -302,7 +302,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
302
302
|
|
303
303
|
test 'builder should generate errors for attribute with errors' do
|
304
304
|
with_form_for @user, :name
|
305
|
-
assert_select 'span.error', "can
|
305
|
+
assert_select 'span.error', "can't be blank"
|
306
306
|
end
|
307
307
|
|
308
308
|
test 'builder should be able to disable showing errors for a input' do
|
@@ -312,7 +312,7 @@ class FormBuilderTest < ActionView::TestCase
|
|
312
312
|
|
313
313
|
test 'builder should pass options to errors' do
|
314
314
|
with_form_for @user, :name, error_html: { id: "cool" }
|
315
|
-
assert_select 'span.error#cool', "can
|
315
|
+
assert_select 'span.error#cool', "can't be blank"
|
316
316
|
end
|
317
317
|
|
318
318
|
test 'placeholder should not be generated when set to false' do
|
@@ -88,14 +88,30 @@ class InputFieldTest < ActionView::TestCase
|
|
88
88
|
assert_select 'input[min=18]'
|
89
89
|
end
|
90
90
|
|
91
|
-
test 'builder input_field should use pattern component' do
|
91
|
+
test 'builder input_field should not use pattern component by default' do
|
92
92
|
with_concat_form_for(@other_validating_user) do |f|
|
93
93
|
f.input_field :country, as: :string
|
94
94
|
end
|
95
95
|
|
96
|
+
assert_no_select 'input[pattern="\w+"]'
|
97
|
+
end
|
98
|
+
|
99
|
+
test 'builder input_field should infer pattern from attributes' do
|
100
|
+
with_concat_form_for(@other_validating_user) do |f|
|
101
|
+
f.input_field :country, as: :string, pattern: true
|
102
|
+
end
|
103
|
+
|
96
104
|
assert_select 'input[pattern="\w+"]'
|
97
105
|
end
|
98
106
|
|
107
|
+
test 'builder input_field should accept custom patter' do
|
108
|
+
with_concat_form_for(@other_validating_user) do |f|
|
109
|
+
f.input_field :country, as: :string, pattern: '\d+'
|
110
|
+
end
|
111
|
+
|
112
|
+
assert_select 'input[pattern="\d+"]'
|
113
|
+
end
|
114
|
+
|
99
115
|
test 'builder input_field should use readonly component' do
|
100
116
|
with_concat_form_for(@other_validating_user) do |f|
|
101
117
|
f.input_field :age, as: :integer, readonly: true
|
@@ -123,43 +139,11 @@ class InputFieldTest < ActionView::TestCase
|
|
123
139
|
assert_no_select 'select.status[value_method]'
|
124
140
|
end
|
125
141
|
|
126
|
-
test 'build input_field
|
127
|
-
|
128
|
-
|
129
|
-
f.input_field :name, pattern: '\w+'
|
130
|
-
end
|
131
|
-
|
132
|
-
assert_select 'input[pattern="\w+"]'
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
test 'build input_field without placeholder component use the placeholder string' do
|
137
|
-
swap_wrapper :default, self.custom_wrapper_with_html5_components do
|
138
|
-
with_concat_form_for(@user) do |f|
|
139
|
-
f.input_field :name, placeholder: 'Placeholder'
|
140
|
-
end
|
141
|
-
|
142
|
-
assert_select 'input[placeholder="Placeholder"]'
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
test 'build input_field without maxlength component use the maxlength string' do
|
147
|
-
swap_wrapper :default, self.custom_wrapper_with_html5_components do
|
148
|
-
with_concat_form_for(@user) do |f|
|
149
|
-
f.input_field :name, maxlength: 5
|
150
|
-
end
|
151
|
-
|
152
|
-
assert_select 'input[maxlength="5"]'
|
142
|
+
test 'build input_field does not treat "boolean_style" as an HTML attribute' do
|
143
|
+
with_concat_form_for(@user) do |f|
|
144
|
+
f.input_field :active, boolean_style: :nested
|
153
145
|
end
|
154
|
-
end
|
155
146
|
|
156
|
-
|
157
|
-
swap_wrapper :default, self.custom_wrapper_with_html5_components do
|
158
|
-
with_concat_form_for(@user) do |f|
|
159
|
-
f.input_field :name, readonly: true
|
160
|
-
end
|
161
|
-
|
162
|
-
assert_select 'input[readonly="readonly"]'
|
163
|
-
end
|
147
|
+
assert_no_select 'input.boolean[boolean_style]'
|
164
148
|
end
|
165
149
|
end
|