client_side_validations 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/client_side_validations.gemspec +4 -7
  2. data/lib/client_side_validations/action_view/form_builder.rb +97 -9
  3. data/lib/client_side_validations/action_view/form_helper.rb +24 -7
  4. data/lib/client_side_validations/action_view.rb +4 -3
  5. data/lib/client_side_validations/active_model/length.rb +12 -10
  6. data/lib/client_side_validations/active_model/numericality.rb +14 -9
  7. data/lib/client_side_validations/active_model.rb +21 -13
  8. data/lib/client_side_validations/active_record/middleware.rb +10 -2
  9. data/lib/client_side_validations/active_record/uniqueness.rb +10 -8
  10. data/lib/client_side_validations/engine.rb +6 -0
  11. data/lib/client_side_validations/files.rb +8 -0
  12. data/lib/client_side_validations/formtastic.rb +3 -3
  13. data/lib/client_side_validations/middleware.rb +5 -7
  14. data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
  15. data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
  16. data/lib/client_side_validations/mongo_mapper.rb +9 -0
  17. data/lib/client_side_validations/mongoid/uniqueness.rb +10 -8
  18. data/lib/client_side_validations/version.rb +1 -1
  19. data/lib/client_side_validations.rb +8 -3
  20. data/lib/generators/client_side_validations/copy_asset_generator.rb +23 -0
  21. data/lib/generators/client_side_validations/install_generator.rb +18 -6
  22. data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
  23. data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
  24. data/lib/generators/templates/{client_side_validations.rb → client_side_validations/initializer.rb} +1 -1
  25. data/test/action_view/cases/helper.rb +37 -13
  26. data/test/action_view/cases/test_helpers.rb +364 -1
  27. data/test/action_view/cases/test_legacy_helpers.rb +68 -1
  28. data/test/active_model/cases/test_validations.rb +27 -3
  29. data/test/active_record/cases/test_middleware.rb +41 -16
  30. data/test/active_record/cases/test_uniqueness_validator.rb +5 -0
  31. data/test/active_record/models/user.rb +4 -0
  32. data/test/base_helper.rb +2 -0
  33. data/test/core_ext/cases/test_core_ext.rb +1 -0
  34. data/test/formtastic/cases/helper.rb +5 -0
  35. data/test/formtastic/cases/test_form_builder.rb +3 -3
  36. data/test/formtastic/cases/test_form_helper.rb +3 -4
  37. data/test/generators/cases/test_generators.rb +31 -0
  38. data/test/javascript/public/test/callbacks/elementAfter.js +1 -1
  39. data/test/javascript/public/test/callbacks/elementBefore.js +1 -1
  40. data/test/javascript/public/test/callbacks/elementFail.js +1 -1
  41. data/test/javascript/public/test/callbacks/elementPass.js +1 -1
  42. data/test/javascript/public/test/callbacks/formAfter.js +1 -1
  43. data/test/javascript/public/test/callbacks/formBefore.js +1 -1
  44. data/test/javascript/public/test/callbacks/formFail.js +1 -1
  45. data/test/javascript/public/test/callbacks/formPass.js +1 -1
  46. data/test/javascript/public/test/form_builders/validateForm.js +1 -1
  47. data/test/javascript/public/test/form_builders/validateFormtastic.js +2 -2
  48. data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
  49. data/test/javascript/public/test/form_builders/validateSimpleForm.js +1 -1
  50. data/test/javascript/public/test/validateElement.js +36 -1
  51. data/test/javascript/public/test/validators/length.js +7 -1
  52. data/test/javascript/public/test/validators/numericality.js +7 -0
  53. data/test/javascript/public/test/validators/presence.js +6 -0
  54. data/test/javascript/public/test/validators/uniqueness.js +8 -1
  55. data/test/javascript/server.rb +9 -3
  56. data/test/javascript/views/index.erb +1 -1
  57. data/test/javascript/views/layout.erb +1 -1
  58. data/test/middleware/cases/helper.rb +3 -0
  59. data/test/mongo_mapper/cases/helper.rb +9 -0
  60. data/test/mongo_mapper/cases/test_base.rb +15 -0
  61. data/test/mongo_mapper/cases/test_middleware.rb +77 -0
  62. data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
  63. data/test/mongo_mapper/models/magazine.rb +11 -0
  64. data/test/mongoid/cases/test_middleware.rb +15 -6
  65. data/test/mongoid/cases/test_uniqueness_validator.rb +5 -0
  66. data/test/mongoid/models/book.rb +4 -0
  67. data/test/simple_form/cases/helper.rb +3 -0
  68. data/test/simple_form/cases/test_form_helper.rb +3 -1
  69. data/test/test_loader.rb +6 -0
  70. data/{javascript → vendor/assets/javascripts}/rails.validations.js +32 -17
  71. metadata +44 -23
  72. data/lib/generators/templates/README +0 -7
  73. data/test/generators/cases/test_install_generator.rb +0 -15
@@ -30,7 +30,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
30
30
 
31
31
  def test_uniqueness_when_resource_exists
32
32
  User.create(:email => 'user@test.com')
33
- get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
33
+ get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
34
34
 
35
35
  assert_equal 'false', last_response.body
36
36
  assert last_response.ok?
@@ -38,14 +38,14 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
38
38
 
39
39
  def test_uniqueness_when_resource_exists_and_param_order_is_backwards
40
40
  User.create(:email => 'user@test.com')
41
- get '/validators/uniqueness.json', { 'case_sensitive' => true, 'user[email]' => 'user@test.com' }
41
+ get '/validators/uniqueness', { 'case_sensitive' => true, 'user[email]' => 'user@test.com' }
42
42
 
43
43
  assert_equal 'false', last_response.body
44
44
  assert last_response.ok?
45
45
  end
46
46
 
47
47
  def test_uniqueness_when_resource_does_not_exist
48
- get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
48
+ get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
49
49
 
50
50
  assert_equal 'true', last_response.body
51
51
  assert last_response.not_found?
@@ -53,15 +53,33 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
53
53
 
54
54
  def test_uniqueness_when_id_is_given
55
55
  user = User.create(:email => 'user@test.com')
56
- get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'id' => user.id, 'case_sensitive' => true }
56
+ get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'id' => user.id, 'case_sensitive' => true }
57
57
 
58
58
  assert_equal 'true', last_response.body
59
59
  assert last_response.not_found?
60
60
  end
61
61
 
62
+ def test_mysql_adapter_uniqueness_when_id_is_given
63
+ user = User.create(:email => 'user@test.com')
64
+ ActiveRecord::ConnectionAdapters::SQLite3Adapter.
65
+ any_instance.expects(:instance_variable_get).
66
+ with("@config").
67
+ returns({:adapter => "mysql"})
68
+
69
+ sql_without_binary = "#{User.arel_table["email"].eq(user.email).to_sql} AND #{User.arel_table.primary_key.not_eq(user.id).to_sql}"
70
+ relation = Arel::Nodes::SqlLiteral.new("BINARY #{sql_without_binary}")
71
+
72
+ #NOTE: Stubs User#where because SQLite3 don't know BINARY
73
+ result = User.where(sql_without_binary)
74
+ User.expects(:where).with(relation).returns(result)
75
+
76
+ get '/validators/uniqueness', { 'user[email]' => user.email, 'case_sensitive' => true, 'id' => user.id}
77
+ assert_equal 'true', last_response.body
78
+ end
79
+
62
80
  def test_uniqueness_when_scope_is_given
63
81
  User.create(:email => 'user@test.com', :age => 25)
64
- get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30 }, 'case_sensitive' => true }
82
+ get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30 }, 'case_sensitive' => true }
65
83
 
66
84
  assert_equal 'true', last_response.body
67
85
  assert last_response.not_found?
@@ -69,7 +87,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
69
87
 
70
88
  def test_uniqueness_when_multiple_scopes_are_given
71
89
  User.create(:email => 'user@test.com', :age => 30, :name => 'Brian')
72
- get '/validators/uniqueness.json', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30, 'name' => 'Robert' }, 'case_sensitive' => true }
90
+ get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30, 'name' => 'Robert' }, 'case_sensitive' => true }
73
91
 
74
92
  assert_equal 'true', last_response.body
75
93
  assert last_response.not_found?
@@ -77,7 +95,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
77
95
 
78
96
  def test_uniqueness_when_case_insensitive
79
97
  User.create(:name => 'Brian')
80
- get '/validators/uniqueness.json', { 'user[name]' => 'BRIAN', 'case_sensitive' => false }
98
+ get '/validators/uniqueness', { 'user[name]' => 'BRIAN', 'case_sensitive' => false }
81
99
 
82
100
  assert_equal 'false', last_response.body
83
101
  assert last_response.ok?
@@ -85,7 +103,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
85
103
 
86
104
  def test_uniqueness_when_attribute_passes_as_an_integer
87
105
  User.create(:name => 123)
88
- get '/validators/uniqueness.json', { 'user[name]' => 123, 'case_sensitive' => true }
106
+ get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
89
107
 
90
108
  assert_equal 'false', last_response.body
91
109
  assert last_response.ok?
@@ -93,7 +111,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
93
111
 
94
112
  def test_uniqueness_when_attribute_passes_as_an_integer
95
113
  User.create(:name => 123)
96
- get '/validators/uniqueness.json', { 'user[name]' => 123, 'case_sensitive' => true }
114
+ get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
97
115
 
98
116
  assert_equal 'false', last_response.body
99
117
  assert last_response.ok?
@@ -102,14 +120,14 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
102
120
  def test_uniqueness_with_columns_which_are_sql_keywords
103
121
  Guid.validates_uniqueness_of :key
104
122
  assert_nothing_raised do
105
- get '/validators/uniqueness.json', { 'guid[key]' => 'test', 'case_sensitive' => true }
123
+ get '/validators/uniqueness', { 'guid[key]' => 'test', 'case_sensitive' => true }
106
124
  end
107
125
  end
108
126
 
109
127
  def test_uniqueness_with_limit
110
128
  # User.title is limited to 5 characters
111
129
  User.create(:title => "abcde")
112
- get '/validators/uniqueness.json', { 'user[title]' => 'abcdefgh', 'case_sensitive' => true }
130
+ get '/validators/uniqueness', { 'user[title]' => 'abcdefgh', 'case_sensitive' => true }
113
131
 
114
132
  assert_equal 'false', last_response.body
115
133
  assert last_response.ok?
@@ -119,7 +137,7 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
119
137
  with_kcode('UTF8') do
120
138
  # User.title is limited to 5 characters
121
139
  User.create(:title => "一二三四五")
122
- get '/validators/uniqueness.json', { 'user[title]' => '一二三四五六七八', 'case_sensitive' => true }
140
+ get '/validators/uniqueness', { 'user[title]' => '一二三四五六七八', 'case_sensitive' => true }
123
141
 
124
142
  assert_equal 'false', last_response.body
125
143
  assert last_response.ok?
@@ -127,24 +145,31 @@ class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
127
145
  end
128
146
 
129
147
  def test_validate_straight_inheritance_uniqueness
130
- get '/validators/uniqueness.json', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
148
+ get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
131
149
  assert_equal 'true', last_response.body
132
150
  assert last_response.not_found?
133
151
 
134
152
  IneptWizard.create(:name => 'Rincewind')
135
- get '/validators/uniqueness.json', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
153
+ get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
136
154
  assert_equal 'false', last_response.body
137
155
  assert last_response.ok?
138
156
 
139
- get '/validators/uniqueness.json', { 'conjurer[name]' => 'Rincewind', 'case_sensitive' => true }
157
+ get '/validators/uniqueness', { 'conjurer[name]' => 'Rincewind', 'case_sensitive' => true }
140
158
  assert_equal 'false', last_response.body
141
159
  assert last_response.ok?
142
160
 
143
161
  Conjurer.create(:name => 'The Amazing Bonko')
144
- get '/validators/uniqueness.json', { 'thaumaturgist[name]' => 'The Amazing Bonko', 'case_sensitive' => true }
162
+ get '/validators/uniqueness', { 'thaumaturgist[name]' => 'The Amazing Bonko', 'case_sensitive' => true }
145
163
  assert_equal 'false', last_response.body
146
164
  assert last_response.ok?
147
165
  end
148
166
 
167
+ def test_uniqueness_when_resource_is_a_nested_module
168
+ ActiveRecordTestModule::User2.create(:email => 'user@test.com')
169
+ get '/validators/uniqueness', { 'active_record_test_module/user2[email]' => 'user@test.com', 'case_sensitive' => true }
170
+
171
+ assert_equal 'false', last_response.body
172
+ assert last_response.ok?
173
+ end
149
174
  end
150
175
 
@@ -41,5 +41,10 @@ class ActiveRecord::UniquenessValidatorTest < ClientSideValidations::ActiveRecor
41
41
  assert_equal expected_hash, result_hash
42
42
  end
43
43
 
44
+ def test_uniqueness_client_side_hash_when_nested_module
45
+ @user = ActiveRecordTestModule::User2.new
46
+ expected_hash = { :message => "has already been taken", :case_sensitive => true, :class => 'active_record_test_module/user2' }
47
+ assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@user, :name)
48
+ end
44
49
  end
45
50
 
@@ -8,3 +8,7 @@ end
8
8
  class IneptWizard < User; end
9
9
  class Conjurer < IneptWizard; end
10
10
  class Thaumaturgist < Conjurer; end
11
+
12
+ module ActiveRecordTestModule
13
+ class User2 < User; end
14
+ end
data/test/base_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.setup
2
4
  require 'ruby-debug'
3
5
  require 'test/unit'
4
6
  require 'mocha'
@@ -1,3 +1,4 @@
1
+ require 'base_helper'
1
2
  require 'client_side_validations/core_ext'
2
3
 
3
4
  class CoreExtTest < Test::Unit::TestCase
@@ -1,2 +1,7 @@
1
+ # encoding: utf-8
2
+ require 'active_support'
3
+ require 'formtastic/railtie' if defined?(::Rails)
4
+ require 'formtastic/engine' if defined?(::Rails)
1
5
  require 'formtastic'
2
6
  require 'client_side_validations/formtastic'
7
+
@@ -1,11 +1,11 @@
1
1
  require 'formtastic/cases/helper'
2
2
 
3
- class ClientSideValidations::Formtastic::SemanticFormBuilderTest < Test::Unit::TestCase
3
+ class ClientSideValidations::Formtastic::FormBuilderTest < Test::Unit::TestCase
4
4
  def test_client_side_form_js_hash
5
5
  expected = {
6
- :type => 'Formtastic::SemanticFormBuilder',
6
+ :type => 'Formtastic::FormBuilder',
7
7
  :inline_error_class => 'inline-errors'
8
8
  }
9
- assert_equal expected, Formtastic::SemanticFormBuilder.client_side_form_settings(nil, nil)
9
+ assert_equal expected, Formtastic::FormBuilder.client_side_form_settings(nil, nil)
10
10
  end
11
11
  end
@@ -3,7 +3,7 @@ require 'formtastic/cases/helper'
3
3
 
4
4
  class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
5
5
  include ActionViewTestSetup
6
- include Formtastic::SemanticFormHelper
6
+ include Formtastic::Helpers::FormHelper
7
7
 
8
8
  def client_side_form_settings_helper
9
9
  ""
@@ -14,9 +14,8 @@ class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
14
14
  concat f.input(:cost)
15
15
  end
16
16
 
17
- expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic post" data-validate="true" id="edit_post_123" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string required" id="post_cost_input"><label for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validate="true" id="post_cost" name="post[cost]" type="text" /></li></form><script>var edit_post_123 = {"type":"Formtastic::SemanticFormBuilder","inline_error_class":"inline-errors","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
17
+ expected = %{<form accept-charset="UTF-8" action="/posts/123" class="formtastic post" data-validate="true" id="edit_post_123" method="post" novalidate="novalidate"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /><input name="_method" type="hidden" value="put" /></div><li class="string input required stringish" id="post_cost_input"><label class=\" label\" for="post_cost">Cost<abbr title="required">*</abbr></label><input data-validate="true" id="post_cost" name="post[cost]" required=\"required\" type="text" />\n\n</li></form><script>window['edit_post_123'] = {"type":"Formtastic::FormBuilder","inline_error_class":"inline-errors","validators":{"post[cost]":{"presence":{"message":"can't be blank"}}}};</script>}
18
18
  assert_equal expected, output_buffer, "\n\n *** If you're running Ruby 1.8 and this test fails is is most likely due to 1.8's lack of insertion order persistence with Hashes ***\n"
19
19
  end
20
20
 
21
- end
22
-
21
+ end
@@ -0,0 +1,31 @@
1
+ require 'rails/generators/test_case'
2
+ require 'generators/client_side_validations/install_generator'
3
+ require 'generators/client_side_validations/copy_asset_generator'
4
+
5
+ class InstallGeneratorTest < Rails::Generators::TestCase
6
+ tests ClientSideValidations::Generators::InstallGenerator
7
+ destination File.expand_path('../../tmp', __FILE__)
8
+ setup :prepare_destination
9
+
10
+ test 'Assert all files are properly created' do
11
+ run_generator
12
+ assert_file 'config/initializers/client_side_validations.rb'
13
+ assert_file 'public/javascripts/rails.validations.js' if Rails.version > '3.0' && Rails.version < '3.1'
14
+ end
15
+ end
16
+
17
+ class CopyAssetGeneratorTest < Rails::Generators::TestCase
18
+ tests ClientSideValidations::Generators::CopyAssetGenerator
19
+ destination File.expand_path('../../tmp', __FILE__)
20
+ setup :prepare_destination
21
+
22
+ test 'Assert file is properly created' do
23
+ run_generator
24
+ if Rails.version >= '3.1'
25
+ assert_file 'app/assets/javascripts/rails.validations.js'
26
+ else
27
+ assert_file 'public/javascripts/rails.validations.js'
28
+ end
29
+ end
30
+ end
31
+
@@ -1,6 +1,6 @@
1
1
  module('Element Validate After Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Before Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Fail Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Element Validate Pass Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate After Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Before Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Fail Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Form Validate Pass Callback', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,6 +1,6 @@
1
1
  module('Validate Form', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -1,7 +1,7 @@
1
1
  module('Validate Formtastic', {
2
2
  setup: function() {
3
- new_user = {
4
- type: 'Formtastic::SemanticFormBuilder',
3
+ window['new_user'] = {
4
+ type: 'Formtastic::FormBuilder',
5
5
  inline_error_class: 'inline-errors',
6
6
  validators: {
7
7
  "user[name]":{"presence":{"message": "must be present"}, "format":{"message":"is invalid","with":/\d+/}}
@@ -0,0 +1,66 @@
1
+ module('Validate Form', {
2
+ setup: function() {
3
+ window['new_user'] = {
4
+ type: 'NestedForm::Builder',
5
+ input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
7
+ validators: {'user[name]':{"presence":{"message": "must be present"}}}
8
+ }
9
+
10
+ $('#qunit-fixture')
11
+ .append($('<form />', {
12
+ action: '/users',
13
+ 'data-validate': true,
14
+ method: 'post',
15
+ id: 'new_user'
16
+ }))
17
+ .find('form')
18
+ .append($('<input />', {
19
+ name: 'user[name]',
20
+ id: 'user_name',
21
+ 'data-validate': 'true',
22
+ type: 'text'
23
+ }))
24
+ .append($('<label for="user_name">Name</label>'));
25
+ $('form#new_user').validate();
26
+ }
27
+ });
28
+
29
+ asyncTest('Validate form with invalid form', 4, function() {
30
+ var form = $('form#new_user'), input = form.find('input#user_name');
31
+ var label = $('label[for="user_name"]');
32
+
33
+ form.trigger('submit');
34
+ setTimeout(function() {
35
+ start();
36
+ ok(input.parent().hasClass('field_with_errors'));
37
+ ok(label.parent().hasClass('field_with_errors'));
38
+ ok(input.parent().find('label:contains("must be present")')[0]);
39
+ ok(!$('iframe').contents().find('p:contains("Form submitted")')[0]);
40
+ }, 30);
41
+ });
42
+
43
+ asyncTest('Validate form with valid form', 1, function() {
44
+ var form = $('form#new_user'), input = form.find('input#user_name');
45
+ input.val('Test');
46
+
47
+ form.trigger('submit');
48
+ setTimeout(function() {
49
+ start();
50
+ ok($('iframe').contents().find('p:contains("Form submitted")')[0]);
51
+ }, 30);
52
+ });
53
+
54
+ asyncTest('Validate form with an input changed to false', 1, function() {
55
+ var form = $('form#new_user'), input = form.find('input#user_name');
56
+ input.val('Test');
57
+ input.attr('changed', false);
58
+ input.attr('data-valid', true);
59
+
60
+ form.trigger('submit');
61
+ setTimeout(function() {
62
+ start();
63
+ ok($('iframe').contents().find('p:contains("Form submitted")')[0]);
64
+ }, 30);
65
+ });
66
+
@@ -1,6 +1,6 @@
1
1
  module('Validate SimpleForm', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'SimpleForm::FormBuilder',
5
5
  error_class: 'error',
6
6
  error_tag: 'span',
@@ -1,6 +1,6 @@
1
1
  module('Validate Element', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -140,5 +140,40 @@ test('Validate when error message needs to change', function() {
140
140
  input.trigger('change')
141
141
  input.trigger('focusout');
142
142
  equal(input.parent().find('label.message').text(), "is invalid");
143
+ })
144
+
145
+ test("Don't validate confirmation when not a validatable input", function() {
146
+ $('#qunit-fixture')
147
+ .append($('<form />', {
148
+ action: '/users',
149
+ 'data-validate': true,
150
+ method: 'post',
151
+ id: 'new_user_2'
152
+ }))
153
+ .find('form')
154
+ .append($('<label for="user_2_password">Password</label>'))
155
+ .append($('<input />', {
156
+ name: 'user_2[password]',
157
+ id: 'user_2_password',
158
+ type: 'password'
159
+ }))
160
+ .append($('<label for="user_2_password_confirmation">Password Confirmation</label>'))
161
+ .append($('<input />', {
162
+ name: 'user_2[password_confirmation]',
163
+ id: 'user_2_password_confirmation',
164
+ type: 'password'
165
+ }))
166
+ new_user_2 = {
167
+ type: 'ActionView::Helpers::FormBuilder',
168
+ input_tag: '<div class="field_with_errors"><span id="input_tag" /><label for="user_name" class="message"></label></div>',
169
+ label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
170
+ validators: {
171
+ }
172
+ }
173
+ $('form#new_user_2').validate();
174
+ var form = $('form#new_user_2'), input = form.find('input#user_2_password_confirmation');
175
+ input.val('123');
176
+ input.trigger('focusout');
177
+ ok(!input.parent().hasClass('field_with_errors'));
143
178
  });
144
179
 
@@ -27,7 +27,13 @@ test('when allowing blank and allowed length is 3', function() {
27
27
  equal(clientSideValidations.validators.local.length(element, options), undefined);
28
28
  });
29
29
 
30
- test('when allowing blank and allowed length is 3', function() {
30
+ test('when allowing blank and minimum length is 3 and maximum length is 100', function() {
31
+ var element = $('<input type="text" />');
32
+ var options = { messages: { minimum: "failed minimum validation", maximum: "failed maximum validation" }, minimum: 3, maximum: 100, allow_blank: true };
33
+ equal(clientSideValidations.validators.local.length(element, options), undefined);
34
+ });
35
+
36
+ test('when not allowing blank and allowed length is 3', function() {
31
37
  var element = $('<input type="text" />');
32
38
  var options = { messages: { is: "failed validation" }, is: 3 };
33
39
  equal(clientSideValidations.validators.local.length(element, options), "failed validation");
@@ -105,6 +105,13 @@ test('when only allowing values equal to 10 and value is 11', function() {
105
105
  equal(clientSideValidations.validators.local.numericality(element, options), "failed validation");
106
106
  });
107
107
 
108
+ test('when only allowing value equal to 0 and value is 1', function() {
109
+ var element = $('<input type="text" />');
110
+ var options = { messages: { equal_to: "failed validation" }, equal_to: 0 };
111
+ element.val('1');
112
+ equal(clientSideValidations.validators.local.numericality(element, options), "failed validation");
113
+ });
114
+
108
115
  test('when only allowing odd values and the value is odd', function() {
109
116
  var element = $('<input type="text" />');
110
117
  var options = { messages: { odd: "failed validation" }, odd: true };
@@ -13,3 +13,9 @@ test('when value is empty', function() {
13
13
  equal(clientSideValidations.validators.local.presence(element, options), "failed validation");
14
14
  });
15
15
 
16
+ test('when value is null from non-selected multi-select element', function() {
17
+ var element = $('<select multiple="multiple />');
18
+ var options = { message: "failed validation" };
19
+ equal(clientSideValidations.validators.local.presence(element, options), "failed validation");
20
+ });
21
+
@@ -1,6 +1,6 @@
1
1
  module('Uniqueness options', {
2
2
  setup: function() {
3
- new_user = {
3
+ window['new_user'] = {
4
4
  type: 'ActionView::Helpers::FormBuilder',
5
5
  input_tag: '<div class="field_with_errors"><span id="input_tag" /><label class="message"></label></div>',
6
6
  label_tag: '<div class="field_with_errors"><label id="label_tag" /></div>',
@@ -87,3 +87,10 @@ test('when validating by scope and mixed focus order', function() {
87
87
  equal($('.message[for="user_email"]').text(), 'must be unique');
88
88
  });
89
89
 
90
+ test('when matching uniqueness on a resource with a defined class name', function() {
91
+ var element = $('<input type="text" name="user2[email]"/>');
92
+ var options = { 'message': "failed validation", 'class': "active_record_test_module/user2" };
93
+ element.val('nottaken@test.com');
94
+ equal(clientSideValidations.validators.remote.uniqueness(element, options), 'failed validation');
95
+ });
96
+
@@ -2,7 +2,7 @@ require 'sinatra'
2
2
  require 'json'
3
3
  require 'ruby-debug'
4
4
 
5
- use Rack::Static, :urls => ['/javascript'], :root => File.expand_path('../..', settings.root)
5
+ use Rack::Static, :urls => ['/vendor/assets/javascripts'], :root => File.expand_path('../..', settings.root)
6
6
 
7
7
  helpers do
8
8
  def jquery_link version
@@ -43,10 +43,16 @@ get '/' do
43
43
  erb :index
44
44
  end
45
45
 
46
- get '/validators/uniqueness.json' do
46
+ get '/validators/uniqueness' do
47
47
  content_type 'application/json'
48
48
 
49
- if scope = params[:scope]
49
+ if user = params[:user2]
50
+ status 500
51
+ 'error'
52
+ elsif user = params['active_record_test_module/user2']
53
+ status 200
54
+ 'false'
55
+ elsif scope = params[:scope]
50
56
  if scope[:name] == 'test name' || scope[:name] == 'taken name'
51
57
  status 200
52
58
  'false'
@@ -7,7 +7,7 @@
7
7
  <h1 id="qunit-header"><%= @title %></h1>
8
8
  <div id="jquery-version">
9
9
  jQuery version:
10
- <% %w{1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1}.each do |version| %>
10
+ <% %w{1.4.1 1.4.2 1.4.3 1.4.4 1.5 1.5.1 1.6}.each do |version| %>
11
11
  <%= jquery_link version %> •
12
12
  <% end %>
13
13
  <%= jquery_link 'edge' if File.exist?(settings.root + '/public/vendor/jquery.js') %>
@@ -12,7 +12,7 @@
12
12
  </style>
13
13
 
14
14
  <%= script_tag jquery_src %>
15
- <%= script_tag "/javascript/rails.validations.js" %>
15
+ <%= script_tag "/vendor/assets/javascripts/rails.validations.js" %>
16
16
  </head>
17
17
 
18
18
  <body id="body">
@@ -1,4 +1,6 @@
1
1
  require 'base_helper'
2
+ require 'action_controller'
3
+ require 'action_controller/railtie'
2
4
  require 'rails'
3
5
 
4
6
  # Pulled from railties/test/abstract_unit in Rails 3.1
@@ -11,5 +13,6 @@ module TestApp
11
13
  end
12
14
 
13
15
  require 'client_side_validations/middleware'
16
+ require 'client_side_validations/engine'
14
17
 
15
18
  TestApp::Application.initialize!
@@ -0,0 +1,9 @@
1
+ require 'base_helper'
2
+ require 'mongo_mapper'
3
+ require 'client_side_validations/mongo_mapper'
4
+
5
+ MongoMapper.database = "client_side_validations_development"
6
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017)
7
+
8
+ require 'mongo_mapper/models/magazine'
9
+