simple_form 2.0.0.rc → 2.0.0

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.

Files changed (45) hide show
  1. data/CHANGELOG.md +16 -6
  2. data/README.md +18 -19
  3. data/lib/generators/simple_form/install_generator.rb +1 -1
  4. data/lib/generators/simple_form/templates/_form.html.erb +2 -2
  5. data/lib/generators/simple_form/templates/_form.html.haml +2 -2
  6. data/lib/generators/simple_form/templates/_form.html.slim +4 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb.tt +23 -20
  8. data/lib/simple_form.rb +13 -9
  9. data/lib/simple_form/action_view_extensions/builder.rb +64 -22
  10. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
  11. data/lib/simple_form/components/errors.rb +1 -1
  12. data/lib/simple_form/components/labels.rb +8 -2
  13. data/lib/simple_form/error_notification.rb +1 -2
  14. data/lib/simple_form/form_builder.rb +19 -6
  15. data/lib/simple_form/helpers/required.rb +5 -3
  16. data/lib/simple_form/inputs/base.rb +4 -1
  17. data/lib/simple_form/inputs/boolean_input.rb +4 -1
  18. data/lib/simple_form/inputs/collection_check_boxes_input.rb +2 -2
  19. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +3 -5
  20. data/lib/simple_form/inputs/date_time_input.rb +8 -4
  21. data/lib/simple_form/inputs/grouped_collection_select_input.rb +1 -1
  22. data/lib/simple_form/version.rb +1 -1
  23. data/lib/simple_form/wrappers/builder.rb +46 -18
  24. data/lib/simple_form/wrappers/many.rb +1 -0
  25. data/lib/simple_form/wrappers/root.rb +1 -1
  26. data/test/action_view_extensions/builder_test.rb +100 -12
  27. data/test/action_view_extensions/form_helper_test.rb +13 -13
  28. data/test/components/label_test.rb +24 -0
  29. data/test/form_builder/association_test.rb +10 -0
  30. data/test/form_builder/button_test.rb +19 -0
  31. data/test/form_builder/error_notification_test.rb +16 -0
  32. data/test/form_builder/error_test.rb +21 -1
  33. data/test/form_builder/general_test.rb +8 -0
  34. data/test/form_builder/hint_test.rb +10 -2
  35. data/test/form_builder/input_field_test.rb +13 -1
  36. data/test/form_builder/label_test.rb +14 -0
  37. data/test/form_builder/wrapper_test.rb +10 -1
  38. data/test/inputs/boolean_input_test.rb +10 -0
  39. data/test/inputs/datetime_input_test.rb +20 -6
  40. data/test/inputs/grouped_collection_select_input_test.rb +9 -0
  41. data/test/inputs/priority_input_test.rb +1 -1
  42. data/test/inputs/string_input_test.rb +1 -1
  43. data/test/support/misc_helpers.rb +11 -12
  44. data/test/test_helper.rb +6 -4
  45. metadata +13 -10
@@ -1,6 +1,6 @@
1
1
  module SimpleForm
2
2
  module ActionViewExtensions
3
- # This module creates simple form wrappers around default form_for and fields_for.
3
+ # This module creates SimpleForm wrappers around default form_for and fields_for.
4
4
  #
5
5
  # Example:
6
6
  #
@@ -12,7 +12,7 @@ module SimpleForm
12
12
  protected
13
13
 
14
14
  def error_text
15
- "#{options[:error_prefix]} #{errors.send(error_method)}".lstrip
15
+ "#{options[:error_prefix]} #{errors.send(error_method)}".lstrip.html_safe
16
16
  end
17
17
 
18
18
  def error_method
@@ -38,8 +38,14 @@ module SimpleForm
38
38
  end
39
39
 
40
40
  def label_html_options
41
- label_options = html_options_for(:label, [input_type, required_class, SimpleForm.label_class].compact)
42
- label_options[:for] = options[:input_html][:id] if options.key?(:input_html) && options[:input_html].key?(:id)
41
+ label_html_classes = SimpleForm.additional_classes_for(:label) {
42
+ [input_type, required_class, SimpleForm.label_class].compact
43
+ }
44
+
45
+ label_options = html_options_for(:label, label_html_classes)
46
+ if options.key?(:input_html) && options[:input_html].key?(:id)
47
+ label_options[:for] = options[:input_html][:id]
48
+ end
43
49
  label_options
44
50
  end
45
51
 
@@ -25,7 +25,7 @@ module SimpleForm
25
25
  end
26
26
 
27
27
  def error_message
28
- @message || translate_error_notification
28
+ (@message || translate_error_notification).html_safe
29
29
  end
30
30
 
31
31
  def error_notification_tag
@@ -34,7 +34,6 @@ module SimpleForm
34
34
 
35
35
  def html_options
36
36
  @options[:class] = "#{SimpleForm.error_notification_class} #{@options[:class]}".strip
37
- @options[:id] = SimpleForm.error_notification_id if SimpleForm.error_notification_id
38
37
  @options
39
38
  end
40
39
 
@@ -131,6 +131,7 @@ module SimpleForm
131
131
  # name="user[name]" size="100" type="text" value="Carlos" />
132
132
  #
133
133
  def input_field(attribute_name, options={})
134
+ options = options.dup
134
135
  options[:input_html] = options.except(:as, :collection, :label_method, :value_method)
135
136
  SimpleForm::Wrappers::Root.new([:input], :wrapper => false).render find_input(attribute_name, options)
136
137
  end
@@ -162,6 +163,8 @@ module SimpleForm
162
163
  # From the options above, only :collection can also be supplied.
163
164
  #
164
165
  def association(association, options={}, &block)
166
+ options = options.dup
167
+
165
168
  return simple_fields_for(*[association,
166
169
  options.delete(:collection), options].compact, &block) if block_given?
167
170
 
@@ -203,10 +206,14 @@ module SimpleForm
203
206
  # f.button :submit
204
207
  # end
205
208
  #
206
- # It just acts as a proxy to method name given.
209
+ # It just acts as a proxy to method name given. We also alias original Rails
210
+ # button implementation (3.2 forward (to delegate to the original when
211
+ # calling `f.button :button`.
207
212
  #
213
+ # TODO: remove if condition when supporting only Rails 3.2 forward.
214
+ alias_method :button_button, :button if method_defined?(:button)
208
215
  def button(type, *args, &block)
209
- options = args.extract_options!
216
+ options = args.extract_options!.dup
210
217
  options[:class] = [SimpleForm.button_class, options[:class]].compact
211
218
  args << options
212
219
  if respond_to?("#{type}_button")
@@ -225,6 +232,8 @@ module SimpleForm
225
232
  # f.error :name, :id => "cool_error"
226
233
  #
227
234
  def error(attribute_name, options={})
235
+ options = options.dup
236
+
228
237
  options[:error_html] = options.except(:error_tag, :error_prefix, :error_method)
229
238
  column = find_attribute_column(attribute_name)
230
239
  input_type = default_input_type(attribute_name, column, options)
@@ -240,6 +249,8 @@ module SimpleForm
240
249
  # f.full_error :token #=> <span class="error">Token is invalid</span>
241
250
  #
242
251
  def full_error(attribute_name, options={})
252
+ options = options.dup
253
+
243
254
  options[:error_prefix] ||= if object.class.respond_to?(:human_attribute_name)
244
255
  object.class.human_attribute_name(attribute_name.to_s)
245
256
  else
@@ -260,6 +271,8 @@ module SimpleForm
260
271
  # f.hint "Don't forget to accept this"
261
272
  #
262
273
  def hint(attribute_name, options={})
274
+ options = options.dup
275
+
263
276
  options[:hint_html] = options.except(:hint_tag, :hint)
264
277
  if attribute_name.is_a?(String)
265
278
  options[:hint] = attribute_name
@@ -288,10 +301,10 @@ module SimpleForm
288
301
  #
289
302
  def label(attribute_name, *args)
290
303
  return super if args.first.is_a?(String) || block_given?
291
- options = args.extract_options!
292
- options[:label_html] = options.dup
293
- options[:label] = options.delete(:label)
294
- options[:required] = options.delete(:required)
304
+
305
+ options = args.extract_options!.dup
306
+ options[:label_html] = options.except(:label, :required)
307
+
295
308
  column = find_attribute_column(attribute_name)
296
309
  input_type = default_input_type(attribute_name, column, options)
297
310
  SimpleForm::Inputs::Base.new(self, attribute_name, column, input_type, options).label
@@ -11,14 +11,16 @@ module SimpleForm
11
11
  if !options[:required].nil?
12
12
  options[:required]
13
13
  elsif has_validators?
14
- (attribute_validators + reflection_validators).any? do |v|
15
- v.kind == :presence && valid_validator?(v)
16
- end
14
+ required_by_validators?
17
15
  else
18
16
  required_by_default?
19
17
  end
20
18
  end
21
19
 
20
+ def required_by_validators?
21
+ (attribute_validators + reflection_validators).any? { |v| v.kind == :presence && valid_validator?(v) }
22
+ end
23
+
22
24
  def required_by_default?
23
25
  SimpleForm.required_by_default
24
26
  end
@@ -59,7 +59,10 @@ module SimpleForm
59
59
  # Notice that html_options_for receives a reference to input_html_classes.
60
60
  # This means that classes added dynamically to input_html_classes will
61
61
  # still propagate to input_html_options.
62
- @html_classes = [input_type, required_class, readonly_class, disabled_class].compact
62
+ @html_classes = SimpleForm.additional_classes_for(:input) {
63
+ [input_type, required_class, readonly_class, disabled_class].compact
64
+ }
65
+
63
66
  @input_html_classes = @html_classes.dup
64
67
  @input_html_options = html_options_for(:input, input_html_classes).tap do |o|
65
68
  o[:readonly] = true if has_readonly?
@@ -16,8 +16,11 @@ module SimpleForm
16
16
  if options[:label] == false
17
17
  input
18
18
  elsif nested_boolean_style?
19
+ html_options = label_html_options.dup
20
+ html_options[:class].push(:checkbox)
21
+
19
22
  build_hidden_field_for_checkbox +
20
- @builder.label(label_target, label_html_options) {
23
+ @builder.label(label_target, html_options) {
21
24
  build_check_box_without_hidden_field + label_text
22
25
  }
23
26
  else
@@ -9,8 +9,8 @@ module SimpleForm
9
9
  false
10
10
  end
11
11
 
12
- def build_nested_boolean_style_item_tag(text, value, html_options)
13
- @builder.check_box(attribute_name, html_options, value, nil) + text
12
+ def build_nested_boolean_style_item_tag(collection_builder)
13
+ collection_builder.check_box + collection_builder.text
14
14
  end
15
15
 
16
16
  def item_wrapper_class
@@ -45,13 +45,11 @@ module SimpleForm
45
45
  def collection_block_for_nested_boolean_style
46
46
  return unless nested_boolean_style?
47
47
 
48
- proc do |label_for, text, value, html_options|
49
- build_nested_boolean_style_item_tag(text, value, html_options)
50
- end
48
+ proc { |builder| build_nested_boolean_style_item_tag(builder) }
51
49
  end
52
50
 
53
- def build_nested_boolean_style_item_tag(text, value, html_options)
54
- @builder.radio_button(attribute_name, value, html_options) + text
51
+ def build_nested_boolean_style_item_tag(collection_builder)
52
+ collection_builder.radio_button + collection_builder.text
55
53
  end
56
54
 
57
55
  def item_wrapper_class
@@ -12,12 +12,16 @@ module SimpleForm
12
12
  private
13
13
 
14
14
  def label_target
15
- case input_type
15
+ position = case input_type
16
16
  when :date, :datetime
17
- "#{attribute_name}_1i"
18
- when :time
19
- "#{attribute_name}_4i"
17
+ date_order = input_options[:order] || I18n.t('date.order')
18
+ date_order.first
19
+ else
20
+ :hour
20
21
  end
22
+
23
+ position = ActionView::Helpers::DateTimeSelector::POSITION[position]
24
+ "#{attribute_name}_#{position}i"
21
25
  end
22
26
  end
23
27
  end
@@ -19,7 +19,7 @@ module SimpleForm
19
19
 
20
20
  # Sample collection
21
21
  def collection
22
- @collection ||= grouped_collection.first.try(:send, group_method)
22
+ @collection ||= grouped_collection.first.try(:send, group_method) || []
23
23
  end
24
24
 
25
25
  def group_method
@@ -1,3 +1,3 @@
1
1
  module SimpleForm
2
- VERSION = "2.0.0.rc".freeze
2
+ VERSION = "2.0.0".freeze
3
3
  end
@@ -1,17 +1,21 @@
1
1
  module SimpleForm
2
2
  module Wrappers
3
3
  # Provides the builder syntax for components. The builder provides
4
- # only one method (called `use`) and it allows the following invocations:
4
+ # three methods `use`, `optional` and `wrapper` and they allow the following invocations:
5
5
  #
6
6
  # config.wrappers do |b|
7
7
  # # Use a single component
8
- # b.use :placeholder
8
+ # b.use :html5
9
+ #
10
+ # # Use the component, but do not automatically lookup. It will only be triggered when
11
+ # # :placeholder is explicitly set.
12
+ # b.optional :placeholder
9
13
  #
10
14
  # # Use a component with specific wrapper options
11
- # b.use :error, :tag => "span", :class => "error"
15
+ # b.use :error, :wrap_with => { :tag => "span", :class => "error" }
12
16
  #
13
17
  # # Use a set of components by wrapping them in a tag+class.
14
- # b.use :tag => "div", :class => "another" do |ba|
18
+ # b.wrapper :tag => "div", :class => "another" do |ba|
15
19
  # ba.use :label
16
20
  # ba.use :input
17
21
  # end
@@ -19,7 +23,7 @@ module SimpleForm
19
23
  # # Use a set of components by wrapping them in a tag+class.
20
24
  # # This wrapper is identified by :label_input, which means it can
21
25
  # # be turned off on demand with `f.input :name, :label_input => false`
22
- # b.use :label_input, :tag => "div", :class => "another" do |ba|
26
+ # b.wrapper :label_input, :tag => "div", :class => "another" do |ba|
23
27
  # ba.use :label
24
28
  # ba.use :input
25
29
  # end
@@ -42,21 +46,43 @@ module SimpleForm
42
46
  end
43
47
 
44
48
  def use(name, options=nil, &block)
45
- add(name, options, &block)
49
+ if block_given?
50
+ ActiveSupport::Deprecation.warn "Passing a block to use is deprecated. " \
51
+ "Please use wrapper instead of use."
52
+ return wrapper(name, options, &block)
53
+ end
54
+
55
+ if options && options.keys != [:wrap_with]
56
+ ActiveSupport::Deprecation.warn "Passing :tag, :class and others to use is deprecated. " \
57
+ "Please invoke b.use #{name.inspect}, :wrap_with => #{options.inspect} instead."
58
+ options = { :wrap_with => options }
59
+ end
60
+
61
+ if options && wrapper = options[:wrap_with]
62
+ @components << Single.new(name, wrapper)
63
+ else
64
+ @components << name
65
+ end
46
66
  end
47
67
 
48
68
  def optional(name, options=nil, &block)
49
- @options[name] = false
50
- add(name, options, &block)
51
- end
69
+ if block_given?
70
+ ActiveSupport::Deprecation.warn "Passing a block to optional is deprecated. " \
71
+ "Please use wrapper instead of optional."
72
+ return wrapper(name, options, &block)
73
+ end
52
74
 
53
- def to_a
54
- @components
55
- end
75
+ if options && options.keys != [:wrap_with]
76
+ ActiveSupport::Deprecation.warn "Passing :tag, :class and others to optional is deprecated. " \
77
+ "Please invoke b.optional #{name.inspect}, :wrap_with => #{options.inspect} instead."
78
+ options = { :wrap_with => options }
79
+ end
56
80
 
57
- private
81
+ @options[name] = false
82
+ use(name, options, &block)
83
+ end
58
84
 
59
- def add(name, options)
85
+ def wrapper(name, options=nil)
60
86
  if block_given?
61
87
  name, options = nil, name if name.is_a?(Hash)
62
88
  builder = self.class.new(@options)
@@ -64,12 +90,14 @@ module SimpleForm
64
90
  options[:tag] = :div if options[:tag].nil?
65
91
  yield builder
66
92
  @components << Many.new(name, builder.to_a, options)
67
- elsif options
68
- @components << Single.new(name, options)
69
93
  else
70
- @components << name
94
+ raise ArgumentError, "A block is required as argument to wrapper"
71
95
  end
72
96
  end
97
+
98
+ def to_a
99
+ @components
100
+ end
73
101
  end
74
102
  end
75
- end
103
+ end
@@ -16,6 +16,7 @@ module SimpleForm
16
16
  @namespace = namespace
17
17
  @components = components
18
18
  @defaults = defaults
19
+ @defaults[:tag] = :div unless @defaults.key?(:tag)
19
20
  @defaults[:class] = Array.wrap(@defaults[:class])
20
21
  end
21
22
 
@@ -24,7 +24,7 @@ module SimpleForm
24
24
 
25
25
  def html_classes(input, options)
26
26
  css = options[:wrapper_class] ? Array.wrap(options[:wrapper_class]) : @defaults[:class]
27
- css += input.html_classes
27
+ css += SimpleForm.additional_classes_for(:wrapper) { input.html_classes }
28
28
  css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
29
29
  css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
30
30
  css
@@ -42,7 +42,7 @@ class BuilderTest < ActionView::TestCase
42
42
  assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
43
43
  end
44
44
 
45
- test 'colection radio should sanitize collection values for labels correctly' do
45
+ test 'collection radio should sanitize collection values for labels correctly' do
46
46
  with_collection_radio_buttons @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
47
47
  assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
48
48
  assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
@@ -174,13 +174,57 @@ class BuilderTest < ActionView::TestCase
174
174
  assert_no_select 'form label input'
175
175
  end
176
176
 
177
- test 'collection radio accepts a block to render the radio and label as required' do
178
- with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s do |label_for, text, value, html_options|
179
- label(:user, label_for, text) { radio_button(:user, :active, value, html_options) }
177
+ test 'collection radio accepts a block to render the label as radio button wrapper' do
178
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
179
+ b.label { b.radio_button }
180
180
  end
181
181
 
182
- assert_select 'form label[for=user_active_true] > input#user_active_true[type=radio]'
183
- assert_select 'form label[for=user_active_false] > input#user_active_false[type=radio]'
182
+ assert_select 'label[for=user_active_true] > input#user_active_true[type=radio]'
183
+ assert_select 'label[for=user_active_false] > input#user_active_false[type=radio]'
184
+ end
185
+
186
+ test 'collection radio accepts a block to change the order of label and radio button' do
187
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
188
+ b.label + b.radio_button
189
+ end
190
+
191
+ assert_select 'label[for=user_active_true] + input#user_active_true[type=radio]'
192
+ assert_select 'label[for=user_active_false] + input#user_active_false[type=radio]'
193
+ end
194
+
195
+ test 'collection radio with block helpers accept extra html options' do
196
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
197
+ b.label(:class => "radio_button") + b.radio_button(:class => "radio_button")
198
+ end
199
+
200
+ assert_select 'label.radio_button[for=user_active_true] + input#user_active_true.radio_button[type=radio]'
201
+ assert_select 'label.radio_button[for=user_active_false] + input#user_active_false.radio_button[type=radio]'
202
+ end
203
+
204
+ test 'collection radio with block helpers allows access to current text and value' do
205
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
206
+ b.label(:"data-value" => b.value) { b.radio_button + b.text }
207
+ end
208
+
209
+ assert_select 'label[for=user_active_true][data-value=true]', 'true' do
210
+ assert_select 'input#user_active_true[type=radio]'
211
+ end
212
+ assert_select 'label[for=user_active_false][data-value=false]', 'false' do
213
+ assert_select 'input#user_active_false[type=radio]'
214
+ end
215
+ end
216
+
217
+ test 'collection radio with block helpers allows access to the current object item in the collection to access extra properties' do
218
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
219
+ b.label(:class => b.object) { b.radio_button + b.text }
220
+ end
221
+
222
+ assert_select 'label.true[for=user_active_true]', 'true' do
223
+ assert_select 'input#user_active_true[type=radio]'
224
+ end
225
+ assert_select 'label.false[for=user_active_false]', 'false' do
226
+ assert_select 'input#user_active_false[type=radio]'
227
+ end
184
228
  end
185
229
 
186
230
  test 'collection_radio helper is deprecated in favor of collection_radio_buttons' do
@@ -226,7 +270,7 @@ class BuilderTest < ActionView::TestCase
226
270
  assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
227
271
  end
228
272
 
229
- test 'colection check box should sanitize collection values for labels correctly' do
273
+ test 'collection check box should sanitize collection values for labels correctly' do
230
274
  with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
231
275
  assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
232
276
  assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
@@ -403,13 +447,57 @@ class BuilderTest < ActionView::TestCase
403
447
  assert_no_select 'form label input'
404
448
  end
405
449
 
406
- test 'collection check box accepts a block to render the radio and label as required' do
407
- with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s do |label_for, text, value, html_options|
408
- label(:user, label_for, text) { check_box(:user, :active, html_options, value) }
450
+ test 'collection check boxes accepts a block to render the label as check box wrapper' do
451
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
452
+ b.label { b.check_box }
409
453
  end
410
454
 
411
- assert_select 'form label[for=user_active_true] > input#user_active_true[type=checkbox]'
412
- assert_select 'form label[for=user_active_false] > input#user_active_false[type=checkbox]'
455
+ assert_select 'label[for=user_active_true] > input#user_active_true[type=checkbox]'
456
+ assert_select 'label[for=user_active_false] > input#user_active_false[type=checkbox]'
457
+ end
458
+
459
+ test 'collection check boxes accepts a block to change the order of label and check box' do
460
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
461
+ b.label + b.check_box
462
+ end
463
+
464
+ assert_select 'label[for=user_active_true] + input#user_active_true[type=checkbox]'
465
+ assert_select 'label[for=user_active_false] + input#user_active_false[type=checkbox]'
466
+ end
467
+
468
+ test 'collection check boxes with block helpers accept extra html options' do
469
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
470
+ b.label(:class => "check_box") + b.check_box(:class => "check_box")
471
+ end
472
+
473
+ assert_select 'label.check_box[for=user_active_true] + input#user_active_true.check_box[type=checkbox]'
474
+ assert_select 'label.check_box[for=user_active_false] + input#user_active_false.check_box[type=checkbox]'
475
+ end
476
+
477
+ test 'collection check boxes with block helpers allows access to current text and value' do
478
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
479
+ b.label(:"data-value" => b.value) { b.check_box + b.text }
480
+ end
481
+
482
+ assert_select 'label[for=user_active_true][data-value=true]', 'true' do
483
+ assert_select 'input#user_active_true[type=checkbox]'
484
+ end
485
+ assert_select 'label[for=user_active_false][data-value=false]', 'false' do
486
+ assert_select 'input#user_active_false[type=checkbox]'
487
+ end
488
+ end
489
+
490
+ test 'collection check boxes with block helpers allows access to the current object item in the collection to access extra properties' do
491
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
492
+ b.label(:class => b.object) { b.check_box + b.text }
493
+ end
494
+
495
+ assert_select 'label.true[for=user_active_true]', 'true' do
496
+ assert_select 'input#user_active_true[type=checkbox]'
497
+ end
498
+ assert_select 'label.false[for=user_active_false]', 'false' do
499
+ assert_select 'input#user_active_false[type=checkbox]'
500
+ end
413
501
  end
414
502
 
415
503
  # SIMPLE FIELDS