ar-validations-json 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/Gemfile +8 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +11 -0
- data/Rakefile +36 -0
- data/VERSION +1 -0
- data/ar-validations-json.gemspec +61 -0
- data/lib/ar-validations-json.rb +82 -0
- data/test/test_helper.rb +38 -0
- data/test/unit/acceptance_test.rb +89 -0
- data/test/unit/associated_test.rb +18 -0
- data/test/unit/confirmation_test.rb +20 -0
- data/test/unit/exclusion_test.rb +50 -0
- data/test/unit/format_test.rb +49 -0
- data/test/unit/inclusion_test.rb +25 -0
- data/test/unit/length_test.rb +73 -0
- data/test/unit/numericality_test.rb +75 -0
- data/test/unit/presence_test.rb +11 -0
- data/test/unit/uniqueness_test.rb +46 -0
- metadata +94 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (3.0.12)
|
5
|
+
activesupport (= 3.0.12)
|
6
|
+
builder (~> 2.1.2)
|
7
|
+
i18n (~> 0.5.0)
|
8
|
+
activerecord (3.0.12)
|
9
|
+
activemodel (= 3.0.12)
|
10
|
+
activesupport (= 3.0.12)
|
11
|
+
arel (~> 2.0.10)
|
12
|
+
tzinfo (~> 0.3.23)
|
13
|
+
activesupport (3.0.12)
|
14
|
+
arel (2.0.10)
|
15
|
+
builder (2.1.2)
|
16
|
+
i18n (0.5.0)
|
17
|
+
sqlite3 (1.3.5)
|
18
|
+
tzinfo (0.3.32)
|
19
|
+
|
20
|
+
PLATFORMS
|
21
|
+
ruby
|
22
|
+
|
23
|
+
DEPENDENCIES
|
24
|
+
activerecord (= 3.0.12)
|
25
|
+
activesupport (= 3.0.12)
|
26
|
+
sqlite3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Francis Hwang
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
ar-validations-json
|
2
|
+
===================
|
3
|
+
|
4
|
+
A library that serializes ActiveRecord validations into JSON, to be used
|
5
|
+
by rich-client apps in helping them do some validation work before
|
6
|
+
trying to send data to the Rails server.
|
7
|
+
|
8
|
+
The goal is to keep validation logic in one place -- the server -- while
|
9
|
+
also allowing clients to know about that validation logic and use it for
|
10
|
+
better user feedback and fewer wasted HTTP requests.
|
11
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
|
4
|
+
Rake::TestTask.new do |t|
|
5
|
+
t.test_files = FileList['test/unit/*_test.rb']
|
6
|
+
t.verbose = true
|
7
|
+
end
|
8
|
+
|
9
|
+
ActiveRecordVersions = %w(3.2.2 3.1.4 3.0.12)
|
10
|
+
|
11
|
+
desc "Run all tests for all supported versions of ActiveRecord"
|
12
|
+
task :all_tests do
|
13
|
+
ActiveRecordVersions.each do |ar_version|
|
14
|
+
cmd = "ACTIVE_RECORD_VERSION=#{ar_version} rake test"
|
15
|
+
puts cmd
|
16
|
+
puts `cd . && #{cmd}`
|
17
|
+
puts
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => :all_tests
|
22
|
+
|
23
|
+
require 'jeweler'
|
24
|
+
Jeweler::Tasks.new do |gem|
|
25
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
26
|
+
gem.name = "ar-validations-json"
|
27
|
+
gem.homepage = "http://github.com/fhwang/ar-validations-json"
|
28
|
+
gem.license = "MIT"
|
29
|
+
gem.summary = %Q{Serializes ActiveRecord validations into JSON for use by rich-client apps.}
|
30
|
+
gem.description = %Q{Serializes ActiveRecord validations into JSON for use by rich-client apps.}
|
31
|
+
gem.email = "sera@fhwang.net"
|
32
|
+
gem.authors = ["Francis Hwang"]
|
33
|
+
# dependencies defined in Gemfile
|
34
|
+
end
|
35
|
+
Jeweler::RubygemsDotOrgTasks.new
|
36
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "ar-validations-json"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Francis Hwang"]
|
12
|
+
s.date = "2012-04-03"
|
13
|
+
s.description = "Serializes ActiveRecord validations into JSON for use by rich-client apps."
|
14
|
+
s.email = "sera@fhwang.net"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"LICENSE.txt",
|
23
|
+
"README.markdown",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"ar-validations-json.gemspec",
|
27
|
+
"lib/ar-validations-json.rb",
|
28
|
+
"test/test_helper.rb",
|
29
|
+
"test/unit/acceptance_test.rb",
|
30
|
+
"test/unit/associated_test.rb",
|
31
|
+
"test/unit/confirmation_test.rb",
|
32
|
+
"test/unit/exclusion_test.rb",
|
33
|
+
"test/unit/format_test.rb",
|
34
|
+
"test/unit/inclusion_test.rb",
|
35
|
+
"test/unit/length_test.rb",
|
36
|
+
"test/unit/numericality_test.rb",
|
37
|
+
"test/unit/presence_test.rb",
|
38
|
+
"test/unit/uniqueness_test.rb"
|
39
|
+
]
|
40
|
+
s.homepage = "http://github.com/fhwang/ar-validations-json"
|
41
|
+
s.licenses = ["MIT"]
|
42
|
+
s.require_paths = ["lib"]
|
43
|
+
s.rubygems_version = "1.8.17"
|
44
|
+
s.summary = "Serializes ActiveRecord validations into JSON for use by rich-client apps."
|
45
|
+
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<activesupport>, [">= 0"])
|
52
|
+
else
|
53
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
54
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
55
|
+
end
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
58
|
+
s.add_dependency(%q<activesupport>, [">= 0"])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ValidationsJson
|
3
|
+
def self.included(mod)
|
4
|
+
mod.extend(ClassMethods)
|
5
|
+
super
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
def validations_json
|
10
|
+
Serializer.new(self).to_json
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Serializer
|
15
|
+
def initialize(ar_class)
|
16
|
+
@ar_class = ar_class
|
17
|
+
end
|
18
|
+
|
19
|
+
def default_to_skip?(validator, option)
|
20
|
+
case validator
|
21
|
+
when ActiveModel::Validations::NumericalityValidator
|
22
|
+
case option
|
23
|
+
when 'allow_nil'
|
24
|
+
validator.options[option.to_sym] == false
|
25
|
+
when 'only_integer'
|
26
|
+
validator.options[option.to_sym] == false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def serializable?(validator)
|
32
|
+
options_that_might_be_procs = {
|
33
|
+
:in => nil, :tokenizer => %r|/active_model/validations/length.rb$|,
|
34
|
+
:with => nil
|
35
|
+
}
|
36
|
+
!options_that_might_be_procs.any? { |option, whitelisted_source|
|
37
|
+
(opt_value = validator.options[option]) && opt_value.is_a?(Proc) &&
|
38
|
+
(whitelisted_source.nil? or
|
39
|
+
opt_value.source_location.first !~ whitelisted_source)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_json
|
44
|
+
json_hash = Hash.new { |h,k| h[k] = {} }
|
45
|
+
@ar_class.validators.each do |validator|
|
46
|
+
if serializable?(validator)
|
47
|
+
label = validator.class.name.split(/::/).last.
|
48
|
+
underscore.split(/_/).first
|
49
|
+
validator.attributes.each do |attr|
|
50
|
+
json_hash[attr.to_s][label] = validator_hash(validator)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
json_hash.to_json
|
55
|
+
end
|
56
|
+
|
57
|
+
def validator_hash(validator)
|
58
|
+
validator_hash = {}
|
59
|
+
validator_options_to_try_copying.each do |option|
|
60
|
+
if validator.options.has_key?(option.to_sym)
|
61
|
+
unless default_to_skip?(validator, option)
|
62
|
+
validator_hash[option] = validator.options[option.to_sym]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
validator_hash = true if validator_hash.empty?
|
67
|
+
validator_hash
|
68
|
+
end
|
69
|
+
|
70
|
+
def validator_options_to_try_copying
|
71
|
+
%w(
|
72
|
+
accept allow_blank allow_nil case_sensitive greater_than
|
73
|
+
greater_than_or_equal_to equal_to even in is less_than
|
74
|
+
less_than_or_equal_to maximum message minimum odd on only_integer
|
75
|
+
scope too_long too_short with without wrong_length
|
76
|
+
)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
ActiveRecord::Base.send(:include, ActiveRecord::ValidationsJson)
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
ENV["RAILS_ENV"] = "test"
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler'
|
4
|
+
begin
|
5
|
+
Bundler.setup(:default, :test)
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'active_record'
|
12
|
+
require 'active_record/base'
|
13
|
+
require 'json'
|
14
|
+
require 'logger'
|
15
|
+
require 'test/unit'
|
16
|
+
|
17
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
18
|
+
require 'ar-validations-json'
|
19
|
+
|
20
|
+
ActiveRecord::Base.logger = Logger.new(
|
21
|
+
File.dirname(__FILE__) + '/log/test.log'
|
22
|
+
)
|
23
|
+
ActiveRecord::Base.establish_connection(
|
24
|
+
:adapter => 'sqlite3', :database => 'test/db/test.sqlite3'
|
25
|
+
)
|
26
|
+
|
27
|
+
module TestHelpers
|
28
|
+
def build_model(&block)
|
29
|
+
@model = Class.new(::ActiveRecord::Base)
|
30
|
+
@model.instance_eval &block
|
31
|
+
end
|
32
|
+
|
33
|
+
def assert_validations_json(expected)
|
34
|
+
assert_equal(expected, JSON.parse(@model.validations_json))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
Test::Unit::TestCase.send(:include, TestHelpers)
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class AcceptanceTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_acceptance_of :terms_of_service
|
7
|
+
end
|
8
|
+
assert_validations_json(
|
9
|
+
'terms_of_service' => {
|
10
|
+
'acceptance' => {'allow_nil' => true, 'accept' => '1'}
|
11
|
+
}
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_message
|
16
|
+
build_model do
|
17
|
+
validates_acceptance_of :terms_of_service, :message => 'must be abided'
|
18
|
+
end
|
19
|
+
assert_validations_json(
|
20
|
+
'terms_of_service' => {
|
21
|
+
'acceptance' => {
|
22
|
+
'message' => 'must be abided', 'allow_nil' => true, 'accept' => '1'
|
23
|
+
}
|
24
|
+
}
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_multiple_attributes
|
29
|
+
build_model do
|
30
|
+
validates_acceptance_of :terms_of_service, :privacy_policy
|
31
|
+
end
|
32
|
+
assert_validations_json(
|
33
|
+
'terms_of_service' => {
|
34
|
+
'acceptance' => {'allow_nil' => true, 'accept' => '1'}
|
35
|
+
},
|
36
|
+
'privacy_policy' => {
|
37
|
+
'acceptance' => {'allow_nil' => true, 'accept' => '1'}
|
38
|
+
}
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_on_create
|
43
|
+
build_model do
|
44
|
+
validates_acceptance_of :terms_of_service, :on => :create
|
45
|
+
end
|
46
|
+
assert_validations_json(
|
47
|
+
'terms_of_service' => {
|
48
|
+
'acceptance' => {
|
49
|
+
'on' => 'create', 'allow_nil' => true, 'accept' => '1'
|
50
|
+
}
|
51
|
+
}
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_on_update
|
56
|
+
build_model do
|
57
|
+
validates_acceptance_of :terms_of_service, :on => :update
|
58
|
+
end
|
59
|
+
assert_validations_json(
|
60
|
+
'terms_of_service' => {
|
61
|
+
'acceptance' => {
|
62
|
+
'on' => 'update', 'allow_nil' => true, 'accept' => '1'
|
63
|
+
}
|
64
|
+
}
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_allow_nil
|
69
|
+
build_model do
|
70
|
+
validates_acceptance_of :terms_of_service, :allow_nil => false
|
71
|
+
end
|
72
|
+
assert_validations_json(
|
73
|
+
'terms_of_service' => {
|
74
|
+
'acceptance' => {'allow_nil' => false, 'accept' => '1'}
|
75
|
+
}
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_accept
|
80
|
+
build_model do
|
81
|
+
validates_acceptance_of :terms_of_service, :accept => true
|
82
|
+
end
|
83
|
+
assert_validations_json(
|
84
|
+
'terms_of_service' => {
|
85
|
+
'acceptance' => {'allow_nil' => true, 'accept' => true}
|
86
|
+
}
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class AssociatedTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_associated :pages
|
7
|
+
end
|
8
|
+
assert_validations_json('pages' => {'associated' => true})
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_on
|
12
|
+
build_model do
|
13
|
+
validates_associated :pages, :on => :create
|
14
|
+
end
|
15
|
+
assert_validations_json('pages' => {'associated' => {'on' => 'create'}})
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class ConfirmationTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_confirmation_of :username
|
7
|
+
end
|
8
|
+
assert_validations_json('username' => {'confirmation' => true})
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_on
|
12
|
+
build_model do
|
13
|
+
validates_confirmation_of :password, :on => :create
|
14
|
+
end
|
15
|
+
assert_validations_json(
|
16
|
+
'password' => {'confirmation' => {'on' => 'create'}}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class ExclusionTest < Test::Unit::TestCase
|
4
|
+
def test_in_array
|
5
|
+
build_model do
|
6
|
+
validates_exclusion_of :username, :in => %w(admin superuser)
|
7
|
+
end
|
8
|
+
assert_validations_json(
|
9
|
+
'username' => {'exclusion' => {'in' => ['admin', 'superuser']}}
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_in_range
|
14
|
+
build_model do
|
15
|
+
validates_exclusion_of :age, :in => (1..17)
|
16
|
+
end
|
17
|
+
assert_validations_json(
|
18
|
+
'age' => {
|
19
|
+
'exclusion' => {'in' => [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]}
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_in_lambda
|
25
|
+
# Using a lambda only became an option as of ActiveRecord 3.1
|
26
|
+
unless ActiveRecord::VERSION::MINOR == 0
|
27
|
+
build_model do
|
28
|
+
validates_exclusion_of(
|
29
|
+
:password, :in => lambda { |p| [p.username, p.first_name] }
|
30
|
+
)
|
31
|
+
end
|
32
|
+
assert_validations_json({})
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_allow_blank
|
37
|
+
build_model do
|
38
|
+
validates_exclusion_of :age, :allow_blank => true, :in => (1..17)
|
39
|
+
end
|
40
|
+
assert_validations_json(
|
41
|
+
'age' => {
|
42
|
+
'exclusion' => {
|
43
|
+
'allow_blank' => true,
|
44
|
+
'in' => [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
|
45
|
+
}
|
46
|
+
}
|
47
|
+
)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class FormatTest < Test::Unit::TestCase
|
4
|
+
def test_with_regexp
|
5
|
+
build_model do
|
6
|
+
validates_format_of(
|
7
|
+
:email,
|
8
|
+
:with => %r/\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/,
|
9
|
+
:on => :create
|
10
|
+
)
|
11
|
+
end
|
12
|
+
assert_validations_json(
|
13
|
+
'email' => {
|
14
|
+
'format' => {
|
15
|
+
'with' => "(?-mix:\\A([^@\\s]+)@((?:[-a-z0-9]+\\.)+[a-z]{2,})\\Z)",
|
16
|
+
'on' => 'create'
|
17
|
+
}
|
18
|
+
}
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_without_regexp
|
23
|
+
build_model do
|
24
|
+
validates_format_of :email, :without => /NOSPAM/
|
25
|
+
end
|
26
|
+
assert_validations_json(
|
27
|
+
'email' => {'format' => {'without' => "(?-mix:NOSPAM)"}}
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_with_lambda
|
32
|
+
unless ActiveRecord::VERSION::MINOR == 0
|
33
|
+
build_model do
|
34
|
+
validates_format_of(
|
35
|
+
:screen_name,
|
36
|
+
:with => lambda { |person|
|
37
|
+
if person.admin?
|
38
|
+
%r/\A[a-z0-9][a-z0-9_\-]*\Z/
|
39
|
+
else
|
40
|
+
%r/\A[a-z][a-z0-9_\-]*\Z/
|
41
|
+
end
|
42
|
+
}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
assert_validations_json({})
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class InclusionTest < Test::Unit::TestCase
|
4
|
+
def test_in_array
|
5
|
+
build_model do
|
6
|
+
validates_inclusion_of :gender, :in => %w(f m)
|
7
|
+
end
|
8
|
+
assert_validations_json(
|
9
|
+
'gender' => {'inclusion' => {'in' => ['f', 'm']}}
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_in_lambda
|
14
|
+
# Using a lambda only became an option as of ActiveRecord 3.1
|
15
|
+
unless ActiveRecord::VERSION::MINOR == 0
|
16
|
+
build_model do
|
17
|
+
validates_inclusion_of(
|
18
|
+
:states, :in => lambda{ |person| STATES[person.country] }
|
19
|
+
)
|
20
|
+
end
|
21
|
+
assert_validations_json({})
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class LengthTest < Test::Unit::TestCase
|
4
|
+
def test_maximum
|
5
|
+
build_model do
|
6
|
+
validates_length_of :first_name, :maximum => 30
|
7
|
+
end
|
8
|
+
assert_validations_json(
|
9
|
+
'first_name' => {'length' => {'maximum' => 30}}
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_in_range
|
14
|
+
build_model do
|
15
|
+
validates_length_of :fax, :in => 7..32, :allow_nil => true
|
16
|
+
end
|
17
|
+
assert_validations_json(
|
18
|
+
'fax' => {
|
19
|
+
'length' => {'allow_nil' => true, 'maximum' => 32, 'minimum' => 7}
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_too_long_and_too_short
|
25
|
+
build_model do
|
26
|
+
validates_length_of(
|
27
|
+
:user_name,
|
28
|
+
:within => 6..20, :too_long => "pick a shorter name",
|
29
|
+
:too_short => "pick a longer name"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
assert_validations_json(
|
33
|
+
'user_name' => {
|
34
|
+
'length' => {
|
35
|
+
'maximum' => 20, 'minimum' => 6,
|
36
|
+
'too_long' => 'pick a shorter name',
|
37
|
+
'too_short' => 'pick a longer name'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_is
|
44
|
+
build_model do
|
45
|
+
validates_length_of(
|
46
|
+
:smurf_leader,
|
47
|
+
:is => 4,
|
48
|
+
:wrong_length => "papa is spelled with 4 characters... don't play me."
|
49
|
+
)
|
50
|
+
end
|
51
|
+
assert_validations_json(
|
52
|
+
'smurf_leader' => {
|
53
|
+
'length' => {
|
54
|
+
'is' => 4,
|
55
|
+
'wrong_length' =>
|
56
|
+
"papa is spelled with 4 characters... don't play me."
|
57
|
+
}
|
58
|
+
}
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_tokenizer_lambda
|
63
|
+
build_model do
|
64
|
+
validates_length_of(
|
65
|
+
:essay,
|
66
|
+
:minimum => 100,
|
67
|
+
:too_short => "Your essay must be at least 100 words.",
|
68
|
+
:tokenizer => lambda { |str| str.scan(/\w+/) }
|
69
|
+
)
|
70
|
+
end
|
71
|
+
assert_validations_json({})
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class NumericalityTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_numericality_of :age, :on => :create
|
7
|
+
end
|
8
|
+
assert_validations_json('age' => {'numericality' => {'on' => 'create'}})
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_only_integer
|
12
|
+
build_model do
|
13
|
+
validates_numericality_of :age, :only_integer => true
|
14
|
+
end
|
15
|
+
assert_validations_json(
|
16
|
+
'age' => {'numericality' => {'only_integer' => true}}
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_greater_than
|
21
|
+
build_model do
|
22
|
+
validates_numericality_of :age, :greater_than => 17
|
23
|
+
end
|
24
|
+
assert_validations_json(
|
25
|
+
'age' => {'numericality' => {'greater_than' => 17}}
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_greater_than_or_equal_to
|
30
|
+
build_model do
|
31
|
+
validates_numericality_of :age, :greater_than_or_equal_to => 18
|
32
|
+
end
|
33
|
+
assert_validations_json(
|
34
|
+
'age' => {'numericality' => {'greater_than_or_equal_to' => 18}}
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_equal_to
|
39
|
+
build_model do
|
40
|
+
validates_numericality_of :age, :equal_to => 18
|
41
|
+
end
|
42
|
+
assert_validations_json('age' => {'numericality' => {'equal_to' => 18}})
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_less_than
|
46
|
+
build_model do
|
47
|
+
validates_numericality_of :age, :less_than => 66
|
48
|
+
end
|
49
|
+
assert_validations_json('age' => {'numericality' => {'less_than' => 66}})
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_less_than_or_equal_to
|
53
|
+
build_model do
|
54
|
+
validates_numericality_of :age, :less_than_or_equal_to => 65
|
55
|
+
end
|
56
|
+
assert_validations_json(
|
57
|
+
'age' => {'numericality' => {'less_than_or_equal_to' => 65}}
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_odd
|
62
|
+
build_model do
|
63
|
+
validates_numericality_of :age, :odd => true
|
64
|
+
end
|
65
|
+
assert_validations_json('age' => {'numericality' => {'odd' => true}})
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_even
|
69
|
+
build_model do
|
70
|
+
validates_numericality_of :age, :even => true
|
71
|
+
end
|
72
|
+
assert_validations_json('age' => {'numericality' => {'even' => true}})
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class PresenceTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_presence_of :first_name
|
7
|
+
end
|
8
|
+
assert_validations_json('first_name' => {'presence' => true})
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '/../test_helper'))
|
2
|
+
|
3
|
+
class UniquenessTest < Test::Unit::TestCase
|
4
|
+
def test_simple
|
5
|
+
build_model do
|
6
|
+
validates_uniqueness_of :user_name
|
7
|
+
end
|
8
|
+
assert_validations_json(
|
9
|
+
'user_name' => {'uniqueness' => {'case_sensitive' => true}}
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_scope
|
14
|
+
build_model do
|
15
|
+
validates_uniqueness_of :user_name, :scope => :account_id
|
16
|
+
end
|
17
|
+
assert_validations_json(
|
18
|
+
'user_name' => {
|
19
|
+
'uniqueness' => {'scope' => 'account_id', 'case_sensitive' => true}
|
20
|
+
}
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_scope_array
|
25
|
+
build_model do
|
26
|
+
validates_uniqueness_of :teacher_id, :scope => [:semester_id, :class_id]
|
27
|
+
end
|
28
|
+
assert_validations_json(
|
29
|
+
'teacher_id' => {
|
30
|
+
'uniqueness' => {
|
31
|
+
'scope' => ['semester_id', 'class_id'], 'case_sensitive' => true
|
32
|
+
}
|
33
|
+
}
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_case_sensitive
|
38
|
+
build_model do
|
39
|
+
validates_uniqueness_of :user_name, :case_sensitive => false
|
40
|
+
end
|
41
|
+
assert_validations_json(
|
42
|
+
'user_name' => {'uniqueness' => {'case_sensitive' => false}}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ar-validations-json
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Francis Hwang
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-04-03 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: activerecord
|
17
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *id001
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: activesupport
|
28
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *id002
|
37
|
+
description: Serializes ActiveRecord validations into JSON for use by rich-client apps.
|
38
|
+
email: sera@fhwang.net
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- LICENSE.txt
|
45
|
+
- README.markdown
|
46
|
+
files:
|
47
|
+
- Gemfile
|
48
|
+
- Gemfile.lock
|
49
|
+
- LICENSE.txt
|
50
|
+
- README.markdown
|
51
|
+
- Rakefile
|
52
|
+
- VERSION
|
53
|
+
- ar-validations-json.gemspec
|
54
|
+
- lib/ar-validations-json.rb
|
55
|
+
- test/test_helper.rb
|
56
|
+
- test/unit/acceptance_test.rb
|
57
|
+
- test/unit/associated_test.rb
|
58
|
+
- test/unit/confirmation_test.rb
|
59
|
+
- test/unit/exclusion_test.rb
|
60
|
+
- test/unit/format_test.rb
|
61
|
+
- test/unit/inclusion_test.rb
|
62
|
+
- test/unit/length_test.rb
|
63
|
+
- test/unit/numericality_test.rb
|
64
|
+
- test/unit/presence_test.rb
|
65
|
+
- test/unit/uniqueness_test.rb
|
66
|
+
homepage: http://github.com/fhwang/ar-validations-json
|
67
|
+
licenses:
|
68
|
+
- MIT
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 1.8.17
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Serializes ActiveRecord validations into JSON for use by rich-client apps.
|
93
|
+
test_files: []
|
94
|
+
|