ar-validations-json 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|