simple_form 1.2.2 → 1.3.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 (36) hide show
  1. data/README.rdoc +80 -14
  2. data/lib/generators/simple_form/templates/_form.html.erb +1 -11
  3. data/lib/generators/simple_form/templates/simple_form.rb +31 -6
  4. data/lib/simple_form.rb +38 -2
  5. data/lib/simple_form/action_view_extensions/builder.rb +53 -20
  6. data/lib/simple_form/components.rb +6 -5
  7. data/lib/simple_form/components/errors.rb +4 -6
  8. data/lib/simple_form/components/hints.rb +2 -2
  9. data/lib/simple_form/components/labels.rb +3 -5
  10. data/lib/simple_form/components/placeholders.rb +22 -0
  11. data/lib/simple_form/components/wrapper.rb +7 -0
  12. data/lib/simple_form/error_notification.rb +4 -6
  13. data/lib/simple_form/form_builder.rb +61 -55
  14. data/lib/simple_form/has_errors.rb +14 -0
  15. data/lib/simple_form/inputs/base.rb +45 -17
  16. data/lib/simple_form/inputs/block_input.rb +3 -2
  17. data/lib/simple_form/inputs/collection_input.rb +42 -17
  18. data/lib/simple_form/inputs/date_time_input.rb +3 -1
  19. data/lib/simple_form/inputs/hidden_input.rb +11 -2
  20. data/lib/simple_form/inputs/mapping_input.rb +16 -3
  21. data/lib/simple_form/inputs/numeric_input.rb +45 -8
  22. data/lib/simple_form/inputs/string_input.rb +13 -9
  23. data/lib/simple_form/map_type.rb +4 -4
  24. data/lib/simple_form/version.rb +1 -1
  25. data/test/action_view_extensions/builder_test.rb +155 -51
  26. data/test/components/error_test.rb +10 -8
  27. data/test/components/hint_test.rb +4 -8
  28. data/test/components/label_test.rb +22 -9
  29. data/test/components/wrapper_test.rb +16 -7
  30. data/test/error_notification_test.rb +4 -3
  31. data/test/form_builder_test.rb +81 -34
  32. data/test/inputs_test.rb +242 -3
  33. data/test/support/misc_helpers.rb +6 -4
  34. data/test/support/models.rb +26 -3
  35. data/test/test_helper.rb +13 -5
  36. metadata +25 -8
@@ -1,8 +1,9 @@
1
1
  module SimpleForm
2
2
  module Inputs
3
3
  class BlockInput < Base
4
- def initialize(builder, block)
5
- @builder, @block = builder, block
4
+ def initialize(*args, &block)
5
+ super
6
+ @block = block
6
7
  end
7
8
 
8
9
  def input
@@ -13,10 +13,10 @@ module SimpleForm
13
13
  end
14
14
 
15
15
  def input
16
- collection = (options[:collection] || self.class.boolean_collection).to_a
17
- detect_collection_methods(collection, options)
18
- @builder.send(:"collection_#{input_type}", attribute_name, collection, options[:value_method],
19
- options[:label_method], input_options, input_html_options)
16
+ label_method, value_method = detect_collection_methods
17
+
18
+ @builder.send(:"collection_#{input_type}", attribute_name, collection,
19
+ value_method, label_method, input_options, input_html_options)
20
20
  end
21
21
 
22
22
  def input_options
@@ -27,6 +27,10 @@ module SimpleForm
27
27
 
28
28
  protected
29
29
 
30
+ def collection
31
+ @collection ||= (options.delete(:collection) || self.class.boolean_collection).to_a
32
+ end
33
+
30
34
  # Check if :include_blank must be included by default.
31
35
  def skip_include_blank?
32
36
  (options.keys & [:prompt, :include_blank, :default, :selected]).any? ||
@@ -38,21 +42,42 @@ module SimpleForm
38
42
  # on default label and value methods that can be configured through
39
43
  # SimpleForm.collection_label_methods and
40
44
  # SimpleForm.collection_value_methods.
41
- def detect_collection_methods(collection, options)
42
- sample = collection.first || collection.last
43
-
44
- case sample
45
- when Array
46
- label, value = :first, :last
47
- when Integer
48
- label, value = :to_s, :to_i
49
- when String, NilClass
50
- label, value = :to_s, :to_s
45
+ def detect_collection_methods
46
+ label, value = options.delete(:label_method), options.delete(:value_method)
47
+
48
+ unless label && value
49
+ common_method_for = detect_common_display_methods
50
+ label ||= common_method_for[:label]
51
+ value ||= common_method_for[:value]
51
52
  end
52
53
 
53
- options[:label_method] ||= label || SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) }
54
- options[:value_method] ||= value || SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) }
54
+ [label, value]
55
+ end
56
+
57
+ def detect_common_display_methods
58
+ collection_classes = detect_collection_classes
59
+
60
+ if collection_classes.include?(Array)
61
+ { :label => :first, :value => :last }
62
+ elsif collection_includes_basic_objects?(collection_classes)
63
+ { :label => :to_s, :value => :to_s }
64
+ else
65
+ sample = collection.first || collection.last
66
+
67
+ { :label => SimpleForm.collection_label_methods.find { |m| sample.respond_to?(m) },
68
+ :value => SimpleForm.collection_value_methods.find { |m| sample.respond_to?(m) } }
69
+ end
70
+ end
71
+
72
+ def detect_collection_classes
73
+ collection.map { |e| e.class }.uniq
74
+ end
75
+
76
+ def collection_includes_basic_objects?(collection_classes)
77
+ (collection_classes & [
78
+ String, Integer, Fixnum, Bignum, Float, NilClass, Symbol, TrueClass, FalseClass
79
+ ]).any?
55
80
  end
56
81
  end
57
82
  end
58
- end
83
+ end
@@ -5,6 +5,8 @@ module SimpleForm
5
5
  @builder.send(:"#{input_type}_select", attribute_name, input_options, input_html_options)
6
6
  end
7
7
 
8
+ private
9
+
8
10
  def label_target
9
11
  case input_type
10
12
  when :date, :datetime
@@ -15,4 +17,4 @@ module SimpleForm
15
17
  end
16
18
  end
17
19
  end
18
- end
20
+ end
@@ -1,11 +1,20 @@
1
1
  module SimpleForm
2
2
  module Inputs
3
- # Handles hidden input.
4
3
  class HiddenInput < Base
5
4
  def render
6
5
  @builder.hidden_field(attribute_name, input_html_options)
7
6
  end
8
7
  alias :input :render
8
+
9
+ protected
10
+
11
+ def attribute_required?
12
+ false
13
+ end
14
+
15
+ def required_class
16
+ nil
17
+ end
9
18
  end
10
19
  end
11
- end
20
+ end
@@ -12,10 +12,23 @@ module SimpleForm
12
12
  @builder.send(input_method, attribute_name, input_html_options)
13
13
  end
14
14
 
15
+ private
16
+
15
17
  def input_method
16
- method = self.class.mappings[input_type]
17
- raise "Could not find method for #{input_type.inspect}" unless method
18
- method
18
+ self.class.mappings[input_type] or
19
+ raise("Could not find method for #{input_type.inspect}")
20
+ end
21
+
22
+ def has_placeholder?
23
+ (text? || password?) && placeholder_present?
24
+ end
25
+
26
+ def password?
27
+ input_type == :password
28
+ end
29
+
30
+ def text?
31
+ input_type == :text
19
32
  end
20
33
  end
21
34
  end
@@ -2,19 +2,56 @@ module SimpleForm
2
2
  module Inputs
3
3
  class NumericInput < Base
4
4
  def input
5
+ input_html_options[:type] ||= "number"
6
+ input_html_options[:size] ||= SimpleForm.default_input_size
7
+ input_html_options[:step] ||= 1 if integer?
8
+ infer_attributes_from_validations!
5
9
  @builder.text_field(attribute_name, input_html_options)
6
10
  end
7
11
 
8
- def input_html_options
9
- input_options = super
10
- input_options[:type] ||= "number"
11
- input_options[:size] ||= SimpleForm.default_input_size
12
- input_options
13
- end
14
-
15
12
  def input_html_classes
16
13
  super.unshift("numeric")
17
14
  end
15
+
16
+ protected
17
+
18
+ def has_placeholder?
19
+ placeholder_present?
20
+ end
21
+
22
+ def infer_attributes_from_validations!
23
+ return unless has_validators?
24
+
25
+ numeric_validator = find_numericality_validator or return
26
+ validator_options = numeric_validator.options
27
+
28
+ input_html_options[:min] ||= minimum_value(validator_options)
29
+ input_html_options[:max] ||= maximum_value(validator_options)
30
+ end
31
+
32
+ def integer?
33
+ input_type == :integer
34
+ end
35
+
36
+ def minimum_value(validator_options)
37
+ if integer? && validator_options.key?(:greater_than)
38
+ validator_options[:greater_than] + 1
39
+ else
40
+ validator_options[:greater_than_or_equal_to]
41
+ end
42
+ end
43
+
44
+ def maximum_value(validator_options)
45
+ if integer? && validator_options.key?(:less_than)
46
+ validator_options[:less_than] - 1
47
+ else
48
+ validator_options[:less_than_or_equal_to]
49
+ end
50
+ end
51
+
52
+ def find_numericality_validator
53
+ attribute_validators.find { |v| ActiveModel::Validations::NumericalityValidator === v }
54
+ end
18
55
  end
19
56
  end
20
- end
57
+ end
@@ -2,19 +2,15 @@ module SimpleForm
2
2
  module Inputs
3
3
  class StringInput < Base
4
4
  def input
5
- @builder.text_field(attribute_name, input_html_options)
6
- end
5
+ input_html_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
6
+ input_html_options[:maxlength] ||= limit if limit
7
+ input_html_options[:type] ||= input_type unless string?
7
8
 
8
- def input_html_options
9
- input_options = super
10
- input_options[:size] ||= [limit, SimpleForm.default_input_size].compact.min
11
- input_options[:maxlength] ||= limit if limit
12
- input_options[:type] ||= input_type unless input_type == :string
13
- input_options
9
+ @builder.text_field(attribute_name, input_html_options)
14
10
  end
15
11
 
16
12
  def input_html_classes
17
- input_type == :string ? super : super.unshift("string")
13
+ string? ? super : super.unshift("string")
18
14
  end
19
15
 
20
16
  protected
@@ -22,6 +18,14 @@ module SimpleForm
22
18
  def limit
23
19
  column && column.limit
24
20
  end
21
+
22
+ def has_placeholder?
23
+ placeholder_present?
24
+ end
25
+
26
+ def string?
27
+ input_type == :string
28
+ end
25
29
  end
26
30
  end
27
31
  end
@@ -5,9 +5,9 @@ module SimpleForm
5
5
  end
6
6
 
7
7
  def map_type(*types)
8
- options = types.extract_options!
9
- raise ArgumentError, "You need to give :to as option to map_type" unless options[:to]
10
- types.each { |t| mappings[t] = options[:to] }
8
+ map_to = types.extract_options![:to]
9
+ raise ArgumentError, "You need to give :to as option to map_type" unless map_to
10
+ types.each { |t| mappings[t] = map_to }
11
11
  end
12
12
  end
13
- end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module SimpleForm
2
- VERSION = "1.2.2".freeze
2
+ VERSION = "1.3.0".freeze
3
3
  end
@@ -1,29 +1,53 @@
1
1
  require 'test_helper'
2
2
 
3
3
  class BuilderTest < ActionView::TestCase
4
+
5
+ def with_concat_form_for(object, &block)
6
+ concat form_for(object, &block)
7
+ end
8
+
9
+ def with_collection_radio(object, attribute, collection, value_method, text_method, options={}, html_options={})
10
+ with_concat_form_for(object) do |f|
11
+ f.collection_radio attribute, collection, value_method, text_method, options, html_options
12
+ end
13
+ end
14
+
15
+ def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={})
16
+ with_concat_form_for(object) do |f|
17
+ f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options
18
+ end
19
+ end
20
+
4
21
  # COLLECTION RADIO
5
22
  test 'collection radio accepts a collection and generate inputs from value method' do
6
- concat(form_for(@user) do |f|
7
- concat f.collection_radio :active, [true, false], :to_s, :to_s
8
- end)
23
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
9
24
 
10
25
  assert_select 'form input[type=radio][value=true]#user_active_true'
11
26
  assert_select 'form input[type=radio][value=false]#user_active_false'
12
27
  end
13
28
 
14
29
  test 'collection radio accepts a collection and generate inputs from label method' do
15
- concat(form_for(@user) do |f|
16
- concat f.collection_radio :active, [true, false], :to_s, :to_s
17
- end)
30
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
18
31
 
19
32
  assert_select 'form label.collection_radio[for=user_active_true]', 'true'
20
33
  assert_select 'form label.collection_radio[for=user_active_false]', 'false'
21
34
  end
22
35
 
36
+ test 'collection radio handles camelized collection values for labels correctly' do
37
+ with_collection_radio @user, :active, ['Yes', 'No'], :to_s, :to_s
38
+
39
+ assert_select 'form label.collection_radio[for=user_active_yes]', 'Yes'
40
+ assert_select 'form label.collection_radio[for=user_active_no]', 'No'
41
+ end
42
+
43
+ test 'colection radio should sanitize collection values for labels correctly' do
44
+ with_collection_radio @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
45
+ assert_select 'label.collection_radio[for=user_name_099]', '$0.99'
46
+ assert_select 'label.collection_radio[for=user_name_199]', '$1.99'
47
+ end
48
+
23
49
  test 'collection radio accepts checked item' do
24
- concat(form_for(@user) do |f|
25
- concat f.collection_radio :active, [[1, true], [0, false]], :last, :first, :checked => true
26
- end)
50
+ with_collection_radio @user, :active, [[1, true], [0, false]], :last, :first, :checked => true
27
51
 
28
52
  assert_select 'form input[type=radio][value=true][checked=checked]'
29
53
  assert_no_select 'form input[type=radio][value=false][checked=checked]'
@@ -31,9 +55,7 @@ class BuilderTest < ActionView::TestCase
31
55
 
32
56
  test 'collection radio accepts multiple disabled items' do
33
57
  collection = [[1, true], [0, false], [2, 'other']]
34
- concat(form_for(@user) do |f|
35
- concat f.collection_radio :active, collection, :last, :first, :disabled => [true, false]
36
- end)
58
+ with_collection_radio @user, :active, collection, :last, :first, :disabled => [true, false]
37
59
 
38
60
  assert_select 'form input[type=radio][value=true][disabled=disabled]'
39
61
  assert_select 'form input[type=radio][value=false][disabled=disabled]'
@@ -42,29 +64,68 @@ class BuilderTest < ActionView::TestCase
42
64
 
43
65
  test 'collection radio accepts single disable item' do
44
66
  collection = [[1, true], [0, false]]
45
- concat(form_for(@user) do |f|
46
- concat f.collection_radio :active, collection, :last, :first, :disabled => true
47
- end)
67
+ with_collection_radio @user, :active, collection, :last, :first, :disabled => true
48
68
 
49
69
  assert_select 'form input[type=radio][value=true][disabled=disabled]'
50
70
  assert_no_select 'form input[type=radio][value=false][disabled=disabled]'
51
71
  end
52
72
 
53
73
  test 'collection radio accepts html options as input' do
54
- concat(form_for(@user) do |f|
55
- concat f.collection_radio :active, [[1, true], [0, false]], :last, :first, {}, :class => 'radio'
56
- end)
74
+ collection = [[1, true], [0, false]]
75
+ with_collection_radio @user, :active, collection, :last, :first, {}, :class => 'radio'
57
76
 
58
77
  assert_select 'form input[type=radio][value=true].radio#user_active_true'
59
78
  assert_select 'form input[type=radio][value=false].radio#user_active_false'
60
79
  end
61
80
 
81
+ test 'collection radio wraps the collection in the configured collection wrapper tag' do
82
+ swap SimpleForm, :collection_wrapper_tag => :ul do
83
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
84
+
85
+ assert_select 'form ul input[type=radio][value=true]#user_active_true'
86
+ assert_select 'form ul input[type=radio][value=false]#user_active_false'
87
+ end
88
+ end
89
+
90
+ test 'collection radio wraps the collection in the given collection wrapper tag' do
91
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
92
+
93
+ assert_select 'form ul input[type=radio][value=true]#user_active_true'
94
+ assert_select 'form ul input[type=radio][value=false]#user_active_false'
95
+ end
96
+
97
+ test 'collection radio does not wrap the collection by default' do
98
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
99
+
100
+ assert_no_select 'form ul'
101
+ end
102
+
103
+ test 'collection radio wraps each label/radio in the configured item wrapper tag' do
104
+ swap SimpleForm, :item_wrapper_tag => :li do
105
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
106
+
107
+ assert_select 'form li input[type=radio][value=true]#user_active_true'
108
+ assert_select 'form li input[type=radio][value=false]#user_active_false'
109
+ end
110
+ end
111
+
112
+ test 'collection radio wraps each label/radio in the given item wrapper tag' do
113
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
114
+
115
+ assert_select 'form li input[type=radio][value=true]#user_active_true'
116
+ assert_select 'form li input[type=radio][value=false]#user_active_false'
117
+ end
118
+
119
+ test 'collection radio does not wrap items by default' do
120
+ with_collection_radio @user, :active, [true, false], :to_s, :to_s
121
+
122
+ assert_no_select 'form li'
123
+ end
124
+
62
125
  # COLLECTION CHECK BOX
63
126
  test 'collection check box accepts a collection and generate a serie of checkboxes for value method' do
64
127
  collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
65
- concat(form_for(@user) do |f|
66
- concat f.collection_check_boxes :tag_ids, collection, :id, :name
67
- end)
128
+ with_collection_check_boxes @user, :tag_ids, collection, :id, :name
68
129
 
69
130
  assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]"
70
131
  assert_select 'form input#user_tag_ids_1[type=checkbox][value=1]'
@@ -73,19 +134,28 @@ class BuilderTest < ActionView::TestCase
73
134
 
74
135
  test 'collection check box accepts a collection and generate a serie of checkboxes with labels for label method' do
75
136
  collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
76
- concat(form_for(@user) do |f|
77
- concat f.collection_check_boxes :tag_ids, collection, :id, :name
78
- end)
137
+ with_collection_check_boxes @user, :tag_ids, collection, :id, :name
79
138
 
80
139
  assert_select 'form label.collection_check_boxes[for=user_tag_ids_1]', 'Tag 1'
81
140
  assert_select 'form label.collection_check_boxes[for=user_tag_ids_2]', 'Tag 2'
82
141
  end
83
142
 
143
+ test 'collection check box handles camelized collection values for labels correctly' do
144
+ with_collection_check_boxes @user, :active, ['Yes', 'No'], :to_s, :to_s
145
+
146
+ assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
147
+ assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
148
+ end
149
+
150
+ test 'colection check box should sanitize collection values for labels correctly' do
151
+ with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
152
+ assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
153
+ assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
154
+ end
155
+
84
156
  test 'collection check box accepts selected values as :checked option' do
85
157
  collection = (1..3).map{|i| [i, "Tag #{i}"] }
86
- concat(form_for(@user) do |f|
87
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, :checked => [1, 3]
88
- end)
158
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => [1, 3]
89
159
 
90
160
  assert_select 'form input[type=checkbox][value=1][checked=checked]'
91
161
  assert_select 'form input[type=checkbox][value=3][checked=checked]'
@@ -94,9 +164,7 @@ class BuilderTest < ActionView::TestCase
94
164
 
95
165
  test 'collection check box accepts a single checked value' do
96
166
  collection = (1..3).map{|i| [i, "Tag #{i}"] }
97
- concat(form_for(@user) do |f|
98
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, :checked => 3
99
- end)
167
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => 3
100
168
 
101
169
  assert_select 'form input[type=checkbox][value=3][checked=checked]'
102
170
  assert_no_select 'form input[type=checkbox][value=1][checked=checked]'
@@ -105,9 +173,7 @@ class BuilderTest < ActionView::TestCase
105
173
 
106
174
  test 'collection check box accepts multiple disabled items' do
107
175
  collection = (1..3).map{|i| [i, "Tag #{i}"] }
108
- concat(form_for(@user) do |f|
109
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => [1, 3]
110
- end)
176
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => [1, 3]
111
177
 
112
178
  assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
113
179
  assert_select 'form input[type=checkbox][value=3][disabled=disabled]'
@@ -116,9 +182,7 @@ class BuilderTest < ActionView::TestCase
116
182
 
117
183
  test 'collection check box accepts single disable item' do
118
184
  collection = (1..3).map{|i| [i, "Tag #{i}"] }
119
- concat(form_for(@user) do |f|
120
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => 1
121
- end)
185
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => 1
122
186
 
123
187
  assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
124
188
  assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
@@ -127,9 +191,7 @@ class BuilderTest < ActionView::TestCase
127
191
 
128
192
  test 'collection check box accepts a proc to disabled items' do
129
193
  collection = (1..3).map{|i| [i, "Tag #{i}"] }
130
- concat(form_for(@user) do |f|
131
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
132
- end)
194
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
133
195
 
134
196
  assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
135
197
  assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
@@ -138,9 +200,7 @@ class BuilderTest < ActionView::TestCase
138
200
 
139
201
  test 'collection check box accepts html options' do
140
202
  collection = [[1, 'Tag 1'], [2, 'Tag 2']]
141
- concat(form_for(@user) do |f|
142
- concat f.collection_check_boxes :tag_ids, collection, :first, :last, {}, :class => 'check'
143
- end)
203
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, {}, :class => 'check'
144
204
 
145
205
  assert_select 'form input.check[type=checkbox][value=1]'
146
206
  assert_select 'form input.check[type=checkbox][value=2]'
@@ -148,11 +208,11 @@ class BuilderTest < ActionView::TestCase
148
208
 
149
209
  test 'collection check box with fields for' do
150
210
  collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
151
- concat(form_for(@user) do |f|
152
- concat(f.fields_for(:post) do |p|
153
- concat p.collection_check_boxes :tag_ids, collection, :id, :name
154
- end)
155
- end)
211
+ with_concat_form_for(@user) do |f|
212
+ f.fields_for(:post) do |p|
213
+ p.collection_check_boxes :tag_ids, collection, :id, :name
214
+ end
215
+ end
156
216
 
157
217
  assert_select 'form input#user_post_tag_ids_1[type=checkbox][value=1]'
158
218
  assert_select 'form input#user_post_tag_ids_2[type=checkbox][value=2]'
@@ -161,12 +221,56 @@ class BuilderTest < ActionView::TestCase
161
221
  assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'
162
222
  end
163
223
 
224
+ test 'collection check box wraps the collection in the configured collection wrapper tag' do
225
+ swap SimpleForm, :collection_wrapper_tag => :ul do
226
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
227
+
228
+ assert_select 'form ul input[type=checkbox][value=true]#user_active_true'
229
+ assert_select 'form ul input[type=checkbox][value=false]#user_active_false'
230
+ end
231
+ end
232
+
233
+ test 'collection check box wraps the collection in the given collection wrapper tag' do
234
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
235
+
236
+ assert_select 'form ul input[type=checkbox][value=true]#user_active_true'
237
+ assert_select 'form ul input[type=checkbox][value=false]#user_active_false'
238
+ end
239
+
240
+ test 'collection check box does not wrap the collection by default' do
241
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
242
+
243
+ assert_no_select 'form ul'
244
+ end
245
+
246
+ test 'collection check box wraps each label/radio in the configured item wrapper tag' do
247
+ swap SimpleForm, :item_wrapper_tag => :li do
248
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
249
+
250
+ assert_select 'form li input[type=checkbox][value=true]#user_active_true'
251
+ assert_select 'form li input[type=checkbox][value=false]#user_active_false'
252
+ end
253
+ end
254
+
255
+ test 'collection check box wraps each label/radio in the given item wrapper tag' do
256
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
257
+
258
+ assert_select 'form li input[type=checkbox][value=true]#user_active_true'
259
+ assert_select 'form li input[type=checkbox][value=false]#user_active_false'
260
+ end
261
+
262
+ test 'collection check box does not wrap items by default' do
263
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
264
+
265
+ assert_no_select 'form li'
266
+ end
267
+
164
268
  # SIMPLE FIELDS
165
269
  test 'simple fields for is available and yields an instance of FormBuilder' do
166
- concat(form_for(@user) do |f|
167
- concat(f.simple_fields_for(:posts) do |posts_form|
270
+ with_concat_form_for(@user) do |f|
271
+ f.simple_fields_for(:posts) do |posts_form|
168
272
  assert posts_form.instance_of?(SimpleForm::FormBuilder)
169
- end)
170
- end)
273
+ end
274
+ end
171
275
  end
172
276
  end