af-client_side_validations 3.1.4.af1
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/client_side_validations.gemspec +34 -0
- data/lib/client_side_validations/action_view/form_builder.rb +160 -0
- data/lib/client_side_validations/action_view/form_helper.rb +92 -0
- data/lib/client_side_validations/action_view/form_tag_helper.rb +12 -0
- data/lib/client_side_validations/action_view.rb +14 -0
- data/lib/client_side_validations/active_model/acceptance.rb +10 -0
- data/lib/client_side_validations/active_model/exclusion.rb +15 -0
- data/lib/client_side_validations/active_model/format.rb +10 -0
- data/lib/client_side_validations/active_model/inclusion.rb +15 -0
- data/lib/client_side_validations/active_model/length.rb +24 -0
- data/lib/client_side_validations/active_model/numericality.rb +31 -0
- data/lib/client_side_validations/active_model/presence.rb +10 -0
- data/lib/client_side_validations/active_model.rb +60 -0
- data/lib/client_side_validations/active_record/middleware.rb +33 -0
- data/lib/client_side_validations/active_record/uniqueness.rb +28 -0
- data/lib/client_side_validations/active_record.rb +11 -0
- data/lib/client_side_validations/core_ext/range.rb +10 -0
- data/lib/client_side_validations/core_ext/regexp.rb +14 -0
- data/lib/client_side_validations/core_ext.rb +3 -0
- data/lib/client_side_validations/engine.rb +6 -0
- data/lib/client_side_validations/files.rb +8 -0
- data/lib/client_side_validations/formtastic.rb +21 -0
- data/lib/client_side_validations/middleware.rb +81 -0
- data/lib/client_side_validations/mongo_mapper/middleware.rb +20 -0
- data/lib/client_side_validations/mongo_mapper/uniqueness.rb +28 -0
- data/lib/client_side_validations/mongo_mapper.rb +9 -0
- data/lib/client_side_validations/mongoid/middleware.rb +20 -0
- data/lib/client_side_validations/mongoid/uniqueness.rb +28 -0
- data/lib/client_side_validations/mongoid.rb +9 -0
- data/lib/client_side_validations/simple_form.rb +24 -0
- data/lib/client_side_validations/version.rb +3 -0
- data/lib/client_side_validations.rb +13 -0
- data/lib/generators/client_side_validations/copy_asset_generator.rb +36 -0
- data/lib/generators/client_side_validations/install_generator.rb +45 -0
- data/lib/generators/templates/client_side_validations/README.rails.3.0 +6 -0
- data/lib/generators/templates/client_side_validations/README.rails.3.1 +7 -0
- data/lib/generators/templates/client_side_validations/initializer.rb +14 -0
- data/test/action_view/cases/helper.rb +176 -0
- data/test/action_view/cases/test_helpers.rb +666 -0
- data/test/action_view/cases/test_legacy_helpers.rb +217 -0
- data/test/action_view/models/comment.rb +35 -0
- data/test/action_view/models/post.rb +35 -0
- data/test/action_view/models.rb +3 -0
- data/test/active_model/cases/helper.rb +4 -0
- data/test/active_model/cases/test_acceptance_validator.rb +16 -0
- data/test/active_model/cases/test_base.rb +11 -0
- data/test/active_model/cases/test_confirmation_validator.rb +16 -0
- data/test/active_model/cases/test_exclusion_validator.rb +20 -0
- data/test/active_model/cases/test_format_validator.rb +21 -0
- data/test/active_model/cases/test_inclusion_validator.rb +21 -0
- data/test/active_model/cases/test_length_validator.rb +61 -0
- data/test/active_model/cases/test_numericality_validator.rb +46 -0
- data/test/active_model/cases/test_presence_validator.rb +16 -0
- data/test/active_model/cases/test_validations.rb +175 -0
- data/test/active_model/models/person.rb +17 -0
- data/test/active_record/cases/helper.rb +12 -0
- data/test/active_record/cases/test_base.rb +11 -0
- data/test/active_record/cases/test_middleware.rb +175 -0
- data/test/active_record/cases/test_uniqueness_validator.rb +50 -0
- data/test/active_record/models/guid.rb +7 -0
- data/test/active_record/models/user.rb +14 -0
- data/test/base_helper.rb +7 -0
- data/test/core_ext/cases/test_core_ext.rb +46 -0
- data/test/formtastic/cases/helper.rb +7 -0
- data/test/formtastic/cases/test_form_builder.rb +11 -0
- data/test/formtastic/cases/test_form_helper.rb +21 -0
- data/test/generators/cases/test_generators.rb +70 -0
- data/test/javascript/config.ru +3 -0
- data/test/javascript/public/test/callbacks/elementAfter.js +54 -0
- data/test/javascript/public/test/callbacks/elementBefore.js +54 -0
- data/test/javascript/public/test/callbacks/elementFail.js +70 -0
- data/test/javascript/public/test/callbacks/elementPass.js +70 -0
- data/test/javascript/public/test/callbacks/formAfter.js +45 -0
- data/test/javascript/public/test/callbacks/formBefore.js +45 -0
- data/test/javascript/public/test/callbacks/formFail.js +51 -0
- data/test/javascript/public/test/callbacks/formPass.js +50 -0
- data/test/javascript/public/test/form_builders/validateForm.js +66 -0
- data/test/javascript/public/test/form_builders/validateFormtastic.js +54 -0
- data/test/javascript/public/test/form_builders/validateNestedForm.js +66 -0
- data/test/javascript/public/test/form_builders/validateSimpleForm.js +57 -0
- data/test/javascript/public/test/settings.js +15 -0
- data/test/javascript/public/test/validateElement.js +209 -0
- data/test/javascript/public/test/validators/acceptance.js +42 -0
- data/test/javascript/public/test/validators/confirmation.js +25 -0
- data/test/javascript/public/test/validators/exclusion.js +41 -0
- data/test/javascript/public/test/validators/format.js +27 -0
- data/test/javascript/public/test/validators/inclusion.js +42 -0
- data/test/javascript/public/test/validators/length.js +76 -0
- data/test/javascript/public/test/validators/numericality.js +158 -0
- data/test/javascript/public/test/validators/presence.js +21 -0
- data/test/javascript/public/test/validators/uniqueness.js +107 -0
- data/test/javascript/public/vendor/jquery.metadata.js +122 -0
- data/test/javascript/public/vendor/qunit.css +196 -0
- data/test/javascript/public/vendor/qunit.js +1374 -0
- data/test/javascript/server.rb +84 -0
- data/test/javascript/views/index.erb +20 -0
- data/test/javascript/views/layout.erb +21 -0
- data/test/middleware/cases/helper.rb +18 -0
- data/test/middleware/cases/test_middleware.rb +8 -0
- data/test/mongo_mapper/cases/helper.rb +9 -0
- data/test/mongo_mapper/cases/test_base.rb +15 -0
- data/test/mongo_mapper/cases/test_middleware.rb +77 -0
- data/test/mongo_mapper/cases/test_uniqueness_validator.rb +50 -0
- data/test/mongo_mapper/models/magazine.rb +11 -0
- data/test/mongoid/cases/helper.rb +16 -0
- data/test/mongoid/cases/test_base.rb +15 -0
- data/test/mongoid/cases/test_middleware.rb +77 -0
- data/test/mongoid/cases/test_uniqueness_validator.rb +49 -0
- data/test/mongoid/models/book.rb +12 -0
- data/test/simple_form/cases/helper.rb +5 -0
- data/test/simple_form/cases/test_form_builder.rb +14 -0
- data/test/simple_form/cases/test_form_helper.rb +24 -0
- data/test/test_loader.rb +6 -0
- data/vendor/assets/javascripts/rails.validations.js +418 -0
- metadata +436 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require 'active_model/cases/test_base'
|
|
2
|
+
|
|
3
|
+
class ActiveModel::ValidationsTest < ClientSideValidations::ActiveModelTestBase
|
|
4
|
+
|
|
5
|
+
class Person
|
|
6
|
+
include ::ActiveModel::Validations
|
|
7
|
+
attr_accessor :first_name, :last_name, :age, :weight
|
|
8
|
+
|
|
9
|
+
def self.name
|
|
10
|
+
"Person"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def new_record?
|
|
14
|
+
true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def new_person
|
|
19
|
+
person = Class.new(Person)
|
|
20
|
+
yield(person)
|
|
21
|
+
person.new
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_validations_to_client_side_hash
|
|
25
|
+
person = new_person do |p|
|
|
26
|
+
p.validates_presence_of :first_name
|
|
27
|
+
end
|
|
28
|
+
expected_hash = {
|
|
29
|
+
:first_name => {
|
|
30
|
+
:presence => {
|
|
31
|
+
:message => "can't be blank"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_validations_to_client_side_hash_with_validations_allow_blank
|
|
39
|
+
person = new_person do |p|
|
|
40
|
+
p.validates_length_of :first_name, :is => 10, :allow_blank => true
|
|
41
|
+
p.validates_format_of :first_name, :with => //, :allow_blank => true
|
|
42
|
+
end
|
|
43
|
+
expected_hash = {
|
|
44
|
+
:first_name => {
|
|
45
|
+
:length => {
|
|
46
|
+
:messages => { :is => 'is the wrong length (should be 10 characters)'},
|
|
47
|
+
:is => 10,
|
|
48
|
+
:allow_blank => true
|
|
49
|
+
},
|
|
50
|
+
:format => {
|
|
51
|
+
:message => 'is invalid',
|
|
52
|
+
:with => //,
|
|
53
|
+
:allow_blank => true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def test_validations_to_client_side_hash_with_validations_on_create
|
|
61
|
+
person = new_person do |p|
|
|
62
|
+
p.validates_length_of :first_name, :is => 10, :on => :create
|
|
63
|
+
p.validates_length_of :last_name, :is => 10, :on => :update
|
|
64
|
+
p.validates_format_of :first_name, :with => //, :on => :update
|
|
65
|
+
p.validates_format_of :last_name, :with => //, :on => :create
|
|
66
|
+
p.validates_numericality_of :age, :on => :create
|
|
67
|
+
p.validates_numericality_of :weight, :on => :update
|
|
68
|
+
p.class_eval do
|
|
69
|
+
def new_record?
|
|
70
|
+
true
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
expected_hash = {
|
|
75
|
+
:first_name => {
|
|
76
|
+
:length => {
|
|
77
|
+
:messages => { :is => 'is the wrong length (should be 10 characters)'},
|
|
78
|
+
:is => 10,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
:last_name => {
|
|
82
|
+
:format => {
|
|
83
|
+
:message => 'is invalid',
|
|
84
|
+
:with => //,
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
:age => {
|
|
88
|
+
:numericality => {
|
|
89
|
+
:messages => { :numericality => 'is not a number' },
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_validations_to_client_side_hash_with_validations_on_update
|
|
97
|
+
person = new_person do |p|
|
|
98
|
+
p.validates_length_of :first_name, :is => 10, :on => :update
|
|
99
|
+
p.validates_length_of :last_name, :is => 10, :on => :create
|
|
100
|
+
p.validates_format_of :first_name, :with => //, :on => :create
|
|
101
|
+
p.validates_format_of :last_name, :with => //, :on => :update
|
|
102
|
+
p.validates_numericality_of :age, :on => :update
|
|
103
|
+
p.validates_numericality_of :weight, :on => :create
|
|
104
|
+
p.class_eval do
|
|
105
|
+
def new_record?
|
|
106
|
+
false
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
expected_hash = {
|
|
111
|
+
:first_name => {
|
|
112
|
+
:length => {
|
|
113
|
+
:messages => { :is => 'is the wrong length (should be 10 characters)'},
|
|
114
|
+
:is => 10,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
:last_name => {
|
|
118
|
+
:format => {
|
|
119
|
+
:message => 'is invalid',
|
|
120
|
+
:with => //,
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
:age => {
|
|
124
|
+
:numericality => {
|
|
125
|
+
:messages => { :numericality => 'is not a number' },
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def test_validates_with_should_be_ignored
|
|
133
|
+
person = new_person do |p|
|
|
134
|
+
p.validates_with PersonValidator
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
expected_hash = {}
|
|
138
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_generic_block_validators_should_be_ignored
|
|
142
|
+
person = new_person do |p|
|
|
143
|
+
p.validates_each(:first_name) do |record, attr, value|
|
|
144
|
+
record.errors.add(:first_name, "failed")
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
expected_hash = {}
|
|
149
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def test_conditionals_persist_on_validator
|
|
153
|
+
person = new_person do |p|
|
|
154
|
+
p.validates :first_name, :presence => { :if => :can_validate? }
|
|
155
|
+
p.validates :last_name, :presence => { :unless => :cannot_validate? }
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
expected_hash = {
|
|
159
|
+
:first_name => {
|
|
160
|
+
:presence => {
|
|
161
|
+
:message => "can't be blank",
|
|
162
|
+
:if => :can_validate?
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
:last_name => {
|
|
166
|
+
:presence => {
|
|
167
|
+
:message => "can't be blank",
|
|
168
|
+
:unless => :cannot_validate?
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
assert_equal expected_hash, person.client_side_validation_hash
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class PersonValidator < ActiveModel::Validator
|
|
2
|
+
def validate(record)
|
|
3
|
+
end
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
class Person
|
|
7
|
+
include ActiveModel::Validations
|
|
8
|
+
|
|
9
|
+
attr_accessor :first_name, :last_name, :email, :age
|
|
10
|
+
|
|
11
|
+
validates_presence_of :first_name
|
|
12
|
+
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
|
13
|
+
|
|
14
|
+
def new_record?
|
|
15
|
+
true
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
require 'base_helper'
|
|
2
|
+
require 'active_record'
|
|
3
|
+
require 'client_side_validations/active_record'
|
|
4
|
+
|
|
5
|
+
# Connection must be establised before anything else
|
|
6
|
+
ActiveRecord::Base.establish_connection(
|
|
7
|
+
:adapter => defined?(JRUBY_VERSION) ? 'jdbcsqlite3' : 'sqlite3',
|
|
8
|
+
:database => ':memory:'
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
require 'active_record/models/user'
|
|
12
|
+
require 'active_record/models/guid'
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'middleware/cases/helper'
|
|
4
|
+
require 'active_record/cases/helper'
|
|
5
|
+
|
|
6
|
+
class ClientSideValidationsActiveRecordMiddlewareTest < Test::Unit::TestCase
|
|
7
|
+
include Rack::Test::Methods
|
|
8
|
+
|
|
9
|
+
def teardown
|
|
10
|
+
User.delete_all
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def with_kcode(kcode)
|
|
14
|
+
if RUBY_VERSION < '1.9'
|
|
15
|
+
orig_kcode, $KCODE = $KCODE, kcode
|
|
16
|
+
begin
|
|
17
|
+
yield
|
|
18
|
+
ensure
|
|
19
|
+
$KCODE = orig_kcode
|
|
20
|
+
end
|
|
21
|
+
else
|
|
22
|
+
yield
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def app
|
|
27
|
+
app = Proc.new { |env| [200, {}, ['success']] }
|
|
28
|
+
ClientSideValidations::Middleware::Validators.new(app)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_uniqueness_when_resource_exists
|
|
32
|
+
User.create(:email => 'user@test.com')
|
|
33
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
|
|
34
|
+
|
|
35
|
+
assert_equal 'false', last_response.body
|
|
36
|
+
assert last_response.ok?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_uniqueness_when_resource_exists_and_param_order_is_backwards
|
|
40
|
+
User.create(:email => 'user@test.com')
|
|
41
|
+
get '/validators/uniqueness', { 'case_sensitive' => true, 'user[email]' => 'user@test.com' }
|
|
42
|
+
|
|
43
|
+
assert_equal 'false', last_response.body
|
|
44
|
+
assert last_response.ok?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_uniqueness_when_resource_does_not_exist
|
|
48
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'case_sensitive' => true }
|
|
49
|
+
|
|
50
|
+
assert_equal 'true', last_response.body
|
|
51
|
+
assert last_response.not_found?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_uniqueness_when_id_is_given
|
|
55
|
+
user = User.create(:email => 'user@test.com')
|
|
56
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'id' => user.id, 'case_sensitive' => true }
|
|
57
|
+
|
|
58
|
+
assert_equal 'true', last_response.body
|
|
59
|
+
assert last_response.not_found?
|
|
60
|
+
end
|
|
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
|
+
|
|
80
|
+
def test_uniqueness_when_scope_is_given
|
|
81
|
+
User.create(:email => 'user@test.com', :age => 25)
|
|
82
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30 }, 'case_sensitive' => true }
|
|
83
|
+
|
|
84
|
+
assert_equal 'true', last_response.body
|
|
85
|
+
assert last_response.not_found?
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def test_uniqueness_when_multiple_scopes_are_given
|
|
89
|
+
User.create(:email => 'user@test.com', :age => 30, :name => 'Brian')
|
|
90
|
+
get '/validators/uniqueness', { 'user[email]' => 'user@test.com', 'scope' => { 'age' => 30, 'name' => 'Robert' }, 'case_sensitive' => true }
|
|
91
|
+
|
|
92
|
+
assert_equal 'true', last_response.body
|
|
93
|
+
assert last_response.not_found?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def test_uniqueness_when_case_insensitive
|
|
97
|
+
User.create(:name => 'Brian')
|
|
98
|
+
get '/validators/uniqueness', { 'user[name]' => 'BRIAN', 'case_sensitive' => false }
|
|
99
|
+
|
|
100
|
+
assert_equal 'false', last_response.body
|
|
101
|
+
assert last_response.ok?
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_uniqueness_when_attribute_passes_as_an_integer
|
|
105
|
+
User.create(:name => 123)
|
|
106
|
+
get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
|
|
107
|
+
|
|
108
|
+
assert_equal 'false', last_response.body
|
|
109
|
+
assert last_response.ok?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_uniqueness_when_attribute_passes_as_an_integer
|
|
113
|
+
User.create(:name => 123)
|
|
114
|
+
get '/validators/uniqueness', { 'user[name]' => 123, 'case_sensitive' => true }
|
|
115
|
+
|
|
116
|
+
assert_equal 'false', last_response.body
|
|
117
|
+
assert last_response.ok?
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def test_uniqueness_with_columns_which_are_sql_keywords
|
|
121
|
+
Guid.validates_uniqueness_of :key
|
|
122
|
+
assert_nothing_raised do
|
|
123
|
+
get '/validators/uniqueness', { 'guid[key]' => 'test', 'case_sensitive' => true }
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_uniqueness_with_limit
|
|
128
|
+
# User.title is limited to 5 characters
|
|
129
|
+
User.create(:title => "abcde")
|
|
130
|
+
get '/validators/uniqueness', { 'user[title]' => 'abcdefgh', 'case_sensitive' => true }
|
|
131
|
+
|
|
132
|
+
assert_equal 'false', last_response.body
|
|
133
|
+
assert last_response.ok?
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_uniqueness_with_limit_and_utf8
|
|
137
|
+
with_kcode('UTF8') do
|
|
138
|
+
# User.title is limited to 5 characters
|
|
139
|
+
User.create(:title => "一二三四五")
|
|
140
|
+
get '/validators/uniqueness', { 'user[title]' => '一二三四五六七八', 'case_sensitive' => true }
|
|
141
|
+
|
|
142
|
+
assert_equal 'false', last_response.body
|
|
143
|
+
assert last_response.ok?
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def test_validate_straight_inheritance_uniqueness
|
|
148
|
+
get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
149
|
+
assert_equal 'true', last_response.body
|
|
150
|
+
assert last_response.not_found?
|
|
151
|
+
|
|
152
|
+
IneptWizard.create(:name => 'Rincewind')
|
|
153
|
+
get '/validators/uniqueness', { 'inept_wizard[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
154
|
+
assert_equal 'false', last_response.body
|
|
155
|
+
assert last_response.ok?
|
|
156
|
+
|
|
157
|
+
get '/validators/uniqueness', { 'conjurer[name]' => 'Rincewind', 'case_sensitive' => true }
|
|
158
|
+
assert_equal 'false', last_response.body
|
|
159
|
+
assert last_response.ok?
|
|
160
|
+
|
|
161
|
+
Conjurer.create(:name => 'The Amazing Bonko')
|
|
162
|
+
get '/validators/uniqueness', { 'thaumaturgist[name]' => 'The Amazing Bonko', 'case_sensitive' => true }
|
|
163
|
+
assert_equal 'false', last_response.body
|
|
164
|
+
assert last_response.ok?
|
|
165
|
+
end
|
|
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
|
|
174
|
+
end
|
|
175
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'active_record/cases/test_base'
|
|
2
|
+
|
|
3
|
+
class ActiveRecord::UniquenessValidatorTest < ClientSideValidations::ActiveRecordTestBase
|
|
4
|
+
|
|
5
|
+
def test_uniqueness_client_side_hash
|
|
6
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true }
|
|
7
|
+
assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@user, :name)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_uniqueness_client_side_hash_with_custom_message
|
|
11
|
+
expected_hash = { :message => "is not available", :case_sensitive => true }
|
|
12
|
+
assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name], :message => "is not available").client_side_hash(@user, :name)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def test_uniqueness_client_side_hash
|
|
16
|
+
@user.stubs(:new_record?).returns(false)
|
|
17
|
+
@user.stubs(:id).returns(1)
|
|
18
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true, :id => 1 }
|
|
19
|
+
assert_equal expected_hash, UniquenessValidator.new(:attributes => [:name]).client_side_hash(@user, :name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_uniqueness_client_side_hash_with_single_scope_item
|
|
23
|
+
@user.stubs(:age).returns(30)
|
|
24
|
+
@user.stubs(:title).returns("test title")
|
|
25
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true, :scope => {:title => "test title"} }
|
|
26
|
+
result_hash = UniquenessValidator.new(:attributes => [:name], :scope => :title).client_side_hash(@user, :name)
|
|
27
|
+
assert_equal expected_hash, result_hash
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_uniqueness_client_side_hash_with_multiple_scope_items
|
|
31
|
+
@user.stubs(:age).returns(30)
|
|
32
|
+
@user.stubs(:title).returns("test title")
|
|
33
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true, :scope => {:age => 30, :title => "test title"} }
|
|
34
|
+
result_hash = UniquenessValidator.new(:attributes => [:name], :scope => [:age, :title]).client_side_hash(@user, :name)
|
|
35
|
+
assert_equal expected_hash, result_hash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_uniqueness_client_side_hash_with_empty_scope_array
|
|
39
|
+
expected_hash = { :message => "has already been taken", :case_sensitive => true }
|
|
40
|
+
result_hash = UniquenessValidator.new(:attributes => [:name], :scope => []).client_side_hash(@user, :name)
|
|
41
|
+
assert_equal expected_hash, result_hash
|
|
42
|
+
end
|
|
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
|
|
49
|
+
end
|
|
50
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
users_table = %{CREATE TABLE users (id INTEGER PRIMARY KEY, age INTEGER, name TEXT, email TEXT, title VARCHAR(5));}
|
|
2
|
+
ActiveRecord::Base.connection.execute(users_table)
|
|
3
|
+
|
|
4
|
+
class User < ActiveRecord::Base
|
|
5
|
+
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class IneptWizard < User; end
|
|
9
|
+
class Conjurer < IneptWizard; end
|
|
10
|
+
class Thaumaturgist < Conjurer; end
|
|
11
|
+
|
|
12
|
+
module ActiveRecordTestModule
|
|
13
|
+
class User2 < User; end
|
|
14
|
+
end
|
data/test/base_helper.rb
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'base_helper'
|
|
2
|
+
require 'client_side_validations/core_ext'
|
|
3
|
+
|
|
4
|
+
class CoreExtTest < Test::Unit::TestCase
|
|
5
|
+
def test_regexp_as_json
|
|
6
|
+
regexp = //
|
|
7
|
+
assert_equal regexp, regexp.as_json
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def test_regexp_replace_A_and_Z
|
|
11
|
+
test_regexp = /\A\Z/
|
|
12
|
+
expected_regexp = /^$/
|
|
13
|
+
assert_equal expected_regexp, test_regexp.as_json
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_regexp_replace_a_and_z
|
|
17
|
+
test_regexp = /\A\z/
|
|
18
|
+
expected_regexp = /^$/
|
|
19
|
+
assert_equal expected_regexp, test_regexp.as_json
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_regexp_to_json
|
|
23
|
+
assert_equal "/^$/", /\A\Z/.to_json(nil)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_regexp_encode_json
|
|
27
|
+
assert_equal "//", //.encode_json(nil)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_regexp_as_jason_with_options
|
|
31
|
+
assert_equal //i, //i.as_json
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_range_as_json
|
|
35
|
+
assert_equal [1,3], (1..3).as_json
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_range_to_json
|
|
39
|
+
assert_equal '[1, 3]', (1..3).to_json(nil)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_range_as_json_with_floats
|
|
43
|
+
assert_equal [0.5,5.5], (0.5..5.5).as_json
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'formtastic/cases/helper'
|
|
2
|
+
|
|
3
|
+
class ClientSideValidations::Formtastic::FormBuilderTest < Test::Unit::TestCase
|
|
4
|
+
def test_client_side_form_js_hash
|
|
5
|
+
expected = {
|
|
6
|
+
:type => 'Formtastic::FormBuilder',
|
|
7
|
+
:inline_error_class => 'inline-errors'
|
|
8
|
+
}
|
|
9
|
+
assert_equal expected, Formtastic::FormBuilder.client_side_form_settings(nil, nil)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'action_view/cases/helper'
|
|
2
|
+
require 'formtastic/cases/helper'
|
|
3
|
+
|
|
4
|
+
class ClientSideValidations::Formtastic::FormHelperTest < ActionView::TestCase
|
|
5
|
+
include ActionViewTestSetup
|
|
6
|
+
include Formtastic::Helpers::FormHelper
|
|
7
|
+
|
|
8
|
+
def client_side_form_settings_helper
|
|
9
|
+
""
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_semantic_form_for
|
|
13
|
+
semantic_form_for(@post, :validate => true) do |f|
|
|
14
|
+
concat f.input(:cost)
|
|
15
|
+
end
|
|
16
|
+
|
|
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="✓" /><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]" 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
|
+
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
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
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 when no asset pipeline present' do
|
|
11
|
+
stub_configuration
|
|
12
|
+
run_generator
|
|
13
|
+
assert_file 'config/initializers/client_side_validations.rb'
|
|
14
|
+
assert_file 'public/javascripts/rails.validations.js'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
test 'Assert all files are properly created when asset pipeline present and disabled' do
|
|
18
|
+
stub_configuration
|
|
19
|
+
Rails.configuration.stubs(:assets).returns({})
|
|
20
|
+
Rails.configuration.assets[:enabled] = false
|
|
21
|
+
run_generator
|
|
22
|
+
assert_file 'config/initializers/client_side_validations.rb'
|
|
23
|
+
assert_file 'public/javascripts/rails.validations.js'
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
test 'Assert all files are properly created when asset pipeline present and enabled' do
|
|
27
|
+
stub_configuration
|
|
28
|
+
Rails.configuration.stubs(:assets).returns({})
|
|
29
|
+
Rails.configuration.assets[:enabled] = true
|
|
30
|
+
run_generator
|
|
31
|
+
assert_file 'config/initializers/client_side_validations.rb'
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def stub_configuration
|
|
35
|
+
Rails.stubs(:configuration).returns(mock('Configuration'))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
class CopyAssetGeneratorTest < Rails::Generators::TestCase
|
|
40
|
+
tests ClientSideValidations::Generators::CopyAssetGenerator
|
|
41
|
+
destination File.expand_path('../../tmp', __FILE__)
|
|
42
|
+
setup :prepare_destination
|
|
43
|
+
|
|
44
|
+
test 'Assert file is properly created when no asset pipeline present' do
|
|
45
|
+
stub_configuration
|
|
46
|
+
run_generator
|
|
47
|
+
assert_file 'public/javascripts/rails.validations.js'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
test 'Assert file is properly created when asset pipeline present and disabled' do
|
|
51
|
+
stub_configuration
|
|
52
|
+
Rails.configuration.stubs(:assets).returns({})
|
|
53
|
+
Rails.configuration.assets[:enabled] = false
|
|
54
|
+
run_generator
|
|
55
|
+
assert_file 'public/javascripts/rails.validations.js'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
test 'Assert file is properly created when asset pipeline present and enabled' do
|
|
59
|
+
stub_configuration
|
|
60
|
+
Rails.configuration.stubs(:assets).returns({})
|
|
61
|
+
Rails.configuration.assets[:enabled] = true
|
|
62
|
+
run_generator
|
|
63
|
+
assert_file 'app/assets/javascripts/rails.validations.js'
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def stub_configuration
|
|
67
|
+
Rails.stubs(:configuration).returns(mock('Configuration'))
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|