simple_form 3.0.3 → 3.1.0.rc1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -37
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +146 -71
  5. data/lib/generators/simple_form/install_generator.rb +2 -2
  6. data/lib/generators/simple_form/templates/README +3 -4
  7. data/lib/generators/simple_form/templates/config/initializers/simple_form.rb +19 -3
  8. data/lib/generators/simple_form/templates/config/initializers/simple_form_bootstrap.rb +83 -22
  9. data/lib/generators/simple_form/templates/config/initializers/simple_form_foundation.rb +1 -1
  10. data/lib/generators/simple_form/templates/config/locales/simple_form.en.yml +7 -2
  11. data/lib/simple_form/action_view_extensions/form_helper.rb +1 -1
  12. data/lib/simple_form/components/errors.rb +27 -5
  13. data/lib/simple_form/components/hints.rb +2 -2
  14. data/lib/simple_form/components/html5.rb +1 -1
  15. data/lib/simple_form/components/label_input.rb +20 -2
  16. data/lib/simple_form/components/labels.rb +9 -5
  17. data/lib/simple_form/components/maxlength.rb +1 -1
  18. data/lib/simple_form/components/min_max.rb +1 -1
  19. data/lib/simple_form/components/pattern.rb +1 -1
  20. data/lib/simple_form/components/placeholders.rb +2 -2
  21. data/lib/simple_form/components/readonly.rb +1 -1
  22. data/lib/simple_form/form_builder.rb +92 -57
  23. data/lib/simple_form/helpers.rb +5 -5
  24. data/lib/simple_form/inputs/base.rb +34 -12
  25. data/lib/simple_form/inputs/block_input.rb +1 -1
  26. data/lib/simple_form/inputs/boolean_input.rb +23 -13
  27. data/lib/simple_form/inputs/collection_input.rb +32 -9
  28. data/lib/simple_form/inputs/collection_radio_buttons_input.rb +6 -11
  29. data/lib/simple_form/inputs/collection_select_input.rb +4 -2
  30. data/lib/simple_form/inputs/date_time_input.rb +12 -2
  31. data/lib/simple_form/inputs/file_input.rb +4 -2
  32. data/lib/simple_form/inputs/grouped_collection_select_input.rb +15 -3
  33. data/lib/simple_form/inputs/hidden_input.rb +4 -2
  34. data/lib/simple_form/inputs/numeric_input.rb +5 -4
  35. data/lib/simple_form/inputs/password_input.rb +4 -2
  36. data/lib/simple_form/inputs/priority_input.rb +4 -2
  37. data/lib/simple_form/inputs/range_input.rb +1 -1
  38. data/lib/simple_form/inputs/string_input.rb +4 -2
  39. data/lib/simple_form/inputs/text_input.rb +4 -2
  40. data/lib/simple_form/railtie.rb +7 -0
  41. data/lib/simple_form/tags.rb +7 -0
  42. data/lib/simple_form/version.rb +1 -1
  43. data/lib/simple_form/wrappers/builder.rb +5 -5
  44. data/lib/simple_form/wrappers/leaf.rb +28 -0
  45. data/lib/simple_form/wrappers/many.rb +5 -6
  46. data/lib/simple_form/wrappers/root.rb +1 -1
  47. data/lib/simple_form/wrappers/single.rb +5 -3
  48. data/lib/simple_form/wrappers.rb +1 -0
  49. data/lib/simple_form.rb +38 -6
  50. data/test/action_view_extensions/builder_test.rb +2 -2
  51. data/test/components/label_test.rb +1 -1
  52. data/test/form_builder/association_test.rb +17 -0
  53. data/test/form_builder/error_notification_test.rb +1 -1
  54. data/test/form_builder/error_test.rb +51 -32
  55. data/test/form_builder/general_test.rb +2 -2
  56. data/test/form_builder/input_field_test.rb +25 -1
  57. data/test/form_builder/label_test.rb +24 -1
  58. data/test/form_builder/wrapper_test.rb +67 -0
  59. data/test/generators/simple_form_generator_test.rb +2 -2
  60. data/test/inputs/boolean_input_test.rb +50 -2
  61. data/test/inputs/collection_check_boxes_input_test.rb +40 -11
  62. data/test/inputs/collection_radio_buttons_input_test.rb +76 -17
  63. data/test/inputs/collection_select_input_test.rb +108 -3
  64. data/test/inputs/datetime_input_test.rb +105 -38
  65. data/test/inputs/discovery_test.rb +12 -1
  66. data/test/inputs/grouped_collection_select_input_test.rb +36 -0
  67. data/test/inputs/string_input_test.rb +20 -0
  68. data/test/simple_form_test.rb +8 -0
  69. data/test/support/discovery_inputs.rb +12 -2
  70. data/test/support/misc_helpers.rb +49 -5
  71. data/test/support/models.rb +49 -24
  72. metadata +6 -5
@@ -1,11 +1,14 @@
1
1
  module SimpleForm
2
2
  module Inputs
3
3
  class GroupedCollectionSelectInput < CollectionInput
4
- def input
4
+ def input(wrapper_options = nil)
5
5
  label_method, value_method = detect_collection_methods
6
+
7
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
+
6
9
  @builder.grouped_collection_select(attribute_name, grouped_collection,
7
10
  group_method, group_label_method, value_method, label_method,
8
- input_options, input_html_options)
11
+ input_options, merged_input_options)
9
12
  end
10
13
 
11
14
  private
@@ -19,7 +22,7 @@ module SimpleForm
19
22
 
20
23
  # Sample collection
21
24
  def collection
22
- @collection ||= grouped_collection.first.try(:send, group_method) || []
25
+ @collection ||= grouped_collection.map { |collection| collection.try(:send, group_method) }.detect(&:present?) || []
23
26
  end
24
27
 
25
28
  def group_method
@@ -36,6 +39,15 @@ module SimpleForm
36
39
 
37
40
  label
38
41
  end
42
+
43
+ def detect_method_from_class(collection_classes)
44
+ return {} if collection_classes.empty?
45
+
46
+ sample = collection_classes.first
47
+
48
+ { label: SimpleForm.collection_label_methods.find { |m| sample.instance_methods.include?(m) },
49
+ value: SimpleForm.collection_value_methods.find { |m| sample.instance_methods.include?(m) } }
50
+ end
39
51
  end
40
52
  end
41
53
  end
@@ -3,8 +3,10 @@ module SimpleForm
3
3
  class HiddenInput < Base
4
4
  disable :label, :errors, :hint, :required
5
5
 
6
- def input
7
- @builder.hidden_field(attribute_name, input_html_options)
6
+ def input(wrapper_options = nil)
7
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
+
9
+ @builder.hidden_field(attribute_name, merged_input_options)
8
10
  end
9
11
 
10
12
  private
@@ -3,16 +3,17 @@ module SimpleForm
3
3
  class NumericInput < Base
4
4
  enable :placeholder, :min_max
5
5
 
6
- def input
6
+ def input(wrapper_options = nil)
7
7
  input_html_classes.unshift("numeric")
8
8
  if html5?
9
9
  input_html_options[:type] ||= "number"
10
10
  input_html_options[:step] ||= integer? ? 1 : "any"
11
11
  end
12
- @builder.text_field(attribute_name, input_html_options)
13
- end
14
12
 
15
- private
13
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
14
+
15
+ @builder.text_field(attribute_name, merged_input_options)
16
+ end
16
17
  end
17
18
  end
18
19
  end
@@ -3,8 +3,10 @@ module SimpleForm
3
3
  class PasswordInput < Base
4
4
  enable :placeholder, :maxlength
5
5
 
6
- def input
7
- @builder.password_field(attribute_name, input_html_options)
6
+ def input(wrapper_options = nil)
7
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
+
9
+ @builder.password_field(attribute_name, merged_input_options)
8
10
  end
9
11
  end
10
12
  end
@@ -1,9 +1,11 @@
1
1
  module SimpleForm
2
2
  module Inputs
3
3
  class PriorityInput < CollectionSelectInput
4
- def input
4
+ def input(wrapper_options = nil)
5
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
6
+
5
7
  @builder.send(:"#{input_type}_select", attribute_name, input_priority,
6
- input_options, input_html_options)
8
+ input_options, merged_input_options)
7
9
  end
8
10
 
9
11
  def input_priority
@@ -1,7 +1,7 @@
1
1
  module SimpleForm
2
2
  module Inputs
3
3
  class RangeInput < NumericInput
4
- def input
4
+ def input(wrapper_options = nil)
5
5
  if html5?
6
6
  input_html_options[:type] ||= "range"
7
7
  input_html_options[:step] ||= 1
@@ -3,13 +3,15 @@ module SimpleForm
3
3
  class StringInput < Base
4
4
  enable :placeholder, :maxlength, :pattern
5
5
 
6
- def input
6
+ def input(wrapper_options = nil)
7
7
  unless string?
8
8
  input_html_classes.unshift("string")
9
9
  input_html_options[:type] ||= input_type if html5?
10
10
  end
11
11
 
12
- @builder.text_field(attribute_name, input_html_options)
12
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
13
+
14
+ @builder.text_field(attribute_name, merged_input_options)
13
15
  end
14
16
 
15
17
  private
@@ -3,8 +3,10 @@ module SimpleForm
3
3
  class TextInput < Base
4
4
  enable :placeholder, :maxlength
5
5
 
6
- def input
7
- @builder.text_area(attribute_name, input_html_options)
6
+ def input(wrapper_options = nil)
7
+ merged_input_options = merge_wrapper_options(input_html_options, wrapper_options)
8
+
9
+ @builder.text_area(attribute_name, merged_input_options)
8
10
  end
9
11
  end
10
12
  end
@@ -3,5 +3,12 @@ require 'rails/railtie'
3
3
  module SimpleForm
4
4
  class Railtie < Rails::Railtie
5
5
  config.eager_load_namespaces << SimpleForm
6
+
7
+ config.after_initialize do
8
+ unless SimpleForm.configured?
9
+ warn '[Simple Form] Simple Form is not configured in the application and will use the default values.' +
10
+ ' Use `rails generate simple_form:install` to generate the Simple Form configuration.'
11
+ end
12
+ end
6
13
  end
7
14
  end
@@ -15,6 +15,13 @@ module SimpleForm
15
15
 
16
16
  rendered_item = yield item, value, text, default_html_options.merge(additional_html_options)
17
17
 
18
+ if @options.fetch(:boolean_style, SimpleForm.boolean_style) == :nested
19
+ label_options = {}
20
+ add_default_name_and_id_for_value(value, label_options)
21
+ label_options['for'] = label_options.delete('id')
22
+ rendered_item = content_tag(:label, rendered_item, label_options)
23
+ end
24
+
18
25
  item_wrapper_tag ? @template_object.content_tag(item_wrapper_tag, rendered_item, class: item_wrapper_class) : rendered_item
19
26
  end.join.html_safe
20
27
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleForm
2
- VERSION = "3.0.3".freeze
2
+ VERSION = "3.1.0.rc1".freeze
3
3
  end
@@ -45,20 +45,20 @@ module SimpleForm
45
45
  @components = []
46
46
  end
47
47
 
48
- def use(name, options=nil, &block)
48
+ def use(name, options = {}, &block)
49
49
  if options && wrapper = options[:wrap_with]
50
- @components << Single.new(name, wrapper)
50
+ @components << Single.new(name, wrapper, options.except(:wrap_with))
51
51
  else
52
- @components << name
52
+ @components << Leaf.new(name, options)
53
53
  end
54
54
  end
55
55
 
56
- def optional(name, options=nil, &block)
56
+ def optional(name, options = {}, &block)
57
57
  @options[name] = false
58
58
  use(name, options, &block)
59
59
  end
60
60
 
61
- def wrapper(name, options=nil)
61
+ def wrapper(name, options = nil)
62
62
  if block_given?
63
63
  name, options = nil, name if name.is_a?(Hash)
64
64
  builder = self.class.new(@options)
@@ -0,0 +1,28 @@
1
+ module SimpleForm
2
+ module Wrappers
3
+ class Leaf
4
+ attr_reader :namespace
5
+
6
+ def initialize(namespace, options = {})
7
+ @namespace = namespace
8
+ @options = options
9
+ end
10
+
11
+ def render(input)
12
+ method = input.method(@namespace)
13
+
14
+ if method.arity == 0
15
+ ActiveSupport::Deprecation.warn(SimpleForm::CUSTOM_INPUT_DEPRECATION_WARN % { name: @namespace })
16
+
17
+ method.call
18
+ else
19
+ method.call(@options)
20
+ end
21
+ end
22
+
23
+ def find(name)
24
+ self if @namespace == name
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,7 +1,7 @@
1
1
  module SimpleForm
2
2
  module Wrappers
3
3
  # A wrapper is an object that holds several components and render them.
4
- # A component may either be a symbol or any object that responds to `render`.
4
+ # A component may be any object that responds to `render`.
5
5
  # This API allows inputs/components to be easily wrapped, removing the
6
6
  # need to modify the code only to wrap input in an extra tag.
7
7
  #
@@ -10,9 +10,8 @@ module SimpleForm
10
10
  # on demand on input generation.
11
11
  class Many
12
12
  attr_reader :namespace, :defaults, :components
13
- alias :to_sym :namespace
14
13
 
15
- def initialize(namespace, components, defaults={})
14
+ def initialize(namespace, components, defaults = {})
16
15
  @namespace = namespace
17
16
  @components = components
18
17
  @defaults = defaults
@@ -25,8 +24,8 @@ module SimpleForm
25
24
  options = input.options
26
25
 
27
26
  components.each do |component|
28
- next if options[component] == false
29
- rendered = component.respond_to?(:render) ? component.render(input) : input.send(component)
27
+ next if options[component.namespace] == false
28
+ rendered = component.render(input)
30
29
  content.safe_concat rendered.to_s if rendered
31
30
  end
32
31
 
@@ -62,7 +61,7 @@ module SimpleForm
62
61
  end
63
62
 
64
63
  def html_options(options)
65
- options[:"#{namespace}_html"] || {}
64
+ (@defaults[:html] || {}).merge(options[:"#{namespace}_html"] || {})
66
65
  end
67
66
 
68
67
  def html_classes(input, options)
@@ -17,7 +17,7 @@ module SimpleForm
17
17
 
18
18
  # Provide a fallback if name cannot be found.
19
19
  def find(name)
20
- super || SimpleForm::Wrappers::Many.new(name, [name])
20
+ super || SimpleForm::Wrappers::Many.new(name, [Leaf.new(name)])
21
21
  end
22
22
 
23
23
  private
@@ -2,14 +2,16 @@ module SimpleForm
2
2
  module Wrappers
3
3
  # `Single` is an optimization for a wrapper that has only one component.
4
4
  class Single < Many
5
- def initialize(name, options={})
6
- super(name, [name], options)
5
+ def initialize(name, wrapper_options = {}, options = {})
6
+ @component = Leaf.new(name, options)
7
+
8
+ super(name, [@component], wrapper_options)
7
9
  end
8
10
 
9
11
  def render(input)
10
12
  options = input.options
11
13
  if options[namespace] != false
12
- content = input.send(namespace)
14
+ content = @component.render(input)
13
15
  wrap(input, options, content) if content
14
16
  end
15
17
  end
@@ -4,5 +4,6 @@ module SimpleForm
4
4
  autoload :Many, 'simple_form/wrappers/many'
5
5
  autoload :Root, 'simple_form/wrappers/root'
6
6
  autoload :Single, 'simple_form/wrappers/single'
7
+ autoload :Leaf, 'simple_form/wrappers/leaf'
7
8
  end
8
9
  end
data/lib/simple_form.rb CHANGED
@@ -24,6 +24,24 @@ module SimpleForm
24
24
  SimpleForm::Components.eager_load!
25
25
  end
26
26
 
27
+ CUSTOM_INPUT_DEPRECATION_WARN = <<-WARN
28
+ %{name} method now accepts a `wrapper_options` argument. The method definition without the argument is deprecated and will be removed in the next Simple Form version. Change your code from:
29
+
30
+ def %{name}
31
+
32
+ to
33
+
34
+ def %{name}(wrapper_options)
35
+
36
+ See https://github.com/plataformatec/simple_form/pull/997 for more information.
37
+ WARN
38
+
39
+ @@configured = false
40
+
41
+ def self.configured? #:nodoc:
42
+ @@configured
43
+ end
44
+
27
45
  ## CONFIGURATION OPTIONS
28
46
 
29
47
  # Method used to tidy up errors.
@@ -66,7 +84,7 @@ module SimpleForm
66
84
 
67
85
  # How the label text should be generated altogether with the required text.
68
86
  mattr_accessor :label_text
69
- @@label_text = lambda { |label, required| "#{required} #{label}" }
87
+ @@label_text = lambda { |label, required, explicit_label| "#{required} #{label}" }
70
88
 
71
89
  # You can define the class to be used on all labels. Defaults to none.
72
90
  mattr_accessor :label_class
@@ -107,6 +125,8 @@ module SimpleForm
107
125
  # Custom wrappers for input types. This should be a hash containing an input
108
126
  # type as key and the wrapper that will be used for all inputs with specified type.
109
127
  # e.g { string: :string_wrapper, boolean: :boolean_wrapper }
128
+ # You can also set a wrapper mapping per form basis.
129
+ # e.g simple_form_for(@foo, wrapper_mappings: { check_boxes: :bootstrap_checkbox })
110
130
  mattr_accessor :wrapper_mappings
111
131
  @@wrapper_mappings = nil
112
132
 
@@ -151,15 +171,26 @@ module SimpleForm
151
171
  mattr_accessor :input_class
152
172
  @@input_class = nil
153
173
 
174
+ # Defines if an input wrapper class should be included or not
175
+ mattr_accessor :include_default_input_wrapper_class
176
+ @@include_default_input_wrapper_class = true
177
+
178
+ # Define the default class of the input wrapper of the boolean input.
179
+ mattr_accessor :boolean_label_class
180
+ @@boolean_label_class = 'checkbox'
181
+
154
182
  ## WRAPPER CONFIGURATION
155
183
  # The default wrapper to be used by the FormBuilder.
156
184
  mattr_accessor :default_wrapper
157
185
  @@default_wrapper = :default
158
- @@wrappers = {}
186
+ @@wrappers = {} #:nodoc:
187
+
188
+ mattr_accessor :i18n_scope
189
+ @@i18n_scope = 'simple_form'
159
190
 
160
191
  # Retrieves a given wrapper
161
192
  def self.wrapper(name)
162
- @@wrappers[name.to_sym] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
193
+ @@wrappers[name.to_s] or raise WrapperNotFound, "Couldn't find wrapper with name #{name}"
163
194
  end
164
195
 
165
196
  # Raised when fails to find a given wrapper name
@@ -172,14 +203,14 @@ module SimpleForm
172
203
  if block_given?
173
204
  options = args.extract_options!
174
205
  name = args.first || :default
175
- @@wrappers[name.to_sym] = build(options, &block)
206
+ @@wrappers[name.to_s] = build(options, &block)
176
207
  else
177
208
  @@wrappers
178
209
  end
179
210
  end
180
211
 
181
212
  # Builds a new wrapper using SimpleForm::Wrappers::Builder.
182
- def self.build(options={})
213
+ def self.build(options = {})
183
214
  options[:tag] = :div if options[:tag].nil?
184
215
  builder = SimpleForm::Wrappers::Builder.new(options)
185
216
  yield builder
@@ -210,9 +241,10 @@ module SimpleForm
210
241
  ActiveSupport::Deprecation.warn "[SIMPLE_FORM] SimpleForm.default_input_size= is deprecated and has no effect", caller
211
242
  end
212
243
 
213
- # Default way to setup SimpleForm. Run rails generate simple_form:install
244
+ # Default way to setup Simple Form. Run rails generate simple_form:install
214
245
  # to create a fresh initializer with all configuration values.
215
246
  def self.setup
247
+ @@configured = true
216
248
  yield self
217
249
  end
218
250
  end
@@ -8,13 +8,13 @@ class BuilderTest < ActionView::TestCase
8
8
  end
9
9
  end
10
10
 
11
- def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
11
+ def with_collection_radio_buttons(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
12
12
  with_concat_form_for(object) do |f|
13
13
  f.collection_radio_buttons attribute, collection, value_method, text_method, options, html_options, &block
14
14
  end
15
15
  end
16
16
 
17
- def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options={}, html_options={}, &block)
17
+ def with_collection_check_boxes(object, attribute, collection, value_method, text_method, options = {}, html_options = {}, &block)
18
18
  with_concat_form_for(object) do |f|
19
19
  f.collection_check_boxes attribute, collection, value_method, text_method, options, html_options, &block
20
20
  end
@@ -7,7 +7,7 @@ class IsolatedLabelTest < ActionView::TestCase
7
7
  SimpleForm::Inputs::Base.reset_i18n_cache :translate_required_html
8
8
  end
9
9
 
10
- def with_label_for(object, attribute_name, type, options={})
10
+ def with_label_for(object, attribute_name, type, options = {})
11
11
  with_concat_form_for(object) do |f|
12
12
  options[:reflection] = Association.new(Company, :company, {}) if options.delete(:setup_association)
13
13
  SimpleForm::Inputs::Base.new(f, attribute_name, nil, type, options).label
@@ -113,6 +113,14 @@ class AssociationTest < ActionView::TestCase
113
113
  assert_no_select 'form select option[value=3]'
114
114
  end
115
115
 
116
+ test 'builder allows collection to have a scope' do
117
+ with_association_for @user, :special_pictures
118
+ assert_select 'form select.select#user_special_picture_ids'
119
+ assert_select 'form select option[value=3]', '3'
120
+ assert_no_select 'form select option[value=1]'
121
+ assert_no_select 'form select option[value=2]'
122
+ end
123
+
116
124
  test 'builder marks the record which already belongs to the user' do
117
125
  @user.company_id = 2
118
126
  with_association_for @user, :company, as: :radio_buttons
@@ -146,6 +154,15 @@ class AssociationTest < ActionView::TestCase
146
154
  end
147
155
  end
148
156
 
157
+ test 'builder does not call order if the given association does not respond to it' do
158
+ with_association_for @user, :pictures
159
+ assert_select 'form select.select#user_picture_ids'
160
+ assert_select 'form select[multiple=multiple]'
161
+ assert_select 'form select option[value=1]', 'Picture 1'
162
+ assert_select 'form select option[value=2]', 'Picture 2'
163
+ assert_select 'form select option[value=3]', 'Picture 3'
164
+ end
165
+
149
166
  test 'builder creates a select with multiple options for collection associations' do
150
167
  with_association_for @user, :tags
151
168
  assert_select 'form select.select#user_tag_ids'
@@ -3,7 +3,7 @@ require 'test_helper'
3
3
 
4
4
  # Tests for f.error_notification
5
5
  class ErrorNotificationTest < ActionView::TestCase
6
- def with_error_notification_for(object, options={}, &block)
6
+ def with_error_notification_for(object, options = {}, &block)
7
7
  with_concat_form_for(object) do |f|
8
8
  f.error_notification(options)
9
9
  end
@@ -14,10 +14,6 @@ class ErrorTest < ActionView::TestCase
14
14
  end
15
15
  end
16
16
 
17
- def with_custom_error_for(object, *args)
18
- with_form_for(object, *args)
19
- end
20
-
21
17
  test 'error should not generate content for attribute without errors' do
22
18
  with_error_for @user, :active
23
19
  assert_no_select 'span.error'
@@ -36,7 +32,7 @@ class ErrorTest < ActionView::TestCase
36
32
 
37
33
  test 'error should generate messages for attribute with single error' do
38
34
  with_error_for @user, :name
39
- assert_select 'span.error', "can&#39;t be blank"
35
+ assert_select 'span.error', "can't be blank"
40
36
  end
41
37
 
42
38
  test 'error should generate messages for attribute with one error when using first' do
@@ -86,21 +82,12 @@ class ErrorTest < ActionView::TestCase
86
82
 
87
83
  test 'error should escape error prefix text' do
88
84
  with_error_for @user, :name, error_prefix: '<b>Name</b>'
89
- assert_select 'span.error', "&lt;b&gt;Name&lt;/b&gt; can&#39;t be blank"
90
- end
91
-
92
- test 'error escapes error text' do
93
- @user.errors.merge!(action: ['must not contain <b>markup</b>'])
94
-
95
- with_error_for @user, :action
96
-
97
- assert_select 'span.error'
98
- assert_no_select 'span.error b', 'markup'
85
+ assert_select 'span.error', "&lt;b&gt;Name&lt;/b&gt; can't be blank"
99
86
  end
100
87
 
101
88
  test 'error should generate an error message with raw HTML tags' do
102
89
  with_error_for @user, :name, error_prefix: '<b>Name</b>'.html_safe
103
- assert_select 'span.error', "Name can&#39;t be blank"
90
+ assert_select 'span.error', "Name can't be blank"
104
91
  assert_select 'span.error b', "Name"
105
92
  end
106
93
 
@@ -108,7 +95,7 @@ class ErrorTest < ActionView::TestCase
108
95
 
109
96
  test 'full error should generate an full error tag for the attribute' do
110
97
  with_full_error_for @user, :name
111
- assert_select 'span.error', "Super User Name! can&#39;t be blank"
98
+ assert_select 'span.error', "Super User Name! can't be blank"
112
99
  end
113
100
 
114
101
  test 'full error should generate an full error tag with a clean HTML' do
@@ -118,13 +105,13 @@ class ErrorTest < ActionView::TestCase
118
105
 
119
106
  test 'full error should allow passing options to full error tag' do
120
107
  with_full_error_for @user, :name, id: 'name_error', error_prefix: "Your name"
121
- assert_select 'span.error#name_error', "Your name can&#39;t be blank"
108
+ assert_select 'span.error#name_error', "Your name can't be blank"
122
109
  end
123
110
 
124
111
  test 'full error should not modify the options hash' do
125
112
  options = { id: 'name_error' }
126
113
  with_full_error_for @user, :name, options
127
- assert_select 'span.error#name_error', "Super User Name! can&#39;t be blank"
114
+ assert_select 'span.error#name_error', "Super User Name! can't be blank"
128
115
  assert_equal({ id: 'name_error' }, options)
129
116
  end
130
117
 
@@ -133,36 +120,68 @@ class ErrorTest < ActionView::TestCase
133
120
  test 'error with custom wrappers works' do
134
121
  swap_wrapper do
135
122
  with_error_for @user, :name
136
- assert_select 'span.omg_error', "can&#39;t be blank"
123
+ assert_select 'span.omg_error', "can't be blank"
124
+ end
125
+ end
126
+
127
+ # FULL_ERROR_WRAPPER
128
+
129
+ test 'full error should find errors on association' do
130
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
131
+ with_form_for @user, :company_id, as: :select
132
+ assert_select 'span.error', 'Company must be valid'
133
+ end
134
+ end
135
+
136
+ test 'full error can be disabled' do
137
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
138
+ with_form_for @user, :company_id, as: :select, full_error: false
139
+ assert_no_select 'span.error'
140
+ end
141
+ end
142
+
143
+ test 'full error can be disabled setting error to false' do
144
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
145
+ with_form_for @user, :company_id, as: :select, error: false
146
+ assert_no_select 'span.error'
137
147
  end
138
148
  end
139
149
 
140
150
  # CUSTOM ERRORS
141
151
 
142
152
  test 'input with custom error works' do
143
- with_custom_error_for(@user, :name, error: "Super User Name! can't be blank")
153
+ error_text = "Super User Name! can't be blank"
154
+ with_form_for @user, :name, error: error_text
144
155
 
145
- assert_select 'span.error', "Super User Name! can&#39;t be blank"
156
+ assert_select 'span.error', error_text
157
+ end
158
+
159
+ test 'input with error option as true does not use custom error' do
160
+ with_form_for @user, :name, error: true
161
+
162
+ assert_select 'span.error', "can't be blank"
146
163
  end
147
164
 
148
165
  test 'input with custom error does not generate the error if there is no error on the attribute' do
149
- error_text = "Super User Active! can't be blank"
150
- with_form_for @user, :active, error: error_text
166
+ with_form_for @user, :active, error: "Super User Active! can't be blank"
151
167
 
152
168
  assert_no_select 'span.error'
153
169
  end
154
170
 
155
- test 'input with custom error escapes the error text' do
156
- with_form_for @user, :name, error: 'error must not contain <b>markup</b>'
171
+ test 'input with custom error works when using full_error component' do
172
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
173
+ error_text = "Super User Name! can't be blank"
174
+ with_form_for @user, :name, error: error_text
157
175
 
158
- assert_select 'span.error'
159
- assert_no_select 'span.error b', 'markup'
176
+ assert_select 'span.error', error_text
177
+ end
160
178
  end
161
179
 
162
- test 'input with custom error does not escape the error text if it is safe' do
163
- with_form_for @user, :name, error: 'error must contain <b>markup</b>'.html_safe
180
+ test 'input with custom error when using full_error component does not generate the error if there is no error on the attribute' do
181
+ swap_wrapper :default, self.custom_wrapper_with_full_error do
182
+ with_form_for @user, :active, error: "Super User Active! can't be blank"
164
183
 
165
- assert_select 'span.error'
166
- assert_select 'span.error b', 'markup'
184
+ assert_no_select 'span.error'
185
+ end
167
186
  end
168
187
  end
@@ -302,7 +302,7 @@ class FormBuilderTest < ActionView::TestCase
302
302
 
303
303
  test 'builder should generate errors for attribute with errors' do
304
304
  with_form_for @user, :name
305
- assert_select 'span.error', "can&#39;t be blank"
305
+ assert_select 'span.error', "can't be blank"
306
306
  end
307
307
 
308
308
  test 'builder should be able to disable showing errors for a input' do
@@ -312,7 +312,7 @@ class FormBuilderTest < ActionView::TestCase
312
312
 
313
313
  test 'builder should pass options to errors' do
314
314
  with_form_for @user, :name, error_html: { id: "cool" }
315
- assert_select 'span.error#cool', "can&#39;t be blank"
315
+ assert_select 'span.error#cool', "can't be blank"
316
316
  end
317
317
 
318
318
  test 'placeholder should not be generated when set to false' do