caring_form 1.2.3
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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +17 -0
- data/Appraisals +18 -0
- data/Gemfile +9 -0
- data/Guardfile +15 -0
- data/LICENSE +22 -0
- data/README.md +33 -0
- data/Rakefile +12 -0
- data/app/assets/javascripts/caring_form/form-observer.coffee +63 -0
- data/app/assets/javascripts/caring_form/main.coffee +15 -0
- data/app/assets/javascripts/caring_form/remote-validator.coffee +71 -0
- data/app/assets/javascripts/caring_form/rule-based-validator.coffee +37 -0
- data/app/assets/javascripts/caring_form/setup.coffee +5 -0
- data/app/assets/javascripts/caring_form/webshims-customization.coffee +25 -0
- data/app/assets/javascripts/caring_forms.js +7 -0
- data/caring_form.gemspec +31 -0
- data/gemfiles/rails_3_1.gemfile +8 -0
- data/gemfiles/rails_3_2.gemfile +8 -0
- data/gemfiles/rails_4.gemfile +7 -0
- data/gemfiles/rails_4_1.gemfile +8 -0
- data/lib/caring_form.rb +20 -0
- data/lib/caring_form/action_view_extensions/builder.rb +75 -0
- data/lib/caring_form/action_view_extensions/config.rb +4 -0
- data/lib/caring_form/action_view_extensions/flash_error_helper.rb +28 -0
- data/lib/caring_form/action_view_extensions/form_helper.rb +33 -0
- data/lib/caring_form/active_model/monkey_patching.rb +32 -0
- data/lib/caring_form/dsl.rb +91 -0
- data/lib/caring_form/engine.rb +4 -0
- data/lib/caring_form/field/base.rb +145 -0
- data/lib/caring_form/field/check_box.rb +23 -0
- data/lib/caring_form/field/check_boxes.rb +15 -0
- data/lib/caring_form/field/collection.rb +48 -0
- data/lib/caring_form/field/dummy.rb +30 -0
- data/lib/caring_form/field/email.rb +41 -0
- data/lib/caring_form/field/full_name.rb +40 -0
- data/lib/caring_form/field/looking_for.rb +37 -0
- data/lib/caring_form/field/metadata.rb +26 -0
- data/lib/caring_form/field/radio_buttons.rb +15 -0
- data/lib/caring_form/field/string.rb +13 -0
- data/lib/caring_form/field/submit.rb +83 -0
- data/lib/caring_form/field/tel.rb +37 -0
- data/lib/caring_form/field/text.rb +13 -0
- data/lib/caring_form/field/us_zip_code.rb +37 -0
- data/lib/caring_form/field_container.rb +126 -0
- data/lib/caring_form/form_builder.rb +51 -0
- data/lib/caring_form/model.rb +58 -0
- data/lib/caring_form/model/active_model.rb +11 -0
- data/lib/caring_form/model/active_record.rb +38 -0
- data/lib/caring_form/simple_form/initializer.rb +26 -0
- data/lib/caring_form/simple_form/monkey_patching.rb +51 -0
- data/lib/caring_form/tools/referee.rb +62 -0
- data/lib/caring_form/version.rb +3 -0
- data/lib/tasks/webshims.rake +7 -0
- data/spec/caring_form/action_view_extensions/flash_error_helper_spec.rb +50 -0
- data/spec/caring_form/action_view_extensions/form_helper_spec.rb +72 -0
- data/spec/caring_form/dsl_spec.rb +21 -0
- data/spec/caring_form/field/base_spec.rb +204 -0
- data/spec/caring_form/field/check_boxes_spec.rb +32 -0
- data/spec/caring_form/field/collection_spec.rb +28 -0
- data/spec/caring_form/field/radio_buttons_spec.rb +29 -0
- data/spec/caring_form/field/submit_spec.rb +57 -0
- data/spec/caring_form/field_container_spec.rb +85 -0
- data/spec/caring_form/form_builder_spec.rb +113 -0
- data/spec/caring_form/model_spec.rb +235 -0
- data/spec/caring_form/tools/referee_spec.rb +86 -0
- data/spec/spec_helper.rb +28 -0
- data/spec/support/nokogiri_matcher.rb +204 -0
- metadata +278 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
module CaringForm
|
|
2
|
+
module FieldContainer
|
|
3
|
+
def self.register_field(klass, type)
|
|
4
|
+
@registered_fields ||= {}
|
|
5
|
+
@registered_fields[type] = klass
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def self.field_for(type)
|
|
9
|
+
@registered_fields[type]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.custom_field_mapping
|
|
13
|
+
{
|
|
14
|
+
:full_name => :string,
|
|
15
|
+
:email => :string,
|
|
16
|
+
:tel => :string,
|
|
17
|
+
:us_zip_code => :string,
|
|
18
|
+
:dummy => :string,
|
|
19
|
+
:looking_for => :select,
|
|
20
|
+
:metadata => :hidden
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.included(klass)
|
|
25
|
+
klass.instance_eval do
|
|
26
|
+
extend ClassMethods
|
|
27
|
+
class << self
|
|
28
|
+
class_attribute :fields
|
|
29
|
+
end
|
|
30
|
+
self.fields = ActiveSupport::OrderedHash.new
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def field_names(&block)
|
|
35
|
+
self.class.field_names(&block)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def field_definitions
|
|
39
|
+
self.class.fields.values.dup
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def field_id(name)
|
|
43
|
+
if (field = self.class.fields[name])
|
|
44
|
+
id = field.input_html[:id] || default_field_id(field)
|
|
45
|
+
else
|
|
46
|
+
nil
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def default_field_id(field)
|
|
51
|
+
[sanitized_form_name, index_on, field.name].compact.join('_')
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def normalize_attribute_value(name, value)
|
|
55
|
+
return value unless (field = self.class.fields[name.to_sym])
|
|
56
|
+
case
|
|
57
|
+
when field.type == :check_box && value.is_a?(Array)
|
|
58
|
+
value.last
|
|
59
|
+
else
|
|
60
|
+
value
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def sanitized_form_name
|
|
67
|
+
underscored_form_name = self.class.model_name.to_s.underscore
|
|
68
|
+
underscored_form_name.gsub(/\]\[|[^-a-zA-Z0-9:.]/, "_").sub(/_$/, "")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
module ClassMethods
|
|
72
|
+
def field(name, options = {})
|
|
73
|
+
if (not_supported = options.keys - CaringForm::Field.field_attributes).present?
|
|
74
|
+
raise Error.new("CaringForm::Dsl.field: #{not_supported.join(', ')} not supported")
|
|
75
|
+
end
|
|
76
|
+
supported_option_names = CaringForm::Field.field_attributes
|
|
77
|
+
values = options.values_at(*supported_option_names)
|
|
78
|
+
if options[:type] == :submit
|
|
79
|
+
field = new_field(:submit, *values)
|
|
80
|
+
field.properties = Array(name)
|
|
81
|
+
name = :submit
|
|
82
|
+
else
|
|
83
|
+
field = new_field(name, *values)
|
|
84
|
+
field.apply_to_model(self)
|
|
85
|
+
end
|
|
86
|
+
@fields[name.to_sym] = field
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def field_names(&block)
|
|
90
|
+
real_fields = fields.reject { |_, field| field.kind_of?(CaringForm::Field::Submit) }
|
|
91
|
+
return real_fields.keys.map(&:to_s) unless block_given?
|
|
92
|
+
selected = real_fields.select(&block)
|
|
93
|
+
# ruby 1.8 returns an array, 1.9 returns a hash
|
|
94
|
+
keys = selected.is_a?(Array) ? selected.map(&:first) : selected.keys
|
|
95
|
+
keys.map(&:to_s)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def inherited(subclass)
|
|
99
|
+
subclass.fields = self.fields.dup
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private
|
|
103
|
+
|
|
104
|
+
def new_field(name, type, *values)
|
|
105
|
+
klass = CaringForm::FieldContainer.field_for(type)
|
|
106
|
+
values.unshift(type)
|
|
107
|
+
klass.new(name, *values)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
require 'caring_form/field/string'
|
|
114
|
+
require 'caring_form/field/text'
|
|
115
|
+
require 'caring_form/field/collection'
|
|
116
|
+
require 'caring_form/field/looking_for'
|
|
117
|
+
require 'caring_form/field/check_boxes'
|
|
118
|
+
require 'caring_form/field/check_box'
|
|
119
|
+
require 'caring_form/field/radio_buttons'
|
|
120
|
+
require 'caring_form/field/metadata'
|
|
121
|
+
require 'caring_form/field/full_name'
|
|
122
|
+
require 'caring_form/field/email'
|
|
123
|
+
require 'caring_form/field/tel'
|
|
124
|
+
require 'caring_form/field/us_zip_code'
|
|
125
|
+
require 'caring_form/field/dummy'
|
|
126
|
+
require 'caring_form/field/submit'
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module CaringForm
|
|
2
|
+
class TextFieldInlineErrorField < SimpleForm::Inputs::CommonTextInput
|
|
3
|
+
def input
|
|
4
|
+
super.html_safe + '<div class="inline-error" style="display: none"></div>'.html_safe
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class FormBuilder
|
|
9
|
+
def initialize(*args)
|
|
10
|
+
@form = args[1]
|
|
11
|
+
@builder = SimpleForm::FormBuilder.new(*args)
|
|
12
|
+
@builder.class.mappings[:string_inline_error] = TextFieldInlineErrorField
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def metadata(options = {})
|
|
16
|
+
field(:all, options.merge(:filter_type => [:metadata, :dummy]))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def fields(options = {}, &block)
|
|
20
|
+
tag = options.delete(:tag) || :ol
|
|
21
|
+
@builder.template.content_tag(tag, options, &block)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def field(*names)
|
|
25
|
+
options = names.extract_options!
|
|
26
|
+
html_list = select_fields!(names, options).map do |field|
|
|
27
|
+
field.render(@form, @builder, options)
|
|
28
|
+
end
|
|
29
|
+
html_list.join("\n").html_safe
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def method_missing(meth, *args, &blk)
|
|
33
|
+
return super unless @builder.respond_to?(meth)
|
|
34
|
+
@builder.send(meth, *args, &blk)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def select_fields!(names, options)
|
|
40
|
+
names = @form.field_names.map(&:to_sym) + [:submit] if names == [:all]
|
|
41
|
+
if options.has_key?(:except)
|
|
42
|
+
names -= Array(options.delete(:except))
|
|
43
|
+
end
|
|
44
|
+
types = Array(options.delete(:filter_type)) if options.has_key?(:filter_type)
|
|
45
|
+
@form.field_definitions.select do |field|
|
|
46
|
+
next false unless names.include?(field.name)
|
|
47
|
+
types.nil? ? true : types.include?(field.type)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'caring_form/dsl'
|
|
2
|
+
|
|
3
|
+
module CaringForm
|
|
4
|
+
class Model
|
|
5
|
+
INHERITED_ATTRIBUTES = [:url, :id, :classes]
|
|
6
|
+
attr_accessor *INHERITED_ATTRIBUTES
|
|
7
|
+
|
|
8
|
+
def self.inherited(klass)
|
|
9
|
+
klass.instance_eval do
|
|
10
|
+
include CaringForm::Dsl
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# attributes can be scoped within key of the name of the class (posted form)
|
|
15
|
+
# or a flat hash of attributes
|
|
16
|
+
def initialize(attributes = {})
|
|
17
|
+
flatten_attributes(attributes).each do |name, value|
|
|
18
|
+
send("#{name}=", normalize_attribute_value(name, value)) if respond_to?(name)
|
|
19
|
+
end
|
|
20
|
+
(INHERITED_ATTRIBUTES - attributes.keys).each do |name|
|
|
21
|
+
value = self.class.send(name)
|
|
22
|
+
send("#{name}=", value) unless value.nil?
|
|
23
|
+
end
|
|
24
|
+
after_initialize
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def after_initialize
|
|
28
|
+
# override if needed
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def normalize_attribute_value(name, value)
|
|
32
|
+
value
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def flatten_attributes(raw_attributes)
|
|
38
|
+
attributes = raw_attributes.symbolize_keys
|
|
39
|
+
scope_key = self.class.model_name.to_s.underscore.to_sym
|
|
40
|
+
# flatten scoped attributes if any
|
|
41
|
+
if attributes.has_key?(scope_key)
|
|
42
|
+
scoped = attributes.delete(scope_key)
|
|
43
|
+
if (index_on_name = self.class.index_on)
|
|
44
|
+
index = attributes[index_on_name]
|
|
45
|
+
scoped = scoped[index]
|
|
46
|
+
end
|
|
47
|
+
attributes.merge!(scoped.respond_to?(:merge) ? scoped : {})
|
|
48
|
+
end
|
|
49
|
+
attributes
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
if defined?(ActiveModel)
|
|
55
|
+
require 'caring_form/model/active_model'
|
|
56
|
+
else
|
|
57
|
+
require 'caring_form/model/active_record'
|
|
58
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module CaringForm
|
|
2
|
+
class Model
|
|
3
|
+
attr_accessor :errors
|
|
4
|
+
|
|
5
|
+
def self.human_name
|
|
6
|
+
to_s.humanize
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def self.human_attribute_name(attribute)
|
|
10
|
+
attribute.to_s.humanize
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.self_and_descendants_from_active_record
|
|
14
|
+
[self]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def save
|
|
18
|
+
# TODO
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def save!
|
|
22
|
+
# TODO
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def new_record?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def update_attribute
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
include ActiveRecord::Validations
|
|
33
|
+
|
|
34
|
+
def after_initialize
|
|
35
|
+
@errors = ActiveRecord::Errors.new(self)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# TODO: support only SimpleForm 2.x+ once we upgrade all our apps to Rails 3.2
|
|
2
|
+
|
|
3
|
+
require 'simple_form'
|
|
4
|
+
|
|
5
|
+
SimpleForm.setup do |config|
|
|
6
|
+
|
|
7
|
+
if config.respond_to?(:wrappers)
|
|
8
|
+
# SimpleForm 2+
|
|
9
|
+
config.wrappers :tag => :div do |b|
|
|
10
|
+
b.use :label
|
|
11
|
+
b.use :input
|
|
12
|
+
b.use :hint, :wrap_with => {:tag => :p, :class => 'hint'}
|
|
13
|
+
end
|
|
14
|
+
else
|
|
15
|
+
# SimpleForm 1
|
|
16
|
+
config.components = [ :label, :input, :hint ]
|
|
17
|
+
config.wrapper_tag = :div
|
|
18
|
+
config.hint_tag = :p
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Common
|
|
22
|
+
config.label_text = lambda { |label, required, explicit_label = nil|
|
|
23
|
+
"#{label}#{required.empty? ? ' <span class="opt">(optional)</span>' : ''}"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'simple_form'
|
|
2
|
+
|
|
3
|
+
module SimpleForm
|
|
4
|
+
module Inputs
|
|
5
|
+
CommonTextInput = if defined?(TextFieldInput)
|
|
6
|
+
TextFieldInput
|
|
7
|
+
elsif defined?(StringInput)
|
|
8
|
+
StringInput
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
Base.class_eval do
|
|
12
|
+
alias :orig_html_options_for :html_options_for
|
|
13
|
+
def html_options_for(*args)
|
|
14
|
+
orig_html_options_for(*args).tap do |options|
|
|
15
|
+
if options[:class] && options[:class].respond_to?(:split)
|
|
16
|
+
options[:class] = options[:class].split(' ').uniq.join(' ')
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
classes = [Base]
|
|
23
|
+
classes << CollectionRadioButtonsInput if defined?(CollectionRadioButtonsInput)
|
|
24
|
+
classes.each do |klass|
|
|
25
|
+
klass.class_eval do
|
|
26
|
+
alias :orig_input :input
|
|
27
|
+
def input(wrapper_options = nil)
|
|
28
|
+
options = input_html_options
|
|
29
|
+
wrapper = options.delete(:wrapper)
|
|
30
|
+
wrapper.nil? ? orig_input : template.content_tag(wrapper, orig_input)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# TODO: make something like below work instead...
|
|
38
|
+
#
|
|
39
|
+
# module CaringForm
|
|
40
|
+
# module CanWrapInputField
|
|
41
|
+
# def input
|
|
42
|
+
# options = input_html_options
|
|
43
|
+
# wrapper = options.delete(:wrapper)
|
|
44
|
+
# content = super
|
|
45
|
+
# wrapper.nil? ? content : template.content_tag(wrapper, content)
|
|
46
|
+
# end
|
|
47
|
+
# end
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
# SimpleForm::Inputs::TextFieldInput.send(:include, CaringForm::CanWrapInputField)
|
|
51
|
+
# SimpleForm::Inputs::CollectionInput.send(:include, CaringForm::CanWrapInputField)
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module CaringForm
|
|
2
|
+
module Tools
|
|
3
|
+
# A referee is a tool used to execute rules stored in a field attribute
|
|
4
|
+
# against value(s) retrieved from a form instance. The referee decides
|
|
5
|
+
# if the rule is true or false for the form instance.
|
|
6
|
+
#
|
|
7
|
+
# i.e.:
|
|
8
|
+
# field = OpenStruct.new(:optional => {:absent => :band_name})
|
|
9
|
+
# form = OpenStruct.new(:band_name => "")
|
|
10
|
+
# referee = Tools::Referee.new(field)
|
|
11
|
+
#
|
|
12
|
+
# # We want to know if the field is optional
|
|
13
|
+
# referee.decide(:optional, form) # => true, because the band name is absent
|
|
14
|
+
# form.band_name = "Everything But The Girl"
|
|
15
|
+
# referee.decide(:optional, form) # => false, now that there is a band name, the field is not optional anymore
|
|
16
|
+
#
|
|
17
|
+
# # We also need to verify that on the front-end, so the referee can translate
|
|
18
|
+
# # the rule into a data attribute key value pair
|
|
19
|
+
# def form.field_id(name); "form_name_index_#{name}"; end
|
|
20
|
+
# referee.rule_as_data_attribute(:optional, form) # => data-optional-if-absent="#form_name_index_band_name"
|
|
21
|
+
class Referee
|
|
22
|
+
def initialize(field)
|
|
23
|
+
@field = field
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def decide(property, form)
|
|
27
|
+
case (value = @field.send(property))
|
|
28
|
+
when true then true
|
|
29
|
+
when false then false
|
|
30
|
+
else
|
|
31
|
+
execute_rule(value, form)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def execute_rule(rule, form)
|
|
36
|
+
type = rule.keys.first
|
|
37
|
+
attribute = rule[type]
|
|
38
|
+
case type
|
|
39
|
+
when :absent then form.send(attribute).blank?
|
|
40
|
+
when :present then form.send(attribute).present?
|
|
41
|
+
else
|
|
42
|
+
false
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def is_rule?(property)
|
|
47
|
+
@field.send(property).is_a?(Hash)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def rule_as_data_attribute(property, form)
|
|
51
|
+
rule = @field.send(property)
|
|
52
|
+
if rule.respond_to?(:keys) && (type = rule.keys.first)
|
|
53
|
+
name = :"data-#{property}-if-#{type}"
|
|
54
|
+
id = "##{form.field_id(rule[type])}"
|
|
55
|
+
{name => id}
|
|
56
|
+
else
|
|
57
|
+
{}
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
require 'fileutils'
|
|
2
|
+
|
|
3
|
+
desc "Copy the webshims to public so dynamic features will work. Only needs to run when caring_form updates the webshims."
|
|
4
|
+
task "webshims:update_public" do
|
|
5
|
+
shim_root = Webshims::Rails::Engine.root.join('vendor', 'assets', 'javascripts', 'webshims')
|
|
6
|
+
FileUtils.cp_r(shim_root, Rails.root.join("public/webshims"))
|
|
7
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
|
2
|
+
|
|
3
|
+
require 'caring_form'
|
|
4
|
+
|
|
5
|
+
class FlashForm < CaringForm::Model
|
|
6
|
+
url '/'
|
|
7
|
+
string :name, :required_message => "Enter your name"
|
|
8
|
+
string :age, :required_message => "Enter your age as a number"
|
|
9
|
+
|
|
10
|
+
validates_numericality_of :age,
|
|
11
|
+
:greater_than_or_equal_to => 0,
|
|
12
|
+
:only_integer => true,
|
|
13
|
+
:allow_blank => true,
|
|
14
|
+
:message => "Age must be a number"
|
|
15
|
+
|
|
16
|
+
on_error :header => "flash header",
|
|
17
|
+
:message => "flash message"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
MiniTest::Spec.register_spec_type(/CaringForm::ActionViewExtensions::FlashErrorHelper$/, ControllerSpec)
|
|
21
|
+
|
|
22
|
+
describe CaringForm::ActionViewExtensions::FlashErrorHelper do
|
|
23
|
+
it "renders a flash error if the form is not valid" do
|
|
24
|
+
view = caring_form_errors_for(FlashForm.new)
|
|
25
|
+
html_matcher('.flash.error > h2').must_be :matching, view
|
|
26
|
+
html_matcher('.flash.error > .flash-close').must_be :matching, view
|
|
27
|
+
html_matcher('.flash.error > .message').must_be :matching, view
|
|
28
|
+
html_matcher('.flash.error > .message > ul').must_be :matching, view
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "doesn't render a flash error if the form is valid" do
|
|
32
|
+
form = FlashForm.new(:name => "Zhanna", :age => "30")
|
|
33
|
+
caring_form_errors_for(form).must_equal ''
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it "renders the header setup with #error_for" do
|
|
37
|
+
view = caring_form_errors_for(FlashForm.new)
|
|
38
|
+
html_matcher('.flash.error > h2', :text => "flash header").must_be :matching, view
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "renders a list of all the error messages" do
|
|
42
|
+
view = caring_form_errors_for(FlashForm.new)
|
|
43
|
+
html_matcher(
|
|
44
|
+
'.flash.error > .message li', :text => "Enter your name"
|
|
45
|
+
).must_be :matching, view
|
|
46
|
+
html_matcher(
|
|
47
|
+
'.flash.error > .message li', :text => "Enter your age as a number"
|
|
48
|
+
).must_be :matching, view
|
|
49
|
+
end
|
|
50
|
+
end
|