simple_form_with_client_validation 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. data/CHANGELOG.md +6 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +783 -0
  4. data/lib/generators/simple_form_with_client_validation/USAGE +3 -0
  5. data/lib/generators/simple_form_with_client_validation/install_generator.rb +32 -0
  6. data/lib/generators/simple_form_with_client_validation/templates/README +12 -0
  7. data/lib/generators/simple_form_with_client_validation/templates/_form.html.erb +13 -0
  8. data/lib/generators/simple_form_with_client_validation/templates/_form.html.haml +10 -0
  9. data/lib/generators/simple_form_with_client_validation/templates/_form.html.slim +10 -0
  10. data/lib/generators/simple_form_with_client_validation/templates/config/initializers/simple_form.rb.tt +179 -0
  11. data/lib/generators/simple_form_with_client_validation/templates/config/locales/simple_form.en.yml +26 -0
  12. data/lib/simple_form_with_client_validation/action_view_extensions/builder.rb +331 -0
  13. data/lib/simple_form_with_client_validation/action_view_extensions/form_helper.rb +74 -0
  14. data/lib/simple_form_with_client_validation/components/errors.rb +35 -0
  15. data/lib/simple_form_with_client_validation/components/hints.rb +18 -0
  16. data/lib/simple_form_with_client_validation/components/html5.rb +26 -0
  17. data/lib/simple_form_with_client_validation/components/label_input.rb +15 -0
  18. data/lib/simple_form_with_client_validation/components/labels.rb +79 -0
  19. data/lib/simple_form_with_client_validation/components/maxlength.rb +41 -0
  20. data/lib/simple_form_with_client_validation/components/min_max.rb +50 -0
  21. data/lib/simple_form_with_client_validation/components/minlength.rb +41 -0
  22. data/lib/simple_form_with_client_validation/components/pattern.rb +34 -0
  23. data/lib/simple_form_with_client_validation/components/placeholders.rb +16 -0
  24. data/lib/simple_form_with_client_validation/components/readonly.rb +22 -0
  25. data/lib/simple_form_with_client_validation/components.rb +21 -0
  26. data/lib/simple_form_with_client_validation/core_ext/hash.rb +16 -0
  27. data/lib/simple_form_with_client_validation/error_notification.rb +48 -0
  28. data/lib/simple_form_with_client_validation/form_builder.rb +484 -0
  29. data/lib/simple_form_with_client_validation/helpers/autofocus.rb +11 -0
  30. data/lib/simple_form_with_client_validation/helpers/disabled.rb +15 -0
  31. data/lib/simple_form_with_client_validation/helpers/readonly.rb +15 -0
  32. data/lib/simple_form_with_client_validation/helpers/required.rb +35 -0
  33. data/lib/simple_form_with_client_validation/helpers/validators.rb +44 -0
  34. data/lib/simple_form_with_client_validation/helpers.rb +12 -0
  35. data/lib/simple_form_with_client_validation/i18n_cache.rb +22 -0
  36. data/lib/simple_form_with_client_validation/inputs/base.rb +162 -0
  37. data/lib/simple_form_with_client_validation/inputs/block_input.rb +14 -0
  38. data/lib/simple_form_with_client_validation/inputs/boolean_input.rb +64 -0
  39. data/lib/simple_form_with_client_validation/inputs/collection_check_boxes_input.rb +21 -0
  40. data/lib/simple_form_with_client_validation/inputs/collection_input.rb +101 -0
  41. data/lib/simple_form_with_client_validation/inputs/collection_radio_buttons_input.rb +63 -0
  42. data/lib/simple_form_with_client_validation/inputs/collection_select_input.rb +14 -0
  43. data/lib/simple_form_with_client_validation/inputs/date_time_input.rb +28 -0
  44. data/lib/simple_form_with_client_validation/inputs/file_input.rb +9 -0
  45. data/lib/simple_form_with_client_validation/inputs/grouped_collection_select_input.rb +41 -0
  46. data/lib/simple_form_with_client_validation/inputs/hidden_input.rb +17 -0
  47. data/lib/simple_form_with_client_validation/inputs/numeric_input.rb +24 -0
  48. data/lib/simple_form_with_client_validation/inputs/password_input.rb +12 -0
  49. data/lib/simple_form_with_client_validation/inputs/priority_input.rb +24 -0
  50. data/lib/simple_form_with_client_validation/inputs/range_input.rb +14 -0
  51. data/lib/simple_form_with_client_validation/inputs/string_input.rb +23 -0
  52. data/lib/simple_form_with_client_validation/inputs/text_input.rb +11 -0
  53. data/lib/simple_form_with_client_validation/inputs.rb +21 -0
  54. data/lib/simple_form_with_client_validation/map_type.rb +16 -0
  55. data/lib/simple_form_with_client_validation/version.rb +3 -0
  56. data/lib/simple_form_with_client_validation/wrappers/builder.rb +115 -0
  57. data/lib/simple_form_with_client_validation/wrappers/many.rb +78 -0
  58. data/lib/simple_form_with_client_validation/wrappers/root.rb +34 -0
  59. data/lib/simple_form_with_client_validation/wrappers/single.rb +18 -0
  60. data/lib/simple_form_with_client_validation/wrappers.rb +8 -0
  61. data/lib/simple_form_with_client_validation.rb +218 -0
  62. data/test/action_view_extensions/builder_test.rb +577 -0
  63. data/test/action_view_extensions/form_helper_test.rb +104 -0
  64. data/test/components/label_test.rb +310 -0
  65. data/test/form_builder/association_test.rb +177 -0
  66. data/test/form_builder/button_test.rb +47 -0
  67. data/test/form_builder/error_notification_test.rb +79 -0
  68. data/test/form_builder/error_test.rb +121 -0
  69. data/test/form_builder/general_test.rb +356 -0
  70. data/test/form_builder/hint_test.rb +139 -0
  71. data/test/form_builder/input_field_test.rb +63 -0
  72. data/test/form_builder/label_test.rb +71 -0
  73. data/test/form_builder/wrapper_test.rb +149 -0
  74. data/test/generators/simple_form_generator_test.rb +32 -0
  75. data/test/inputs/boolean_input_test.rb +108 -0
  76. data/test/inputs/collection_check_boxes_input_test.rb +224 -0
  77. data/test/inputs/collection_radio_buttons_input_test.rb +326 -0
  78. data/test/inputs/collection_select_input_test.rb +241 -0
  79. data/test/inputs/datetime_input_test.rb +99 -0
  80. data/test/inputs/disabled_test.rb +38 -0
  81. data/test/inputs/discovery_test.rb +61 -0
  82. data/test/inputs/file_input_test.rb +16 -0
  83. data/test/inputs/general_test.rb +69 -0
  84. data/test/inputs/grouped_collection_select_input_test.rb +118 -0
  85. data/test/inputs/hidden_input_test.rb +30 -0
  86. data/test/inputs/numeric_input_test.rb +173 -0
  87. data/test/inputs/priority_input_test.rb +43 -0
  88. data/test/inputs/readonly_test.rb +61 -0
  89. data/test/inputs/required_test.rb +113 -0
  90. data/test/inputs/string_input_test.rb +140 -0
  91. data/test/inputs/text_input_test.rb +29 -0
  92. data/test/simple_form_test.rb +9 -0
  93. data/test/support/discovery_inputs.rb +21 -0
  94. data/test/support/misc_helpers.rb +102 -0
  95. data/test/support/mock_controller.rb +24 -0
  96. data/test/support/mock_response.rb +14 -0
  97. data/test/support/models.rb +210 -0
  98. data/test/test_helper.rb +95 -0
  99. metadata +227 -0
@@ -0,0 +1,78 @@
1
+ module SimpleFormWithClientValidation
2
+ module Wrappers
3
+ # A wrapper is an object that holds several components and render them.
4
+ # A component may either be a symbol or any object that responds to `render`.
5
+ # This API allows inputs/components to be easily wrapped, removing the
6
+ # need to modify the code only to wrap input in an extra tag.
7
+ #
8
+ # `Many` represents a wrapper around several components at the same time.
9
+ # It may optionally receive a namespace, allowing it to be configured
10
+ # on demand on input generation. The find function returns if it
11
+ # matches namespace
12
+ class Many
13
+ attr_reader :namespace, :defaults, :components
14
+ alias :to_sym :namespace
15
+
16
+ def initialize(namespace, components, defaults={})
17
+ @namespace = namespace
18
+ @components = components
19
+ @defaults = defaults
20
+ @defaults[:tag] = :div unless @defaults.key?(:tag)
21
+ @defaults[:class] = Array.wrap(@defaults[:class])
22
+ end
23
+
24
+ def render(input)
25
+ content = "".html_safe
26
+ options = input.options
27
+
28
+ components.each do |component|
29
+ next if options[component] == false
30
+ rendered = component.respond_to?(:render) ? component.render(input) : input.send(component)
31
+ content.safe_concat rendered.to_s if rendered
32
+ end
33
+
34
+ wrap(input, options, content)
35
+ end
36
+
37
+ def find(name)
38
+ return self if namespace == name
39
+
40
+ @components.each do |c|
41
+ if c.is_a?(Symbol)
42
+ return nil if c == namespace
43
+ elsif value = c.find(name)
44
+ return value
45
+ end
46
+ end
47
+
48
+ nil
49
+ end
50
+
51
+ private
52
+
53
+ #this will wrap the content
54
+ #unless options for this namespace=false which is set by b.optional :namespace
55
+ #and user didn't explicitly set one
56
+ def wrap(input, options, content)
57
+
58
+ #this would be triggered if b.optional :namespace and user didn't supply :namespace explicitly
59
+ #in b.input :myfield, :namespace => "something"
60
+ return content if options[namespace] == false
61
+
62
+ tag = (namespace && options[:"#{namespace}_tag"]) || @defaults[:tag]
63
+ return content unless tag
64
+
65
+ klass = html_classes(input, options)
66
+ opts = options[:"#{namespace}_html"] || {}
67
+ opts[:class] = (klass << opts[:class]).join(' ').strip unless klass.empty?
68
+
69
+ #this outputs into @builder.template of input
70
+ input.template.content_tag(tag, content, opts)
71
+ end
72
+
73
+ def html_classes(input, options)
74
+ @defaults[:class].dup
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,34 @@
1
+ module SimpleFormWithClientValidation
2
+ module Wrappers
3
+ # `Root` is the root wrapper for all components. It is special cased to
4
+ # always have a namespace and to add special html classes.
5
+ class Root < Many
6
+ attr_reader :options
7
+
8
+ def initialize(*args)
9
+ super(:wrapper, *args)
10
+ @options = @defaults.except(:tag, :class, :error_class, :hint_class)
11
+ end
12
+
13
+ def render(input)
14
+ input.options.reverse_merge!(@options)
15
+ super
16
+ end
17
+
18
+ # Provide a fallback if name cannot be found.
19
+ def find(name)
20
+ super || SimpleFormWithClientValidation::Wrappers::Many.new(name, [name])
21
+ end
22
+
23
+ private
24
+
25
+ def html_classes(input, options)
26
+ css = options[:wrapper_class] ? Array.wrap(options[:wrapper_class]) : @defaults[:class]
27
+ css += SimpleFormWithClientValidation.additional_classes_for(:wrapper) { input.html_classes }
28
+ css << (options[:wrapper_error_class] || @defaults[:error_class]) if input.has_errors?
29
+ css << (options[:wrapper_hint_class] || @defaults[:hint_class]) if input.has_hint?
30
+ css
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,18 @@
1
+ module SimpleFormWithClientValidation
2
+ module Wrappers
3
+ # `Single` is an optimization for a wrapper that has only one component.
4
+ class Single < Many
5
+ def initialize(name, options={})
6
+ super(name, [name], options)
7
+ end
8
+
9
+ def render(input)
10
+ options = input.options
11
+ if options[namespace] != false
12
+ content = input.send(namespace)
13
+ wrap(input, options, content) if content
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,8 @@
1
+ module SimpleFormWithClientValidation
2
+ module Wrappers
3
+ autoload :Builder, 'simple_form_with_client_validation/wrappers/builder'
4
+ autoload :Many, 'simple_form_with_client_validation/wrappers/many'
5
+ autoload :Root, 'simple_form_with_client_validation/wrappers/root'
6
+ autoload :Single, 'simple_form_with_client_validation/wrappers/single'
7
+ end
8
+ end
@@ -0,0 +1,218 @@
1
+ require 'action_view'
2
+ require 'simple_form_with_client_validation/action_view_extensions/form_helper'
3
+ require 'simple_form_with_client_validation/action_view_extensions/builder'
4
+ require 'active_support/core_ext/hash/slice'
5
+ require 'active_support/core_ext/hash/except'
6
+ require 'active_support/core_ext/hash/reverse_merge'
7
+
8
+ module SimpleFormWithClientValidation
9
+ autoload :Components, 'simple_form_with_client_validation/components'
10
+ autoload :ErrorNotification, 'simple_form_with_client_validation/error_notification'
11
+ autoload :FormBuilder, 'simple_form_with_client_validation/form_builder'
12
+ autoload :Helpers, 'simple_form_with_client_validation/helpers'
13
+ autoload :I18nCache, 'simple_form_with_client_validation/i18n_cache'
14
+ autoload :Inputs, 'simple_form_with_client_validation/inputs'
15
+ autoload :MapType, 'simple_form_with_client_validation/map_type'
16
+ autoload :Wrappers, 'simple_form_with_client_validation/wrappers'
17
+
18
+ ## CONFIGURATION OPTIONS
19
+
20
+ # Method used to tidy up errors.
21
+ mattr_accessor :error_method
22
+ @@error_method = :first
23
+
24
+ # Default tag used for error notification helper.
25
+ mattr_accessor :error_notification_tag
26
+ @@error_notification_tag = :p
27
+
28
+ # CSS class to add for error notification helper.
29
+ mattr_accessor :error_notification_class
30
+ @@error_notification_class = :error_notification
31
+
32
+ # Series of attemps to detect a default label method for collection.
33
+ mattr_accessor :collection_label_methods
34
+ @@collection_label_methods = [ :to_label, :name, :title, :to_s ]
35
+
36
+ # Series of attemps to detect a default value method for collection.
37
+ mattr_accessor :collection_value_methods
38
+ @@collection_value_methods = [ :id, :to_s ]
39
+
40
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
41
+ mattr_accessor :collection_wrapper_tag
42
+ @@collection_wrapper_tag = nil
43
+
44
+ # You can define the class to use on all collection wrappers, defaulting to none.
45
+ mattr_accessor :collection_wrapper_class
46
+ @@collection_wrapper_class = nil
47
+
48
+ # You can wrap each item in a collection of radio/check boxes with a tag,
49
+ # defaulting to none. Please note that when using :boolean_style = :nested,
50
+ # SimpleFormWithClientValidation will force this option to be a :label.
51
+ mattr_accessor :item_wrapper_tag
52
+ @@item_wrapper_tag = :span
53
+
54
+ # You can define the class to use on all item wrappers, defaulting to none.
55
+ mattr_accessor :item_wrapper_class
56
+ @@item_wrapper_class = nil
57
+
58
+ # How the label text should be generated altogether with the required text.
59
+ mattr_accessor :label_text
60
+ @@label_text = lambda { |label, required| "#{required} #{label}" }
61
+
62
+ # You can define the class to use on all labels. Default is nil.
63
+ mattr_accessor :label_class
64
+ @@label_class = nil
65
+
66
+ # Define the way to render check boxes / radio buttons with labels.
67
+ # :inline => input + label (default)
68
+ # :nested => label > input
69
+ mattr_accessor :boolean_style
70
+ @@boolean_style = :inline
71
+
72
+ # You can define the class to use on all forms. Default is simple_form.
73
+ mattr_accessor :form_class
74
+ @@form_class = :simple_form
75
+
76
+ # You can define which elements should obtain additional classes
77
+ mattr_accessor :generate_additional_classes_for
78
+ @@generate_additional_classes_for = [:wrapper, :label, :input]
79
+
80
+ # Whether attributes are required by default (or not).
81
+ mattr_accessor :required_by_default
82
+ @@required_by_default = true
83
+
84
+ # Tell browsers whether to use default HTML5 validations (novalidate option).
85
+ mattr_accessor :browser_validations
86
+ @@browser_validations = true
87
+
88
+ # Collection of methods to detect if a file type was given.
89
+ mattr_accessor :file_methods
90
+ @@file_methods = [ :mounted_as, :file?, :public_filename ]
91
+
92
+ # Custom mappings for input types. This should be a hash containing a regexp
93
+ # to match as key, and the input type that will be used when the field name
94
+ # matches the regexp as value, such as { /count/ => :integer }.
95
+ mattr_accessor :input_mappings
96
+ @@input_mappings = nil
97
+
98
+ # Default priority for time_zone inputs.
99
+ mattr_accessor :time_zone_priority
100
+ @@time_zone_priority = nil
101
+
102
+ # Default priority for country inputs.
103
+ mattr_accessor :country_priority
104
+ @@country_priority = nil
105
+
106
+ # Maximum size allowed for inputs.
107
+ mattr_accessor :default_input_size
108
+ @@default_input_size = 50
109
+
110
+ # When off, do not use translations in labels. Disabling translation in
111
+ # hints and placeholders can be done manually in the wrapper API.
112
+ mattr_accessor :translate_labels
113
+ @@translate_labels = true
114
+
115
+ # Automatically discover new inputs in Rails' autoload path.
116
+ mattr_accessor :inputs_discovery
117
+ @@inputs_discovery = true
118
+
119
+ # Cache SimpleFormWithClientValidation inputs discovery
120
+ mattr_accessor :cache_discovery
121
+ @@cache_discovery = defined?(Rails) && !Rails.env.development?
122
+
123
+ # Adds a class to each generated button, mostly for compatiblity
124
+ mattr_accessor :button_class
125
+ @@button_class = 'button'
126
+
127
+ ## WRAPPER CONFIGURATION
128
+ # The default wrapper to be used by the FormBuilder.
129
+ mattr_accessor :default_wrapper
130
+ @@default_wrapper = :default
131
+ @@wrappers = {}
132
+
133
+ # Retrieves a given wrapper
134
+ def self.wrapper(name)
135
+ @@wrappers[name.to_sym] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
136
+ end
137
+
138
+ # Raised when fails to find a given wrapper name
139
+ class WrapperNotFound < StandardError
140
+ end
141
+
142
+ # Define a new wrapper using SimpleFormWithClientValidation::Wrappers::Builder
143
+ # and store it in the given name.
144
+ def self.wrappers(*args, &block)
145
+ if block_given?
146
+ options = args.extract_options!
147
+ name = args.first || :default
148
+ @@wrappers[name.to_sym] = build(options, &block)
149
+ else
150
+ @@wrappers
151
+ end
152
+ end
153
+
154
+ # Builds a new wrapper using SimpleFormWithClientValidation::Wrappers::Builder.
155
+ def self.build(options={})
156
+ options[:tag] = :div if options[:tag].nil?
157
+ builder = SimpleFormWithClientValidation::Wrappers::Builder.new(options)
158
+ yield builder
159
+ SimpleFormWithClientValidation::Wrappers::Root.new(builder.to_a, options)
160
+ end
161
+
162
+ #this creates a :default wrapper that will be overridden if user configures
163
+ #one in config/initializers/simple_form_with_client_validation.rb
164
+ wrappers :class => :input, :hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
165
+ b.use :html5
166
+
167
+ b.use :min_max
168
+ b.use :maxlength
169
+ b.use :minlength
170
+ b.use :placeholder
171
+ b.optional :pattern
172
+ b.optional :readonly
173
+
174
+ b.use :label_input
175
+ b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
176
+ b.use :error, :wrap_with => { :tag => :span, :class => :error }
177
+ end
178
+
179
+ ## SETUP
180
+
181
+ DEPRECATED = %w(hint_tag hint_class error_tag error_class error_notification_id wrapper_tag wrapper_class wrapper_error_class components html5)
182
+ @@deprecated = []
183
+
184
+ DEPRECATED.each do |method|
185
+ class_eval "def self.#{method}=(*); @@deprecated << :#{method}=; end"
186
+ class_eval "def self.#{method}; deprecation_warn 'SimpleFormWithClientValidation.#{method} is deprecated and has no effect'; end"
187
+ end
188
+
189
+ def self.translate=(value)
190
+ deprecation_warn "SimpleFormWithClientValidation.translate= is disabled in favor of translate_labels="
191
+ self.translate_labels = value
192
+ end
193
+
194
+ def self.translate
195
+ deprecation_warn "SimpleFormWithClientValidation.translate is disabled in favor of translate_labels"
196
+ self.translate_labels
197
+ end
198
+
199
+ def self.deprecation_warn(message)
200
+ ActiveSupport::Deprecation.warn "[SIMPLE_FORM] #{message}", caller
201
+ end
202
+
203
+ def self.additional_classes_for(component)
204
+ generate_additional_classes_for.include?(component) ? yield : []
205
+ end
206
+
207
+ # Default way to setup SimpleFormWithClientValidation. Run rails generate simple_form:install
208
+ # to create a fresh initializer with all configuration values.
209
+ def self.setup
210
+ yield self
211
+
212
+ unless @@deprecated.empty?
213
+ raise "[SIMPLE FORM] Your SimpleFormWithClientValidation initializer file is using the following methods: #{@@deprecated.to_sentence}. " <<
214
+ "Those methods are part of the outdated configuration API. Updating to the new API is easy and fast. " <<
215
+ "Check for more info here: https://github.com/plataformatec/simple_form/wiki/Upgrading-to-Simple-Form-2.0"
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,577 @@
1
+ require 'test_helper'
2
+
3
+ class BuilderTest < ActionView::TestCase
4
+ def with_custom_form_for(object, *args, &block)
5
+ with_concat_custom_form_for(object) do |f|
6
+ assert f.instance_of?(CustomFormBuilder)
7
+ yield f
8
+ end
9
+ end
10
+
11
+ def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
12
+ with_concat_form_for(object) do |f|
13
+ f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
14
+ end
15
+ end
16
+
17
+ def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
18
+ with_concat_form_for(object) do |f|
19
+ f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
20
+ end
21
+ end
22
+
23
+ # COLLECTION RADIO
24
+ test 'collection radio accepts a collection and generate inputs from value method' do
25
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
26
+
27
+ assert_select 'form input[type=radio][value=true]#user_active_true'
28
+ assert_select 'form input[type=radio][value=false]#user_active_false'
29
+ end
30
+
31
+ test 'collection radio accepts a collection and generate inputs from label method' do
32
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
33
+
34
+ assert_select 'form label.collection_radio_buttons[for=user_active_true]', 'true'
35
+ assert_select 'form label.collection_radio_buttons[for=user_active_false]', 'false'
36
+ end
37
+
38
+ test 'collection radio handles camelized collection values for labels correctly' do
39
+ with_collection_radio_buttons @user, :active, ['Yes', 'No'], :to_s, :to_s
40
+
41
+ assert_select 'form label.collection_radio_buttons[for=user_active_yes]', 'Yes'
42
+ assert_select 'form label.collection_radio_buttons[for=user_active_no]', 'No'
43
+ end
44
+
45
+ test 'collection radio should sanitize collection values for labels correctly' do
46
+ with_collection_radio_buttons @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
47
+ assert_select 'label.collection_radio_buttons[for=user_name_099]', '$0.99'
48
+ assert_select 'label.collection_radio_buttons[for=user_name_199]', '$1.99'
49
+ end
50
+
51
+ test 'collection radio checks the correct value to local variables' do
52
+ user = User.new
53
+ user.active = false
54
+ with_collection_radio_buttons user, :active, [true, false], :to_s, :to_s
55
+
56
+ assert_select 'form input[type=radio][value=true]'
57
+ assert_select 'form input[type=radio][value=false][checked=checked]'
58
+ end
59
+
60
+ test 'collection radio accepts checked item' do
61
+ with_collection_radio_buttons @user, :active, [[1, true], [0, false]], :last, :first, :checked => true
62
+
63
+ assert_select 'form input[type=radio][value=true][checked=checked]'
64
+ assert_no_select 'form input[type=radio][value=false][checked=checked]'
65
+ end
66
+
67
+ test 'collection radio accepts checked item which has a value of false' do
68
+ with_collection_radio_buttons @user, :active, [[1, true], [0, false]], :last, :first, :checked => false
69
+ assert_no_select 'form input[type=radio][value=true][checked=checked]'
70
+ assert_select 'form input[type=radio][value=false][checked=checked]'
71
+ end
72
+
73
+ test 'collection radio accepts multiple disabled items' do
74
+ collection = [[1, true], [0, false], [2, 'other']]
75
+ with_collection_radio_buttons @user, :active, collection, :last, :first, :disabled => [true, false]
76
+
77
+ assert_select 'form input[type=radio][value=true][disabled=disabled]'
78
+ assert_select 'form input[type=radio][value=false][disabled=disabled]'
79
+ assert_no_select 'form input[type=radio][value=other][disabled=disabled]'
80
+ end
81
+
82
+ test 'collection radio accepts single disable item' do
83
+ collection = [[1, true], [0, false]]
84
+ with_collection_radio_buttons @user, :active, collection, :last, :first, :disabled => true
85
+
86
+ assert_select 'form input[type=radio][value=true][disabled=disabled]'
87
+ assert_no_select 'form input[type=radio][value=false][disabled=disabled]'
88
+ end
89
+
90
+ test 'collection radio accepts html options as input' do
91
+ collection = [[1, true], [0, false]]
92
+ with_collection_radio_buttons @user, :active, collection, :last, :first, {}, :class => 'special-radio'
93
+
94
+ assert_select 'form input[type=radio][value=true].special-radio#user_active_true'
95
+ assert_select 'form input[type=radio][value=false].special-radio#user_active_false'
96
+ end
97
+
98
+ test 'collection radio wraps the collection in the given collection wrapper tag' do
99
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
100
+
101
+ assert_select 'form ul input[type=radio]', :count => 2
102
+ end
103
+
104
+ test 'collection radio does not render any wrapper tag by default' do
105
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
106
+
107
+ assert_select 'form input[type=radio]', :count => 2
108
+ assert_no_select 'form ul'
109
+ end
110
+
111
+ test 'collection radio does not wrap the collection when given falsy values' do
112
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
113
+
114
+ assert_select 'form input[type=radio]', :count => 2
115
+ assert_no_select 'form ul'
116
+ end
117
+
118
+ test 'collection radio uses the given class for collection wrapper tag' do
119
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
120
+ :collection_wrapper_tag => :ul, :collection_wrapper_class => "items-list"
121
+
122
+ assert_select 'form ul.items-list input[type=radio]', :count => 2
123
+ end
124
+
125
+ test 'collection radio uses no class for collection wrapper tag when no wrapper tag is given' do
126
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
127
+ :collection_wrapper_class => "items-list"
128
+
129
+ assert_select 'form input[type=radio]', :count => 2
130
+ assert_no_select 'form ul'
131
+ assert_no_select '.items-list'
132
+ end
133
+
134
+ test 'collection radio uses no class for collection wrapper tag by default' do
135
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
136
+
137
+ assert_select 'form ul'
138
+ assert_no_select 'form ul[class]'
139
+ end
140
+
141
+ test 'collection radio wrap items in a span tag by default' do
142
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
143
+
144
+ assert_select 'form span input[type=radio][value=true]#user_active_true + label'
145
+ assert_select 'form span input[type=radio][value=false]#user_active_false + label'
146
+ end
147
+
148
+ test 'collection radio wraps each item in the given item wrapper tag' do
149
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
150
+
151
+ assert_select 'form li input[type=radio]', :count => 2
152
+ end
153
+
154
+ test 'collection radio does not wrap each item when given explicitly falsy value' do
155
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => false
156
+
157
+ assert_select 'form input[type=radio]'
158
+ assert_no_select 'form span input[type=radio]'
159
+ end
160
+
161
+ test 'collection radio uses the given class for item wrapper tag' do
162
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
163
+ :item_wrapper_tag => :li, :item_wrapper_class => "inline"
164
+
165
+ assert_select "form li.inline input[type=radio]", :count => 2
166
+ end
167
+
168
+ test 'collection radio uses no class for item wrapper tag when no wrapper tag is given' do
169
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
170
+ :item_wrapper_tag => nil, :item_wrapper_class => "inline"
171
+
172
+ assert_select 'form input[type=radio]', :count => 2
173
+ assert_no_select 'form li'
174
+ assert_no_select '.inline'
175
+ end
176
+
177
+ test 'collection radio uses no class for item wrapper tag by default' do
178
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s,
179
+ :item_wrapper_tag => :li
180
+
181
+ assert_select "form li", :count => 2
182
+ assert_no_select "form li[class]"
183
+ end
184
+
185
+ test 'collection radio does not wrap input inside the label' do
186
+ with_collection_radio_buttons @user, :active, [true, false], :to_s, :to_s
187
+
188
+ assert_select 'form input[type=radio] + label'
189
+ assert_no_select 'form label input'
190
+ end
191
+
192
+ test 'collection radio accepts a block to render the label as radio button wrapper' do
193
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
194
+ b.label { b.radio_button }
195
+ end
196
+
197
+ assert_select 'label[for=user_active_true] > input#user_active_true[type=radio]'
198
+ assert_select 'label[for=user_active_false] > input#user_active_false[type=radio]'
199
+ end
200
+
201
+ test 'collection radio accepts a block to change the order of label and radio button' do
202
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
203
+ b.label + b.radio_button
204
+ end
205
+
206
+ assert_select 'label[for=user_active_true] + input#user_active_true[type=radio]'
207
+ assert_select 'label[for=user_active_false] + input#user_active_false[type=radio]'
208
+ end
209
+
210
+ test 'collection radio with block helpers accept extra html options' do
211
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
212
+ b.label(:class => "radio_button") + b.radio_button(:class => "radio_button")
213
+ end
214
+
215
+ assert_select 'label.radio_button[for=user_active_true] + input#user_active_true.radio_button[type=radio]'
216
+ assert_select 'label.radio_button[for=user_active_false] + input#user_active_false.radio_button[type=radio]'
217
+ end
218
+
219
+ test 'collection radio with block helpers allows access to current text and value' do
220
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
221
+ b.label(:"data-value" => b.value) { b.radio_button + b.text }
222
+ end
223
+
224
+ assert_select 'label[for=user_active_true][data-value=true]', 'true' do
225
+ assert_select 'input#user_active_true[type=radio]'
226
+ end
227
+ assert_select 'label[for=user_active_false][data-value=false]', 'false' do
228
+ assert_select 'input#user_active_false[type=radio]'
229
+ end
230
+ end
231
+
232
+ test 'collection radio with block helpers allows access to the current object item in the collection to access extra properties' do
233
+ with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s do |b|
234
+ b.label(:class => b.object) { b.radio_button + b.text }
235
+ end
236
+
237
+ assert_select 'label.true[for=user_active_true]', 'true' do
238
+ assert_select 'input#user_active_true[type=radio]'
239
+ end
240
+ assert_select 'label.false[for=user_active_false]', 'false' do
241
+ assert_select 'input#user_active_false[type=radio]'
242
+ end
243
+ end
244
+
245
+ test 'collection_radio helper is deprecated in favor of collection_radio_buttons' do
246
+ assert_deprecated "[SIMPLE_FORM] The `collection_radio` helper is deprecated, " \
247
+ "please use `collection_radio_buttons` instead" do
248
+ with_concat_form_for(@user) do |f|
249
+ f.collection_radio :active, [true, false], :to_s, :to_s
250
+ end
251
+ end
252
+
253
+ assert_select 'input[type=radio][value=true]'
254
+ assert_select 'input[type=radio][value=false]'
255
+ end
256
+
257
+ # COLLECTION CHECK BOX
258
+ test 'collection check box accepts a collection and generate a serie of checkboxes for value method' do
259
+ collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
260
+ with_collection_check_boxes @user, :tag_ids, collection, :id, :name
261
+
262
+ assert_select 'form input#user_tag_ids_1[type=checkbox][value=1]'
263
+ assert_select 'form input#user_tag_ids_2[type=checkbox][value=2]'
264
+ end
265
+
266
+ test 'collection check box generates only one hidden field for the entire collection, to ensure something will be sent back to the server when posting an empty collection' do
267
+ collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
268
+ with_collection_check_boxes @user, :tag_ids, collection, :id, :name
269
+
270
+ assert_select "form input[type=hidden][name='user[tag_ids][]'][value=]", :count => 1
271
+ end
272
+
273
+ test 'collection check box accepts a collection and generate a serie of checkboxes with labels for label method' do
274
+ collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
275
+ with_collection_check_boxes @user, :tag_ids, collection, :id, :name
276
+
277
+ assert_select 'form label.collection_check_boxes[for=user_tag_ids_1]', 'Tag 1'
278
+ assert_select 'form label.collection_check_boxes[for=user_tag_ids_2]', 'Tag 2'
279
+ end
280
+
281
+ test 'collection check box handles camelized collection values for labels correctly' do
282
+ with_collection_check_boxes @user, :active, ['Yes', 'No'], :to_s, :to_s
283
+
284
+ assert_select 'form label.collection_check_boxes[for=user_active_yes]', 'Yes'
285
+ assert_select 'form label.collection_check_boxes[for=user_active_no]', 'No'
286
+ end
287
+
288
+ test 'collection check box should sanitize collection values for labels correctly' do
289
+ with_collection_check_boxes @user, :name, ['$0.99', '$1.99'], :to_s, :to_s
290
+ assert_select 'label.collection_check_boxes[for=user_name_099]', '$0.99'
291
+ assert_select 'label.collection_check_boxes[for=user_name_199]', '$1.99'
292
+ end
293
+
294
+ test 'collection check box checks the correct value to local variables' do
295
+ user = User.new
296
+ user.tag_ids = [1, 3]
297
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
298
+ with_collection_check_boxes user, :tag_ids, collection, :first, :last
299
+
300
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
301
+ assert_select 'form input[type=checkbox][value=3][checked=checked]'
302
+ assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
303
+ end
304
+
305
+
306
+ test 'collection check box accepts selected values as :checked option' do
307
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
308
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => [1, 3]
309
+
310
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
311
+ assert_select 'form input[type=checkbox][value=3][checked=checked]'
312
+ assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
313
+ end
314
+
315
+ test 'collection check box accepts a single checked value' do
316
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
317
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => 3
318
+
319
+ assert_select 'form input[type=checkbox][value=3][checked=checked]'
320
+ assert_no_select 'form input[type=checkbox][value=1][checked=checked]'
321
+ assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
322
+ end
323
+
324
+ test 'collection check box accepts selected values as :checked option and override the model values' do
325
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
326
+ @user.tag_ids = [2]
327
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :checked => [1, 3]
328
+
329
+ assert_select 'form input[type=checkbox][value=1][checked=checked]'
330
+ assert_select 'form input[type=checkbox][value=3][checked=checked]'
331
+ assert_no_select 'form input[type=checkbox][value=2][checked=checked]'
332
+ end
333
+
334
+ test 'collection check box accepts multiple disabled items' do
335
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
336
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => [1, 3]
337
+
338
+ assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
339
+ assert_select 'form input[type=checkbox][value=3][disabled=disabled]'
340
+ assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
341
+ end
342
+
343
+ test 'collection check box accepts single disable item' do
344
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
345
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => 1
346
+
347
+ assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
348
+ assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
349
+ assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
350
+ end
351
+
352
+ test 'collection check box accepts a proc to disabled items' do
353
+ collection = (1..3).map{|i| [i, "Tag #{i}"] }
354
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
355
+
356
+ assert_select 'form input[type=checkbox][value=1][disabled=disabled]'
357
+ assert_no_select 'form input[type=checkbox][value=3][disabled=disabled]'
358
+ assert_no_select 'form input[type=checkbox][value=2][disabled=disabled]'
359
+ end
360
+
361
+ test 'collection check box accepts html options' do
362
+ collection = [[1, 'Tag 1'], [2, 'Tag 2']]
363
+ with_collection_check_boxes @user, :tag_ids, collection, :first, :last, {}, :class => 'check'
364
+
365
+ assert_select 'form input.check[type=checkbox][value=1]'
366
+ assert_select 'form input.check[type=checkbox][value=2]'
367
+ end
368
+
369
+ test 'collection check box with fields for' do
370
+ collection = [Tag.new(1, 'Tag 1'), Tag.new(2, 'Tag 2')]
371
+ with_concat_form_for(@user) do |f|
372
+ f.fields_for(:post) do |p|
373
+ p.collection_check_boxes :tag_ids, collection, :id, :name
374
+ end
375
+ end
376
+
377
+ assert_select 'form input#user_post_tag_ids_1[type=checkbox][value=1]'
378
+ assert_select 'form input#user_post_tag_ids_2[type=checkbox][value=2]'
379
+
380
+ assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_1]', 'Tag 1'
381
+ assert_select 'form label.collection_check_boxes[for=user_post_tag_ids_2]', 'Tag 2'
382
+ end
383
+
384
+ test 'collection check boxes wraps the collection in the given collection wrapper tag' do
385
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
386
+
387
+ assert_select 'form ul input[type=checkbox]', :count => 2
388
+ end
389
+
390
+ test 'collection check boxes does not render any wrapper tag by default' do
391
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
392
+
393
+ assert_select 'form input[type=checkbox]', :count => 2
394
+ assert_no_select 'form ul'
395
+ end
396
+
397
+ test 'collection check boxes does not wrap the collection when given falsy values' do
398
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => false
399
+
400
+ assert_select 'form input[type=checkbox]', :count => 2
401
+ assert_no_select 'form ul'
402
+ end
403
+
404
+ test 'collection check boxes uses the given class for collection wrapper tag' do
405
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
406
+ :collection_wrapper_tag => :ul, :collection_wrapper_class => "items-list"
407
+
408
+ assert_select 'form ul.items-list input[type=checkbox]', :count => 2
409
+ end
410
+
411
+ test 'collection check boxes uses no class for collection wrapper tag when no wrapper tag is given' do
412
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
413
+ :collection_wrapper_class => "items-list"
414
+
415
+ assert_select 'form input[type=checkbox]', :count => 2
416
+ assert_no_select 'form ul'
417
+ assert_no_select '.items-list'
418
+ end
419
+
420
+ test 'collection check boxes uses no class for collection wrapper tag by default' do
421
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :collection_wrapper_tag => :ul
422
+
423
+ assert_select 'form ul'
424
+ assert_no_select 'form ul[class]'
425
+ end
426
+
427
+ test 'collection check boxes wrap items in a span tag by default' do
428
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
429
+
430
+ assert_select 'form span input[type=checkbox]', :count => 2
431
+ end
432
+
433
+ test 'collection check boxes wraps each item in the given item wrapper tag' do
434
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => :li
435
+
436
+ assert_select 'form li input[type=checkbox]', :count => 2
437
+ end
438
+
439
+ test 'collection check boxes does not wrap each item when given explicitly falsy value' do
440
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s, :item_wrapper_tag => false
441
+
442
+ assert_select 'form input[type=checkbox]'
443
+ assert_no_select 'form span input[type=checkbox]'
444
+ end
445
+
446
+ test 'collection check boxes uses the given class for item wrapper tag' do
447
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
448
+ :item_wrapper_tag => :li, :item_wrapper_class => "inline"
449
+
450
+ assert_select "form li.inline input[type=checkbox]", :count => 2
451
+ end
452
+
453
+ test 'collection check boxes uses no class for item wrapper tag when no wrapper tag is given' do
454
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
455
+ :item_wrapper_tag => nil, :item_wrapper_class => "inline"
456
+
457
+ assert_select 'form input[type=checkbox]', :count => 2
458
+ assert_no_select 'form li'
459
+ assert_no_select '.inline'
460
+ end
461
+
462
+ test 'collection check boxes uses no class for item wrapper tag by default' do
463
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s,
464
+ :item_wrapper_tag => :li
465
+
466
+ assert_select "form li", :count => 2
467
+ assert_no_select "form li[class]"
468
+ end
469
+
470
+ test 'collection check box does not wrap input inside the label' do
471
+ with_collection_check_boxes @user, :active, [true, false], :to_s, :to_s
472
+
473
+ assert_select 'form input[type=checkbox] + label'
474
+ assert_no_select 'form label input'
475
+ end
476
+
477
+ test 'collection check boxes accepts a block to render the label as check box wrapper' do
478
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
479
+ b.label { b.check_box }
480
+ end
481
+
482
+ assert_select 'label[for=user_active_true] > input#user_active_true[type=checkbox]'
483
+ assert_select 'label[for=user_active_false] > input#user_active_false[type=checkbox]'
484
+ end
485
+
486
+ test 'collection check boxes accepts a block to change the order of label and check box' do
487
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
488
+ b.label + b.check_box
489
+ end
490
+
491
+ assert_select 'label[for=user_active_true] + input#user_active_true[type=checkbox]'
492
+ assert_select 'label[for=user_active_false] + input#user_active_false[type=checkbox]'
493
+ end
494
+
495
+ test 'collection check boxes with block helpers accept extra html options' do
496
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
497
+ b.label(:class => "check_box") + b.check_box(:class => "check_box")
498
+ end
499
+
500
+ assert_select 'label.check_box[for=user_active_true] + input#user_active_true.check_box[type=checkbox]'
501
+ assert_select 'label.check_box[for=user_active_false] + input#user_active_false.check_box[type=checkbox]'
502
+ end
503
+
504
+ test 'collection check boxes with block helpers allows access to current text and value' do
505
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
506
+ b.label(:"data-value" => b.value) { b.check_box + b.text }
507
+ end
508
+
509
+ assert_select 'label[for=user_active_true][data-value=true]', 'true' do
510
+ assert_select 'input#user_active_true[type=checkbox]'
511
+ end
512
+ assert_select 'label[for=user_active_false][data-value=false]', 'false' do
513
+ assert_select 'input#user_active_false[type=checkbox]'
514
+ end
515
+ end
516
+
517
+ test 'collection check boxes with block helpers allows access to the current object item in the collection to access extra properties' do
518
+ with_collection_check_boxes :user, :active, [true, false], :to_s, :to_s do |b|
519
+ b.label(:class => b.object) { b.check_box + b.text }
520
+ end
521
+
522
+ assert_select 'label.true[for=user_active_true]', 'true' do
523
+ assert_select 'input#user_active_true[type=checkbox]'
524
+ end
525
+ assert_select 'label.false[for=user_active_false]', 'false' do
526
+ assert_select 'input#user_active_false[type=checkbox]'
527
+ end
528
+ end
529
+
530
+ # SIMPLE FIELDS
531
+ test 'simple fields for is available and yields an instance of FormBuilder' do
532
+ with_concat_form_for(@user) do |f|
533
+ f.simple_fields_for(:posts) do |posts_form|
534
+ assert posts_form.instance_of?(SimpleFormWithClientValidation::FormBuilder)
535
+ end
536
+ end
537
+ end
538
+
539
+ test 'fields for with a hash like model yeilds an instance of FormBuilder' do
540
+ @hash_backed_author = HashBackedAuthor.new
541
+
542
+ with_concat_form_for(:user) do |f|
543
+ f.simple_fields_for(:author, @hash_backed_author) do |author|
544
+ assert author.instance_of?(SimpleFormWithClientValidation::FormBuilder)
545
+ author.input :name
546
+ end
547
+ end
548
+
549
+ assert_select "input[name='user[author][name]'][value='hash backed author']"
550
+ end
551
+
552
+ test 'fields for yields an instance of CustomBuilder if main builder is a CustomBuilder' do
553
+ with_custom_form_for(:user) do |f|
554
+ f.simple_fields_for(:company) do |company|
555
+ assert company.instance_of?(CustomFormBuilder)
556
+ end
557
+ end
558
+ end
559
+
560
+ test 'fields for yields an instance of FormBuilder if it was set in options' do
561
+ with_custom_form_for(:user) do |f|
562
+ f.simple_fields_for(:company, :builder => SimpleFormWithClientValidation::FormBuilder) do |company|
563
+ assert company.instance_of?(SimpleFormWithClientValidation::FormBuilder)
564
+ end
565
+ end
566
+ end
567
+
568
+ test 'fields inherites wrapper option from the parent form' do
569
+ swap_wrapper :another do
570
+ simple_form_for(:user, :wrapper => :another) do |f|
571
+ f.simple_fields_for(:company) do |company|
572
+ assert_equal :another, company.options[:wrapper]
573
+ end
574
+ end
575
+ end
576
+ end
577
+ end