active_form 0.0.1
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.
- data.tar.gz.sig +2 -0
- data/History.txt +4 -0
- data/License.txt +20 -0
- data/MIT-LICENSE +19 -0
- data/Manifest.txt +181 -0
- data/README.txt +1 -0
- data/Rakefile +4 -0
- data/config/hoe.rb +71 -0
- data/config/requirements.rb +17 -0
- data/init.rb +5 -0
- data/lib/active_form.rb +86 -0
- data/lib/active_form/core_extensions.rb +179 -0
- data/lib/active_form/definition.rb +72 -0
- data/lib/active_form/element.rb +50 -0
- data/lib/active_form/elements/base.rb +67 -0
- data/lib/active_form/elements/builder.rb +103 -0
- data/lib/active_form/elements/button.rb +15 -0
- data/lib/active_form/elements/checkbox.rb +18 -0
- data/lib/active_form/elements/file.rb +15 -0
- data/lib/active_form/elements/hidden.rb +9 -0
- data/lib/active_form/elements/image.rb +7 -0
- data/lib/active_form/elements/input.rb +23 -0
- data/lib/active_form/elements/password.rb +12 -0
- data/lib/active_form/elements/radio.rb +18 -0
- data/lib/active_form/elements/reset.rb +15 -0
- data/lib/active_form/elements/section.rb +37 -0
- data/lib/active_form/elements/select.rb +42 -0
- data/lib/active_form/elements/submit.rb +19 -0
- data/lib/active_form/elements/text.rb +9 -0
- data/lib/active_form/elements/textarea.rb +18 -0
- data/lib/active_form/errors.rb +73 -0
- data/lib/active_form/facets/checkbox_group.rb +11 -0
- data/lib/active_form/facets/collection_input.rb +96 -0
- data/lib/active_form/facets/radio_group.rb +11 -0
- data/lib/active_form/facets/select_date.rb +10 -0
- data/lib/active_form/facets/select_datetime.rb +10 -0
- data/lib/active_form/facets/select_day.rb +17 -0
- data/lib/active_form/facets/select_from_model.rb +60 -0
- data/lib/active_form/facets/select_hour.rb +17 -0
- data/lib/active_form/facets/select_minute.rb +17 -0
- data/lib/active_form/facets/select_month.rb +46 -0
- data/lib/active_form/facets/select_numeric_range.rb +59 -0
- data/lib/active_form/facets/select_second.rb +17 -0
- data/lib/active_form/facets/select_time.rb +10 -0
- data/lib/active_form/facets/select_timebased.rb +145 -0
- data/lib/active_form/facets/select_weekday.rb +46 -0
- data/lib/active_form/facets/select_year.rb +24 -0
- data/lib/active_form/mixins/attribute_methods.rb +33 -0
- data/lib/active_form/mixins/casting.rb +152 -0
- data/lib/active_form/mixins/collection_element_methods.rb +204 -0
- data/lib/active_form/mixins/common_methods.rb +350 -0
- data/lib/active_form/mixins/container_methods.rb +417 -0
- data/lib/active_form/mixins/css_methods.rb +70 -0
- data/lib/active_form/mixins/element_methods.rb +314 -0
- data/lib/active_form/mixins/javascript_methods.rb +99 -0
- data/lib/active_form/mixins/loader_methods.rb +72 -0
- data/lib/active_form/mixins/option_element_methods.rb +61 -0
- data/lib/active_form/mixins/validation_methods.rb +253 -0
- data/lib/active_form/validator.rb +47 -0
- data/lib/active_form/validators/alpha.rb +9 -0
- data/lib/active_form/validators/alphanum.rb +9 -0
- data/lib/active_form/validators/base.rb +132 -0
- data/lib/active_form/validators/digits.rb +9 -0
- data/lib/active_form/validators/email.rb +29 -0
- data/lib/active_form/validators/format.rb +15 -0
- data/lib/active_form/validators/length_range.rb +24 -0
- data/lib/active_form/validators/number.rb +9 -0
- data/lib/active_form/validators/option_count.rb +24 -0
- data/lib/active_form/validators/proc.rb +22 -0
- data/lib/active_form/validators/required.rb +9 -0
- data/lib/active_form/validators/set.rb +21 -0
- data/lib/active_form/validators/time_range.rb +30 -0
- data/lib/active_form/validators/uri.rb +54 -0
- data/lib/active_form/version.rb +9 -0
- data/lib/active_form/views/fieldsets.rb +34 -0
- data/lib/active_form/views/plain.rb +32 -0
- data/lib/active_form/views/tables.rb +28 -0
- data/lib/active_form/widget.rb +43 -0
- data/lib/active_form/widgets/base.rb +28 -0
- data/lib/loob/uri_validator.rb +140 -0
- data/lib/rails/acts_as_dropdown/MIT-LICENSE +20 -0
- data/lib/rails/acts_as_dropdown/acts_as_dropdown.rb +119 -0
- data/lib/rails/acts_as_dropdown/dropdown.rb +27 -0
- data/lib/rails/controller_helper.rb +19 -0
- data/lib/rails/model/loader.rb +206 -0
- data/lib/rails/view_helper.rb +20 -0
- data/samples/html/css/style.css +175 -0
- data/samples/html/js/effects.js +958 -0
- data/samples/html/js/prototype.js +2006 -0
- data/samples/html/js/validation.js +228 -0
- data/samples/html/plain_view.html +77 -0
- data/samples/html/sample001.html +158 -0
- data/samples/html/sample002.html +76 -0
- data/samples/html/sample003.html +34 -0
- data/samples/layouts/default.rhtml +18 -0
- data/samples/layouts/plain.rhtml +21 -0
- data/samples/layouts/sample003.rhtml +25 -0
- data/samples/plain_view.rb +58 -0
- data/samples/sample001.rb +111 -0
- data/samples/sample002.rb +92 -0
- data/samples/sample003.rb +30 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/script/txt2html +74 -0
- data/setup.rb +1585 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/website.rake +17 -0
- data/test/elements/test_base_element.rb +159 -0
- data/test/elements/test_builder_element.rb +81 -0
- data/test/elements/test_button_element.rb +12 -0
- data/test/elements/test_checkbox_element.rb +233 -0
- data/test/elements/test_file_element.rb +20 -0
- data/test/elements/test_hidden_element.rb +11 -0
- data/test/elements/test_image_element.rb +11 -0
- data/test/elements/test_input_element.rb +39 -0
- data/test/elements/test_password_element.rb +16 -0
- data/test/elements/test_radio_element.rb +197 -0
- data/test/elements/test_reset_element.rb +12 -0
- data/test/elements/test_section_element.rb +162 -0
- data/test/elements/test_select_element.rb +364 -0
- data/test/elements/test_submit_element.rb +12 -0
- data/test/elements/test_text_element.rb +91 -0
- data/test/elements/test_textarea_element.rb +23 -0
- data/test/facets/test_checkbox_group_element.rb +388 -0
- data/test/facets/test_radio_group_element.rb +312 -0
- data/test/facets/test_select_date_element.rb +211 -0
- data/test/facets/test_select_datetime_element.rb +56 -0
- data/test/facets/test_select_day_element.rb +37 -0
- data/test/facets/test_select_from_model_element.rb +86 -0
- data/test/facets/test_select_hour_element.rb +37 -0
- data/test/facets/test_select_minute_element.rb +52 -0
- data/test/facets/test_select_month_element.rb +79 -0
- data/test/facets/test_select_numeric_range_element.rb +14 -0
- data/test/facets/test_select_second_element.rb +48 -0
- data/test/facets/test_select_time_element.rb +148 -0
- data/test/facets/test_select_weekday_element.rb +71 -0
- data/test/facets/test_select_year_element.rb +73 -0
- data/test/fixtures/author.rb +11 -0
- data/test/fixtures/authors.yml +0 -0
- data/test/fixtures/book.rb +14 -0
- data/test/fixtures/books.yml +8 -0
- data/test/fixtures/categories.yml +0 -0
- data/test/fixtures/categorization.rb +2 -0
- data/test/fixtures/categorizations.yml +0 -0
- data/test/fixtures/category.rb +8 -0
- data/test/fixtures/publisher.rb +5 -0
- data/test/fixtures/publishers.yml +10 -0
- data/test/fixtures/schema.rb +43 -0
- data/test/rails/test_model_autodefinition.rb +121 -0
- data/test/rails/test_model_loader.rb +61 -0
- data/test/resources/elements/chunky.rb +11 -0
- data/test/resources/forms/demo.rb +5 -0
- data/test/resources/models/book.rb +8 -0
- data/test/resources/models/register_publisher.rb +5 -0
- data/test/resources/sections/demo.rb +6 -0
- data/test/resources/sections/foo.rb +6 -0
- data/test/resources/validators/foo.rb +9 -0
- data/test/resources/widgets/custom.rb +13 -0
- data/test/test_active_form.rb +1050 -0
- data/test/test_casting.rb +124 -0
- data/test/test_definition.rb +68 -0
- data/test/test_definition_class.rb +118 -0
- data/test/test_element_class.rb +201 -0
- data/test/test_helper.rb +74 -0
- data/test/test_javascript.rb +234 -0
- data/test/test_load_definition.rb +68 -0
- data/test/test_load_element.rb +35 -0
- data/test/test_load_section_element.rb +43 -0
- data/test/test_load_validator.rb +31 -0
- data/test/test_load_widget.rb +93 -0
- data/test/test_validation.rb +722 -0
- data/test/validators/test_validates_as_alpha.rb +26 -0
- data/test/validators/test_validates_as_alphanum.rb +26 -0
- data/test/validators/test_validates_as_digits.rb +26 -0
- data/test/validators/test_validates_as_email.rb +29 -0
- data/test/validators/test_validates_as_number.rb +26 -0
- data/test/validators/test_validates_as_uri.rb +128 -0
- data/test/validators/test_validates_with_format.rb +26 -0
- data/test/validators/test_validates_within_length_range.rb +46 -0
- data/test/validators/test_validates_within_set.rb +46 -0
- data/test/validators/test_validates_within_time_range.rb +53 -0
- metadata +307 -0
- metadata.gz.sig +4 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestLoadValidator < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
ActiveForm::Validator.load_paths << File.join(File.dirname(__FILE__), 'resources', 'validators')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_load_paths
|
|
10
|
+
assert_equal 2, ActiveForm::Validator.load_paths.length
|
|
11
|
+
assert File.directory?(ActiveForm::Validator.load_paths.first)
|
|
12
|
+
assert File.directory?(ActiveForm::Validator.load_paths.last)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_assign_and_use_validator
|
|
16
|
+
form = ActiveForm::compose :form do |f|
|
|
17
|
+
f.text_element :elem_a, :label => 'A', :value => 'no foo' do |e|
|
|
18
|
+
e.validates_as_required
|
|
19
|
+
e.validates_as_foo
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
assert_equal ["required", "foo"], form[:elem_a].validators.collect(&:code)
|
|
23
|
+
assert !form.validate
|
|
24
|
+
assert_equal ["A: should be foo-matic!"], form[:elem_a].errors.collect(&:msg)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def teardown
|
|
28
|
+
ActiveForm::Validator.load_paths.delete_at(1)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
class TestLoadWidget < Test::Unit::TestCase
|
|
4
|
+
|
|
5
|
+
def setup
|
|
6
|
+
ActiveForm::Widget.load_paths << File.join(File.dirname(__FILE__), 'resources', 'widgets')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def test_load_paths
|
|
10
|
+
assert_equal 2, ActiveForm::Widget.load_paths.length
|
|
11
|
+
assert File.directory?(ActiveForm::Widget.load_paths[0])
|
|
12
|
+
assert File.directory?(ActiveForm::Widget.load_paths[1])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_load_and_build
|
|
16
|
+
assert_equal ActiveForm::Widget::Custom, ActiveForm::Widget::get(:custom)
|
|
17
|
+
elem = ActiveForm::Widget::build(:custom)
|
|
18
|
+
assert_kind_of ActiveForm::Widget::Custom, elem
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def test_add_widget
|
|
22
|
+
form = ActiveForm::compose :form do |f|
|
|
23
|
+
f.text_element :name
|
|
24
|
+
f.custom_widget :my_widget
|
|
25
|
+
end
|
|
26
|
+
assert_equal [:text, :custom_widget], form.collect(&:element_type)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_add_widget_as_element_at_top
|
|
30
|
+
form = ActiveForm::compose :form do |f|
|
|
31
|
+
f.text_element :name
|
|
32
|
+
end
|
|
33
|
+
form.insert_element_at_top(ActiveForm::Widget::build(:custom))
|
|
34
|
+
assert_equal [:custom_widget, :text], form.collect(&:element_type)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_widget_to_html
|
|
38
|
+
users = [ { :id => 1, :firstname => 'Fred', :lastname => 'Flintstone' }, { :id => 2, :firstname => 'Barney', :lastname => 'Rubble' } ]
|
|
39
|
+
form = ActiveForm::compose :form do |f|
|
|
40
|
+
f.section :users do |s|
|
|
41
|
+
users.each do |user|
|
|
42
|
+
s.custom_widget "user_#{user[:id]}", :values => user
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
f.submit_element
|
|
46
|
+
end
|
|
47
|
+
expected = %|<form action="#form" class="active_form" id="form" method="post">
|
|
48
|
+
<table>
|
|
49
|
+
<tr>
|
|
50
|
+
<td>
|
|
51
|
+
<label for="form_users_user_1_firstname">Firstname</label>
|
|
52
|
+
</td>
|
|
53
|
+
<td>
|
|
54
|
+
<label for="form_users_user_1_lastname">Lastname</label>
|
|
55
|
+
</td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<td>
|
|
59
|
+
<input class="elem_text" id="form_users_user_1_firstname" name="form[users][user_1][firstname]" size="30" title="First Name" type="text" value="Fred"/>
|
|
60
|
+
</td>
|
|
61
|
+
<td>
|
|
62
|
+
<input class="elem_text" id="form_users_user_1_lastname" name="form[users][user_1][lastname]" size="30" title="Last Name" type="text" value="Flintstone"/>
|
|
63
|
+
</td>
|
|
64
|
+
</tr>
|
|
65
|
+
</table>
|
|
66
|
+
<table>
|
|
67
|
+
<tr>
|
|
68
|
+
<td>
|
|
69
|
+
<label for="form_users_user_2_firstname">Firstname</label>
|
|
70
|
+
</td>
|
|
71
|
+
<td>
|
|
72
|
+
<label for="form_users_user_2_lastname">Lastname</label>
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<td>
|
|
77
|
+
<input class="elem_text" id="form_users_user_2_firstname" name="form[users][user_2][firstname]" size="30" title="First Name" type="text" value="Barney"/>
|
|
78
|
+
</td>
|
|
79
|
+
<td>
|
|
80
|
+
<input class="elem_text" id="form_users_user_2_lastname" name="form[users][user_2][lastname]" size="30" title="Last Name" type="text" value="Rubble"/>
|
|
81
|
+
</td>
|
|
82
|
+
</tr>
|
|
83
|
+
</table>
|
|
84
|
+
<input class="elem_submit" id="form_submit" name="form[submit]" type="submit" value="Submit"/>
|
|
85
|
+
</form>\n|
|
|
86
|
+
assert_equal expected, form.to_html
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def teardown
|
|
90
|
+
ActiveForm::Widget.load_paths.delete_at(1)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
require 'test_helper'
|
|
2
|
+
|
|
3
|
+
ActiveForm::Validator::Base.create :special do
|
|
4
|
+
|
|
5
|
+
default_message "%s: isn't all that great"
|
|
6
|
+
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class TestValidation < Test::Unit::TestCase
|
|
10
|
+
|
|
11
|
+
def test_create_and_build_validator
|
|
12
|
+
assert_equal ActiveForm::Validator::Special, ActiveForm::Validator::get(:special)
|
|
13
|
+
validator = ActiveForm::Validator::build(:special)
|
|
14
|
+
assert_kind_of ActiveForm::Validator::Special, validator
|
|
15
|
+
assert_equal "%s: isn't all that great", validator.message
|
|
16
|
+
ActiveForm::Validator::get(:special).default_message = "%s: isn't so special"
|
|
17
|
+
assert_equal "%s: isn't so special", validator.message
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def test_validated
|
|
21
|
+
form = ActiveForm::compose :form do |f|
|
|
22
|
+
f.text_element :name
|
|
23
|
+
f.text_element :language
|
|
24
|
+
f.submit_element :send
|
|
25
|
+
end
|
|
26
|
+
assert !form.submitted?
|
|
27
|
+
assert !form.validated?
|
|
28
|
+
assert form.validate
|
|
29
|
+
# coming from click on submit button
|
|
30
|
+
form[:send].value = 'Send'
|
|
31
|
+
assert form.submitted?
|
|
32
|
+
assert form.validated?
|
|
33
|
+
assert form.validate
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_define_class_level_validation
|
|
37
|
+
ActiveForm::Definition.define_validation do |form|
|
|
38
|
+
form.each do |elem|
|
|
39
|
+
elem.errors.add('%s is empty', 'empty') if elem.blank?
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
ActiveForm::Element::Base.define_validation do |elem|
|
|
44
|
+
elem.errors.add("%s can't be numeric", 'non-numeric') if elem.value.to_s.match(/^[0-9]+$/)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
form = ActiveForm::compose :form do |f|
|
|
48
|
+
f.text_element :elem_a
|
|
49
|
+
f.text_element :elem_b
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
assert !form.validate
|
|
53
|
+
assert_equal 2, form.element_errors.length
|
|
54
|
+
assert_equal "Elem A is empty", form[:elem_a].errors.first.message
|
|
55
|
+
assert_equal "Elem B is empty", form[:elem_b].errors.first.message
|
|
56
|
+
|
|
57
|
+
form.params = { :form => { :elem_a => 'a', :elem_b => 'b' } }
|
|
58
|
+
|
|
59
|
+
assert form.validate
|
|
60
|
+
assert_equal 0, form.element_errors.length
|
|
61
|
+
|
|
62
|
+
form.params = { :form => { :elem_a => 2 } }
|
|
63
|
+
|
|
64
|
+
assert !form.validate
|
|
65
|
+
assert_equal 1, form.element_errors.length
|
|
66
|
+
assert_equal "Elem A can't be numeric", form[:elem_a].errors.first.message
|
|
67
|
+
|
|
68
|
+
ActiveForm::Definition.reset_validation
|
|
69
|
+
ActiveForm::Element::Base.reset_validation
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_define_container_validation
|
|
73
|
+
form = ActiveForm::compose :form do |f|
|
|
74
|
+
f.text_element :elem_a
|
|
75
|
+
f.text_element :elem_b
|
|
76
|
+
|
|
77
|
+
f.define_validation do |elem|
|
|
78
|
+
elem.errors.add('empty elements found', 'empty') if elem[:elem_a].blank? || elem[:elem_b].blank?
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
assert !form.validate
|
|
82
|
+
assert !form.valid?
|
|
83
|
+
assert_equal 1, form.errors.length
|
|
84
|
+
assert_equal 1, form.element_errors.length
|
|
85
|
+
assert form.errors.collect(&:code).include?('empty')
|
|
86
|
+
assert form.runtime_css_class.include?('validation-failed')
|
|
87
|
+
assert form.label_css_class.include?('validation-failed')
|
|
88
|
+
form[:elem_a].element_value = 'non-empty'
|
|
89
|
+
form[:elem_b].element_value = 'non-empty'
|
|
90
|
+
assert form.validate
|
|
91
|
+
assert form.valid?
|
|
92
|
+
assert_equal 0, form.element_errors.length
|
|
93
|
+
assert !form.runtime_css_class.include?('validation-failed')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_define_validation_add_error_to_element
|
|
97
|
+
form = ActiveForm::compose :form do |f|
|
|
98
|
+
f.text_element :elem_a
|
|
99
|
+
f.text_element :elem_b
|
|
100
|
+
|
|
101
|
+
f.define_validation do |elem|
|
|
102
|
+
elem[:elem_a].errors.add('%s is empty', 'empty') if elem[:elem_a].blank?
|
|
103
|
+
elem[:elem_b].errors.add('%s is empty', 'empty') if elem[:elem_b].blank?
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
assert !form.validate
|
|
107
|
+
assert !form.valid?
|
|
108
|
+
assert_equal 2, form.element_errors.length
|
|
109
|
+
assert form.element_errors.collect(&:code).include?('empty')
|
|
110
|
+
assert form.runtime_css_class.include?('validation-failed')
|
|
111
|
+
assert !form[:elem_a].valid?
|
|
112
|
+
assert form[:elem_a].runtime_css_class.include?('validation-failed')
|
|
113
|
+
assert !form[:elem_b].valid?
|
|
114
|
+
assert form[:elem_b].runtime_css_class.include?('validation-failed')
|
|
115
|
+
form[:elem_a].element_value = 'non-empty'
|
|
116
|
+
assert !form.validate
|
|
117
|
+
assert !form.valid?
|
|
118
|
+
assert_equal 1, form.element_errors.length
|
|
119
|
+
assert form.runtime_css_class.include?('validation-failed')
|
|
120
|
+
assert form[:elem_a].valid?
|
|
121
|
+
assert !form[:elem_a].runtime_css_class.include?('validation-failed')
|
|
122
|
+
assert !form[:elem_b].valid?
|
|
123
|
+
assert form[:elem_b].runtime_css_class.include?('validation-failed')
|
|
124
|
+
form[:elem_b].element_value = 'non-empty'
|
|
125
|
+
assert form.validate
|
|
126
|
+
assert form.valid?
|
|
127
|
+
assert_equal 0, form.element_errors.length
|
|
128
|
+
assert !form.runtime_css_class.include?('validation-failed')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def test_clear_validations
|
|
132
|
+
form = ActiveForm::compose :form do |f|
|
|
133
|
+
f.text_element :elem_a
|
|
134
|
+
f.text_element :elem_b
|
|
135
|
+
|
|
136
|
+
f.define_validation do |elem|
|
|
137
|
+
elem[:elem_a].errors.add('%s is empty', 'empty') if elem[:elem_a].blank?
|
|
138
|
+
elem[:elem_b].errors.add('%s is empty', 'empty') if elem[:elem_b].blank?
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
assert !(form.validate && form.valid?)
|
|
142
|
+
assert_equal 2, form.element_errors.length
|
|
143
|
+
form.clear_validations!
|
|
144
|
+
assert_equal 0, form.element_errors.length
|
|
145
|
+
assert !(form.validate && form.valid?)
|
|
146
|
+
assert_equal 2, form.element_errors.length
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def test_validation_exception
|
|
150
|
+
form = ActiveForm::compose :form do |f|
|
|
151
|
+
f.text_element :elem_a
|
|
152
|
+
f.text_element :elem_b
|
|
153
|
+
f.define_validation do |elem|
|
|
154
|
+
elem[:elem_a].errors.add('%s is empty', 'empty') if elem[:elem_a].blank?
|
|
155
|
+
elem[:elem_b].errors.add('%s is empty', 'empty') if elem[:elem_b].blank?
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
assert_raises(ActiveForm::ValidationException) { form.validate! }
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def test_define_element_validation
|
|
162
|
+
form = ActiveForm::compose :form do |f|
|
|
163
|
+
f.text_element :elem_a do |e|
|
|
164
|
+
e.define_validation do |elem|
|
|
165
|
+
elem.errors.add('%s is empty', 'empty') if elem.blank?
|
|
166
|
+
elem.errors.add('%s is not numeric', 'numeric') unless value.to_s.match(/^[0-9]+$/)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
f.text_element :elem_b
|
|
170
|
+
end
|
|
171
|
+
assert !form.validate
|
|
172
|
+
assert_equal 0, form.errors.length
|
|
173
|
+
assert_equal 2, form.element_errors.length
|
|
174
|
+
assert_equal ['empty', 'numeric'], form.element_errors.collect(&:code)
|
|
175
|
+
assert_equal 1, form.initial_errors.length
|
|
176
|
+
assert_equal ['empty'], form.initial_errors.collect(&:code)
|
|
177
|
+
assert_equal 2, form[:elem_a].element_errors.length
|
|
178
|
+
assert_equal ['empty', 'numeric'], form[:elem_a].element_errors.collect(&:code)
|
|
179
|
+
assert_equal 1, form[:elem_a].initial_errors.length
|
|
180
|
+
assert_equal ['empty'], form[:elem_a].initial_errors.collect(&:code)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def test_create_proc_validator
|
|
184
|
+
form = ActiveForm::compose :form do |f|
|
|
185
|
+
f.text_element :elem_a do |e|
|
|
186
|
+
e.validates_with_proc :msg => '%s: proc validation failed' do |v|
|
|
187
|
+
v.element.errors.add(v.message) unless v.value == 123
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
assert !form.validate
|
|
192
|
+
assert_equal 'Elem A: proc validation failed', form[:elem_a].errors.first.message
|
|
193
|
+
form[:elem_a].element_value = 123
|
|
194
|
+
assert form.validate
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def test_assign_proc_validator
|
|
198
|
+
one_two_three = lambda { |v| v.element.errors.add(v.message, v.code) unless v.value == 123 }
|
|
199
|
+
form = ActiveForm::compose :form do |f|
|
|
200
|
+
f.text_element :elem_a do |e|
|
|
201
|
+
e.validates_with_proc :msg => '%s: proc validation failed', :proc => one_two_three
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
assert !form.validate
|
|
205
|
+
assert_equal 'Elem A: proc validation failed', form[:elem_a].errors.first.message
|
|
206
|
+
form[:elem_a].element_value = 123
|
|
207
|
+
assert form.validate
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
def test_validation_messages
|
|
211
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
212
|
+
form = ActiveForm::compose :form do |f|
|
|
213
|
+
f.text_element :elem_a, :label => 'Result', :value => 'foo' do |e|
|
|
214
|
+
e.validates_with_proc :msg => '%s: flunked test (value=%s)', :proc => flunker
|
|
215
|
+
e.validates_with_proc :msg => 'value "%2$s" incorrect for %1$s-field', :proc => flunker
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
assert !form.validate
|
|
219
|
+
assert_equal 'Result: flunked test (value=foo)', form[:elem_a].errors[0].message
|
|
220
|
+
assert_equal 'value "foo" incorrect for Result-field', form[:elem_a].errors[1].message
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def test_localized_validation_messages
|
|
224
|
+
translations = {
|
|
225
|
+
'form_elem_a_label' => 'Resultaat',
|
|
226
|
+
'form_elem_a_validates_one' => 'een: advies voor %s-veld',
|
|
227
|
+
'form_elem_a_validates_two' => 'twee: advies voor %s-veld'
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
231
|
+
form = ActiveForm::compose :form do |f|
|
|
232
|
+
f.define_localizer { |formname, elemname, key| translations[ [formname, elemname, key].compact.join('_') ] }
|
|
233
|
+
f.text_element :elem_a, :label => 'Result', :value => 'foo' do |e|
|
|
234
|
+
e.validates_with_proc :code => 'one', :msg => '%s: flunked test (%s)', :proc => flunker
|
|
235
|
+
e.validates_with_proc :code => 'two', :msg => 'value "%2$s" incorrect for %1$s', :proc => flunker
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
assert !form.validate
|
|
239
|
+
assert_equal 'een: advies voor Resultaat-veld', form[:elem_a].errors[0].message
|
|
240
|
+
assert_equal 'twee: advies voor Resultaat-veld', form[:elem_a].errors[1].message
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def test_errors_enumerable
|
|
244
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
245
|
+
form = ActiveForm::compose :form do |f|
|
|
246
|
+
f.text_element :elem_a, :label => 'A', :value => 'foo' do |e|
|
|
247
|
+
e.validates_with_proc :code => 'test-code', :proc => flunker
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
assert !form.validate
|
|
251
|
+
assert_equal ["A: validation failed"], form[:elem_a].errors.collect(&:msg)
|
|
252
|
+
assert_equal ['test-code'], form[:elem_a].errors.collect(&:code)
|
|
253
|
+
assert_equal ["%s: validation failed"], form[:elem_a].validators_by_type('test-code').collect(&:message)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
def test_validate_group
|
|
257
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
258
|
+
form = ActiveForm::compose :form do |f|
|
|
259
|
+
f.section :section do |s|
|
|
260
|
+
s.validates_with_proc :msg => '%s: cannot be blank' do |v|
|
|
261
|
+
v.element.each do |elem|
|
|
262
|
+
elem.errors.add(v.message, 'blank') if elem.blank?
|
|
263
|
+
# ... add more validations here if needed
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
s.text_element :elem_b, :label => 'B' do |e|
|
|
267
|
+
e.validates_with_proc :code => 'test-code', :proc => flunker
|
|
268
|
+
end
|
|
269
|
+
s.text_element :elem_c, :label => 'C'
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
form[:section].define_element_at_top :text, :elem_a, :label => 'A'
|
|
273
|
+
assert_equal ['A', 'B', 'C'], form[:section].collect(&:label)
|
|
274
|
+
assert !form.validate
|
|
275
|
+
assert_equal ["A: cannot be blank", "B: validation failed", "B: cannot be blank", "C: cannot be blank"], form.all_errors.collect(&:message)
|
|
276
|
+
assert_equal ["A: cannot be blank", "B: validation failed", "C: cannot be blank"], form.initial_errors.collect(&:message)
|
|
277
|
+
assert_equal form.all_errors, form[:section].all_errors
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
def test_each_error
|
|
281
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
282
|
+
form = ActiveForm::compose :form do |f|
|
|
283
|
+
f.text_element :elem_a, :label => 'A', :value => 'foo' do |e|
|
|
284
|
+
e.validates_with_proc :proc => flunker
|
|
285
|
+
end
|
|
286
|
+
f.section :section do |s|
|
|
287
|
+
s.text_element :elem_b, :label => 'B', :value => 'foo' do |e|
|
|
288
|
+
e.validates_with_proc :proc => flunker
|
|
289
|
+
e.validates_with_proc :proc => flunker, :msg => '%s failed'
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
end
|
|
293
|
+
assert !form.validate
|
|
294
|
+
expected = ['A: validation failed', 'B: validation failed', 'B failed']
|
|
295
|
+
check = []
|
|
296
|
+
form.each_error { |e| check << e.message }
|
|
297
|
+
assert_equal expected, check
|
|
298
|
+
assert_equal 3, check.length
|
|
299
|
+
expected = ['A: validation failed']
|
|
300
|
+
check = []
|
|
301
|
+
form[:elem_a].each_error { |e| check << e.message }
|
|
302
|
+
assert_equal expected, check
|
|
303
|
+
assert_equal 1, check.length
|
|
304
|
+
expected = ['B: validation failed', 'B failed']
|
|
305
|
+
check = []
|
|
306
|
+
form[:section].each_error { |e| check << e.message }
|
|
307
|
+
assert_equal expected, check
|
|
308
|
+
assert_equal 2, check.length
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def test_every_error
|
|
312
|
+
flunker = lambda { |v| v.element.errors.add(v.message, v.code) }
|
|
313
|
+
form = ActiveForm::compose :form do |f|
|
|
314
|
+
f.text_element :elem_a, :label => 'A', :value => 'foo' do |e|
|
|
315
|
+
e.validates_with_proc :proc => flunker
|
|
316
|
+
end
|
|
317
|
+
f.section :section do |s|
|
|
318
|
+
s.text_element :elem_b, :label => 'B', :value => 'foo' do |e|
|
|
319
|
+
e.validates_with_proc :proc => flunker
|
|
320
|
+
e.validates_with_proc :proc => flunker, :msg => '%s failed'
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
assert !form.validate
|
|
325
|
+
expected = ['A: validation failed', 'B: validation failed']
|
|
326
|
+
check = []
|
|
327
|
+
form.every_error { |e| check << e.message }
|
|
328
|
+
assert_equal expected, check
|
|
329
|
+
assert_equal 2, check.length
|
|
330
|
+
expected = ['A: validation failed']
|
|
331
|
+
check = []
|
|
332
|
+
form[:elem_a].every_error { |e| check << e.message }
|
|
333
|
+
assert_equal expected, check
|
|
334
|
+
assert_equal 1, check.length
|
|
335
|
+
expected = ['B: validation failed']
|
|
336
|
+
check = []
|
|
337
|
+
form[:section].every_error { |e| check << e.message }
|
|
338
|
+
assert_equal expected, check
|
|
339
|
+
assert_equal 1, check.length
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
def test_add_custom_javascript_validation
|
|
343
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
344
|
+
f.javascript_validation do |elem, code, params|
|
|
345
|
+
params[:name] = 'custom'
|
|
346
|
+
params[:msg] = 'Not valid'
|
|
347
|
+
code << "return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)"
|
|
348
|
+
end
|
|
349
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
350
|
+
e.css_class << 'validate-custom'
|
|
351
|
+
end
|
|
352
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
353
|
+
e.css_class << 'validate-custom'
|
|
354
|
+
end
|
|
355
|
+
end
|
|
356
|
+
expected = %`var fform_form=$('form');if(fform_form){
|
|
357
|
+
Validation.add('validate-custom', "Not valid", function (v) {
|
|
358
|
+
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
|
|
359
|
+
});
|
|
360
|
+
new Validation(fform_form, {stopOnFirst:false, useTitles:true});
|
|
361
|
+
}`
|
|
362
|
+
assert_equal expected, form.element_javascript
|
|
363
|
+
assert form[:elem_a].css_class.include?('elem_text')
|
|
364
|
+
assert form[:elem_a].css_class.include?('validate-custom')
|
|
365
|
+
assert form[:elem_b].css_class.include?('elem_text')
|
|
366
|
+
assert form[:elem_b].css_class.include?('validate-custom')
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def test_custom_javascript_element_validation
|
|
370
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
371
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
372
|
+
e.javascript_validation do |elem, code, params|
|
|
373
|
+
code << "return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)"
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
377
|
+
e.javascript_validation do |elem, code, params|
|
|
378
|
+
params[:name] = 'reusable'
|
|
379
|
+
params[:msg] = 'Not valid'
|
|
380
|
+
code << "return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)"
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
end
|
|
384
|
+
expected = %`Validation.add('validate-form-elem-a', "A: validation failed", function (v) {
|
|
385
|
+
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
|
|
386
|
+
});`
|
|
387
|
+
assert_equal expected, form[:elem_a].javascript_validation_code
|
|
388
|
+
expected = %`Validation.add('validate-reusable', "Not valid", function (v) {
|
|
389
|
+
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
|
|
390
|
+
});`
|
|
391
|
+
assert_equal expected, form[:elem_b].javascript_validation_code
|
|
392
|
+
expected = %`var fform_form=$('form');if(fform_form){
|
|
393
|
+
var ftext_form_elem_a=$('form_elem_a');if(ftext_form_elem_a){
|
|
394
|
+
Validation.add('validate-form-elem-a', "A: validation failed", function (v) {
|
|
395
|
+
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
var ftext_form_elem_b=$('form_elem_b');if(ftext_form_elem_b){
|
|
399
|
+
Validation.add('validate-reusable', "Not valid", function (v) {
|
|
400
|
+
return Validation.get('IsEmpty').test(v) || /^[a-zA-Z]+$/.test(v)
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
new Validation(fform_form, {stopOnFirst:false, useTitles:true});
|
|
404
|
+
}`
|
|
405
|
+
assert_equal expected, form.element_javascript
|
|
406
|
+
assert form[:elem_a].css_class.include?("validate-form-elem-a")
|
|
407
|
+
assert form[:elem_b].css_class.include?("validate-reusable")
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def test_gather_validation_advice
|
|
411
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
412
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
413
|
+
e.validates_as_required
|
|
414
|
+
e.validates_as_number
|
|
415
|
+
end
|
|
416
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
417
|
+
e.validates_as_required
|
|
418
|
+
e.validates_as_alpha
|
|
419
|
+
end
|
|
420
|
+
f.text_element :elem_c, :label => 'C' do |e|
|
|
421
|
+
e.validates_as_required
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
expected = %`var fform_form=$('form');if(fform_form){
|
|
425
|
+
new Validation(fform_form, {stopOnFirst:false, useTitles:true});
|
|
426
|
+
}`
|
|
427
|
+
assert_equal expected, form.element_javascript
|
|
428
|
+
assert form[:elem_a].css.include?('elem_text')
|
|
429
|
+
assert form[:elem_a].css.include?('required')
|
|
430
|
+
assert form[:elem_a].css.include?('validate-number')
|
|
431
|
+
assert form[:elem_b].css.include?('elem_text')
|
|
432
|
+
assert form[:elem_b].css.include?('required')
|
|
433
|
+
assert form[:elem_b].css.include?('validate-alpha')
|
|
434
|
+
assert form[:elem_c].css.include?('elem_text')
|
|
435
|
+
assert form[:elem_c].css.include?('required')
|
|
436
|
+
|
|
437
|
+
assert_equal ["A: can't be blank", "A: should be numeric"], form[:elem_a].gather_validation_advice.collect(&:message)
|
|
438
|
+
assert_equal ["B: can't be blank", "B: should contain alphabetical characters only"], form[:elem_b].gather_validation_advice.collect(&:message)
|
|
439
|
+
assert_equal ["C: can't be blank"], form[:elem_c].gather_validation_advice.collect(&:message)
|
|
440
|
+
|
|
441
|
+
expected = [ ["form_elem_a", "A: can't be blank"], ["form_elem_a", "A: should be numeric"],
|
|
442
|
+
["form_elem_b", "B: can't be blank"], ["form_elem_b", "B: should contain alphabetical characters only"],
|
|
443
|
+
["form_elem_c", "C: can't be blank"]
|
|
444
|
+
]
|
|
445
|
+
assert_equal expected, form.gather_validation_advice.collect { |adv| [adv.element.identifier, adv.message] }
|
|
446
|
+
|
|
447
|
+
assert !form.validate
|
|
448
|
+
params = { :form => { :elem_a => '123', :elem_b => 'abcde', :elem_c => 'fghi' } }
|
|
449
|
+
form.update_from_params(params)
|
|
450
|
+
assert form.validate
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def test_gather_nested_elements_validation_advice
|
|
454
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
455
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
456
|
+
e.validates_as_required
|
|
457
|
+
e.validates_as_number
|
|
458
|
+
end
|
|
459
|
+
f.section :section do |s|
|
|
460
|
+
s.text_element :elem_b, :label => 'B' do |e|
|
|
461
|
+
e.validates_as_required
|
|
462
|
+
e.validates_as_alpha
|
|
463
|
+
end
|
|
464
|
+
s.text_element :elem_c, :label => 'C' do |e|
|
|
465
|
+
e.validates_as_required
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
assert form[:elem_a].css.include?('elem_text')
|
|
470
|
+
assert form[:elem_a].css.include?('required')
|
|
471
|
+
assert form[:elem_a].css.include?('validate-number')
|
|
472
|
+
assert form[:section][:elem_b].css.include?('elem_text')
|
|
473
|
+
assert form[:section][:elem_b].css.include?('required')
|
|
474
|
+
assert form[:section][:elem_b].css.include?('validate-alpha')
|
|
475
|
+
assert form[:section][:elem_c].css.include?('elem_text')
|
|
476
|
+
assert form[:section][:elem_c].css.include?('required')
|
|
477
|
+
|
|
478
|
+
assert_equal ["A: can't be blank", "A: should be numeric"], form[:elem_a].gather_validation_advice.collect(&:message)
|
|
479
|
+
assert_equal ["B: can't be blank", "B: should contain alphabetical characters only"], form[:section][:elem_b].gather_validation_advice.collect(&:message)
|
|
480
|
+
assert_equal ["C: can't be blank"], form[:section][:elem_c].gather_validation_advice.collect(&:message)
|
|
481
|
+
|
|
482
|
+
expected = [ ["form_elem_a", "A: can't be blank"], ["form_elem_a", "A: should be numeric"],
|
|
483
|
+
["form_section_elem_b", "B: can't be blank"], ["form_section_elem_b", "B: should contain alphabetical characters only"],
|
|
484
|
+
["form_section_elem_c", "C: can't be blank"]
|
|
485
|
+
]
|
|
486
|
+
assert_equal expected, form.gather_validation_advice.collect { |adv| [adv.element.identifier, adv.message] }
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def test_validation_css_class
|
|
490
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
491
|
+
f.text_element :elem_a, :label => 'A', :required => true do |e|
|
|
492
|
+
e.validates_as_number
|
|
493
|
+
end
|
|
494
|
+
end
|
|
495
|
+
assert_equal ["required", "validate-number"], form[:elem_a].validation_css_class
|
|
496
|
+
assert_equal ["required", "validate-number"], form[:elem_a].runtime_css_class
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def test_server_side_validation_advice
|
|
500
|
+
form = ActiveForm::compose :form do |f|
|
|
501
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
502
|
+
e.validates_as_required
|
|
503
|
+
e.validates_as_number
|
|
504
|
+
end
|
|
505
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
506
|
+
e.validates_as_required
|
|
507
|
+
e.validates_as_alpha
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
assert_equal '', form[:elem_a].server_side_validation_advice
|
|
511
|
+
assert_equal '', form[:elem_b].server_side_validation_advice
|
|
512
|
+
assert !form.validate
|
|
513
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a">A: can't be blank</div>\n`
|
|
514
|
+
assert_equal expected, form[:elem_a].server_side_validation_advice
|
|
515
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_b">B: can't be blank</div>\n`
|
|
516
|
+
assert_equal expected, form[:elem_b].server_side_validation_advice
|
|
517
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a">A: can't be blank</div>
|
|
518
|
+
<div class="validation-advice advice-required" id="advice-required-form_elem_b">B: can't be blank</div>\n`
|
|
519
|
+
assert_equal expected, form.server_side_validation_advice
|
|
520
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a">A: can't be blank</div>
|
|
521
|
+
<div class="validation-advice advice-required" id="advice-required-form_elem_b">B: can't be blank</div>\n`
|
|
522
|
+
assert_equal expected, form.all_server_side_validation_advice
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def test_client_side_validation_advice
|
|
526
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
527
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
528
|
+
e.validates_as_required
|
|
529
|
+
e.validates_as_number
|
|
530
|
+
end
|
|
531
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
532
|
+
e.validates_as_required
|
|
533
|
+
e.validates_as_alpha
|
|
534
|
+
end
|
|
535
|
+
end
|
|
536
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a" style="display: none">A: can't be blank</div>
|
|
537
|
+
<div class="validation-advice advice-number" id="advice-validate-number-form_elem_a" style="display: none">A: should be numeric</div>\n`
|
|
538
|
+
assert_equal expected, form[:elem_a].client_side_validation_advice
|
|
539
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_b" style="display: none">B: can't be blank</div>
|
|
540
|
+
<div class="validation-advice advice-alpha" id="advice-validate-alpha-form_elem_b" style="display: none">B: should contain alphabetical characters only</div>\n`
|
|
541
|
+
assert_equal expected, form[:elem_b].client_side_validation_advice
|
|
542
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a" style="display: none">A: can't be blank</div>
|
|
543
|
+
<div class="validation-advice advice-number" id="advice-validate-number-form_elem_a" style="display: none">A: should be numeric</div>
|
|
544
|
+
<div class="validation-advice advice-required" id="advice-required-form_elem_b" style="display: none">B: can't be blank</div>
|
|
545
|
+
<div class="validation-advice advice-alpha" id="advice-validate-alpha-form_elem_b" style="display: none">B: should contain alphabetical characters only</div>\n`
|
|
546
|
+
assert_equal expected, form.client_side_validation_advice
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
def test_validation_advice
|
|
550
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
551
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
552
|
+
e.validates_as_required :msg => '%s: should not be left blank'
|
|
553
|
+
e.validates_as_number :msg => '%s: numeric values only'
|
|
554
|
+
end
|
|
555
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
556
|
+
e.validates_as_required :msg => '%s: should not be left blank'
|
|
557
|
+
e.validates_as_alpha :msg => '%s: letter characters only please'
|
|
558
|
+
end
|
|
559
|
+
end
|
|
560
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a" style="display: none">A: should not be left blank</div>
|
|
561
|
+
<div class="validation-advice advice-number" id="advice-validate-number-form_elem_a" style="display: none">A: numeric values only</div>
|
|
562
|
+
<div class="validation-advice advice-required" id="advice-required-form_elem_b" style="display: none">B: should not be left blank</div>
|
|
563
|
+
<div class="validation-advice advice-alpha" id="advice-validate-alpha-form_elem_b" style="display: none">B: letter characters only please</div>\n`
|
|
564
|
+
assert_equal expected, form.validation_advice
|
|
565
|
+
end
|
|
566
|
+
|
|
567
|
+
def test_localized_validation_advice
|
|
568
|
+
translations = {
|
|
569
|
+
'form_elem_a_label' => 'Foo',
|
|
570
|
+
'form_elem_a_validates_required' => '%s: mag niet leeg zijn',
|
|
571
|
+
'form_elem_a_validates_number' => '%s: dit moet een nummer zijn',
|
|
572
|
+
'form_elem_b_label' => 'Bar',
|
|
573
|
+
'form_elem_b_validates_required' => '%s: mag niet leeg zijn',
|
|
574
|
+
'form_elem_b_validates_alpha' => '%s: mag alleen letters bevatten'
|
|
575
|
+
}
|
|
576
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
577
|
+
f.define_localizer { |formname, elemname, key| translations[ [formname, elemname, key].compact.join('_') ] }
|
|
578
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
579
|
+
e.validates_as_required
|
|
580
|
+
e.validates_as_number
|
|
581
|
+
end
|
|
582
|
+
f.text_element :elem_b, :label => 'B' do |e|
|
|
583
|
+
e.validates_as_required
|
|
584
|
+
e.validates_as_alpha
|
|
585
|
+
end
|
|
586
|
+
end
|
|
587
|
+
expected = %`<div class="validation-advice advice-required" id="advice-required-form_elem_a" style="display: none">Foo: mag niet leeg zijn</div>
|
|
588
|
+
<div class="validation-advice advice-number" id="advice-validate-number-form_elem_a" style="display: none">Foo: dit moet een nummer zijn</div>
|
|
589
|
+
<div class="validation-advice advice-required" id="advice-required-form_elem_b" style="display: none">Bar: mag niet leeg zijn</div>
|
|
590
|
+
<div class="validation-advice advice-alpha" id="advice-validate-alpha-form_elem_b" style="display: none">Bar: mag alleen letters bevatten</div>\n`
|
|
591
|
+
assert_equal expected, form.validation_advice
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def test_javascript_validator_definition
|
|
595
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
596
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
597
|
+
e.validates_as_sample
|
|
598
|
+
end
|
|
599
|
+
f.submit_element :label => 'Validate'
|
|
600
|
+
end
|
|
601
|
+
assert form[:elem_a].css.include?('validate-sample')
|
|
602
|
+
expected = %`Validation.add('validate-sample', "value needs to be identical to 'sample'", function (v) {
|
|
603
|
+
return Validation.get('IsEmpty').test(v) || /^sample$/i.test(v);
|
|
604
|
+
});`
|
|
605
|
+
assert_equal expected, form.validation_javascript_definitions
|
|
606
|
+
expected = %`var fform_form=$('form');if(fform_form){
|
|
607
|
+
Validation.add('validate-sample', "value needs to be identical to 'sample'", function (v) {
|
|
608
|
+
return Validation.get('IsEmpty').test(v) || /^sample$/i.test(v);
|
|
609
|
+
});
|
|
610
|
+
new Validation(fform_form, {stopOnFirst:false, useTitles:true});
|
|
611
|
+
}`
|
|
612
|
+
assert_equal expected, form.js
|
|
613
|
+
assert_equal ["sample"], form[:elem_a].validators.collect(&:code)
|
|
614
|
+
end
|
|
615
|
+
|
|
616
|
+
def test_validates_as_required_alternative
|
|
617
|
+
form = ActiveForm::compose :form do |f|
|
|
618
|
+
f.text_element :elem_a, :required => true
|
|
619
|
+
end
|
|
620
|
+
assert form[:elem_a].css.include?('required')
|
|
621
|
+
assert_equal ["required"], form[:elem_a].validators.collect(&:code)
|
|
622
|
+
form[:elem_a].required = false
|
|
623
|
+
assert_equal [], form[:elem_a].validators.collect(&:code)
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
def test_mixed_validations
|
|
627
|
+
is_blank = lambda { |v| v.element.errors.add(v.message, v.code) if v.value.blank? }
|
|
628
|
+
form = ActiveForm::compose :form, :client_side => true do |f|
|
|
629
|
+
f.text_element :elem_a, :label => 'A' do |e|
|
|
630
|
+
e.validates_as_required
|
|
631
|
+
e.validates_as_number
|
|
632
|
+
e.validates_with_proc :code => 'test-code', :proc => is_blank, :msg => '%s: is_blank proc validation failed'
|
|
633
|
+
e.define_validation { |elem| elem.errors.add('%s is empty', 'empty') if elem.blank? }
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
expected = ["A: can't be blank", "A: should be numeric"]
|
|
637
|
+
assert_equal expected, form.gather_validation_advice.collect(&:message)
|
|
638
|
+
assert !form.validate
|
|
639
|
+
expected = ["A: can't be blank", "A: is_blank proc validation failed", "A is empty"]
|
|
640
|
+
assert_equal expected, form.all_errors.collect(&:message)
|
|
641
|
+
form[:elem_a].value = '1234'
|
|
642
|
+
assert form.validate
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
def test_after_validation_callback
|
|
646
|
+
ActiveForm::Element::Base.define_element_wrapper do |builder, elem, render|
|
|
647
|
+
builder.div(:id => "elem_#{elem.identifier}", :class => elem.css, :style => elem.style) do
|
|
648
|
+
elem.frozen? ? builder.span(elem.label, elem.label_attributes) : elem.render_label(builder)
|
|
649
|
+
builder.br
|
|
650
|
+
render.call
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
form = ActiveForm::compose :myform do |f|
|
|
655
|
+
f.text_element :first_name, :required => true
|
|
656
|
+
f.text_element :last_name, :required => true do |e|
|
|
657
|
+
e.after_validation do |elem|
|
|
658
|
+
elem.value += ' (OK)' if elem.valid?
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
f.password_element :password, :required => true
|
|
662
|
+
f.password_element :password_confirm, :required => true
|
|
663
|
+
f.after_validation do |elem|
|
|
664
|
+
if elem.valid?
|
|
665
|
+
elem.remove_elements(:password, :password_confirm)
|
|
666
|
+
elem.freeze!
|
|
667
|
+
end
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
assert !form.validate
|
|
671
|
+
expected = %`<!--o---------------------------[ myform ]---------------------------o-->
|
|
672
|
+
<div class="validation-advice advice-required" id="advice-required-myform_first_name">First Name: can't be blank</div>
|
|
673
|
+
<div class="validation-advice advice-required" id="advice-required-myform_last_name">Last Name: can't be blank</div>
|
|
674
|
+
<div class="validation-advice advice-required" id="advice-required-myform_password">Password: can't be blank</div>
|
|
675
|
+
<div class="validation-advice advice-required" id="advice-required-myform_password_confirm">Password Confirm: can't be blank</div>
|
|
676
|
+
<form action="#myform" class="active_form validation-failed" id="myform" method="post">
|
|
677
|
+
<div class="elem_text required validation-failed" id="elem_myform_first_name">
|
|
678
|
+
<label class="required validation-failed" for="myform_first_name">First Name</label>
|
|
679
|
+
<br/>
|
|
680
|
+
<input class="required" id="myform_first_name" name="myform[first_name]" size="30" type="text"/>
|
|
681
|
+
</div>
|
|
682
|
+
<div class="elem_text required validation-failed" id="elem_myform_last_name">
|
|
683
|
+
<label class="required validation-failed" for="myform_last_name">Last Name</label>
|
|
684
|
+
<br/>
|
|
685
|
+
<input class="required" id="myform_last_name" name="myform[last_name]" size="30" type="text"/>
|
|
686
|
+
</div>
|
|
687
|
+
<div class="elem_password required validation-failed" id="elem_myform_password">
|
|
688
|
+
<label class="required validation-failed" for="myform_password">Password</label>
|
|
689
|
+
<br/>
|
|
690
|
+
<input class="required" id="myform_password" name="myform[password]" size="30" type="password"/>
|
|
691
|
+
</div>
|
|
692
|
+
<div class="elem_password required validation-failed" id="elem_myform_password_confirm">
|
|
693
|
+
<label class="required validation-failed" for="myform_password_confirm">Password Confirm</label>
|
|
694
|
+
<br/>
|
|
695
|
+
<input class="required" id="myform_password_confirm" name="myform[password_confirm]" size="30" type="password"/>
|
|
696
|
+
</div>
|
|
697
|
+
</form>
|
|
698
|
+
<!--x---------------------------[ myform ]---------------------------x-->\n`
|
|
699
|
+
assert_equal expected, form.render
|
|
700
|
+
form.values[:first_name] = 'Fabien'
|
|
701
|
+
form.values[:last_name] = 'Franzen'
|
|
702
|
+
form.values[:password] = form.values[:password_confirm] = 'secret'
|
|
703
|
+
assert form.validate
|
|
704
|
+
assert_equal 'Franzen (OK)', form[:last_name].value
|
|
705
|
+
|
|
706
|
+
expected = %`<!--o---------------------------[ myform ]---------------------------o-->
|
|
707
|
+
<form action="#myform" class="active_form frozen" id="myform" method="post">
|
|
708
|
+
<div class="elem_text frozen required" id="elem_myform_first_name">
|
|
709
|
+
<span class="inactive required" for="myform_first_name">First Name</span>
|
|
710
|
+
<br/>
|
|
711
|
+
Fabien </div>
|
|
712
|
+
<div class="elem_text frozen required" id="elem_myform_last_name">
|
|
713
|
+
<span class="inactive required" for="myform_last_name">Last Name</span>
|
|
714
|
+
<br/>
|
|
715
|
+
Franzen (OK) </div>
|
|
716
|
+
</form>
|
|
717
|
+
<!--x---------------------------[ myform ]---------------------------x-->\n`
|
|
718
|
+
assert_equal expected, form.render
|
|
719
|
+
ActiveForm::Element::Base.reset_element_wrapper
|
|
720
|
+
end
|
|
721
|
+
|
|
722
|
+
end
|