validity 0.0.2 → 1.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.
- checksums.yaml +13 -5
- data/lib/validity/record.rb +115 -0
- data/lib/validity.rb +93 -4
- metadata +49 -7
- data/lib/validity/active_record.rb +0 -86
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NWNhNDQzMzUxYTQ4ZjQ3ODJhOWFjZmNlNTBhNDRmMzk5NjUxMTBlNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MmQzNDE1NTUwODhmYTU1YTIwMDdhNjNmMDZiZTE4MzRkNjdlMTQ3YQ==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzNiNzNhOWY4ODM3NDgyZTI0ODk4YTgwNjdhODdjMTQ2MzMzNGIzM2FkY2Zh
|
10
|
+
MWY2NzBhZTNjYjI2NTgzNGU1Yjc1ZDNmYzM0MjUyZWM2MTcyYmZkNzRiODll
|
11
|
+
YWU0ZDVjMTFmMzMwNTM3YTg3NjFmMTZkNWVjMTIxNzhiNTQxOGY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
OTg2M2EwNThhNTJjZmNmMTE3ZDY5OWZiMzAyNzU4OGFmNmZjZjEwYWQ5YzA4
|
14
|
+
MjkxZTI1ZmM5OTJjYjk0YzllM2UwYzgxZjY4YzVhZTJlMGJkNzA0NDk5YzI0
|
15
|
+
OTVlMzU2YzJjNDg0ODNkYjJkNjViNGFiMTliODhiY2M3MzJhMzA=
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Validity
|
2
|
+
# The Validity::Record module contains testing logic specific to ActiveRecord.
|
3
|
+
# Example Usage:
|
4
|
+
# @user = Record.validates(User.new)
|
5
|
+
# @user.field_uniqueness(:email)
|
6
|
+
# @user.field_presence(:email)
|
7
|
+
#
|
8
|
+
# Author:: Matt Fornaciari (mailto:mattforni@gmail.com)
|
9
|
+
# License:: MIT
|
10
|
+
class Record
|
11
|
+
include Test::Unit::Assertions
|
12
|
+
include Validity
|
13
|
+
|
14
|
+
attr_reader :record
|
15
|
+
|
16
|
+
# Creates a Validity::Record for validation.
|
17
|
+
#
|
18
|
+
# * *Args*:
|
19
|
+
# - +record+ the ActiveRecord model to validate
|
20
|
+
# * *Returns*:
|
21
|
+
# - a newly created Validity::Record object
|
22
|
+
# * *Raises*:
|
23
|
+
# - +Unconfigured+ if Validity is not configured
|
24
|
+
def self.validates(record)
|
25
|
+
Validity.check_configured!
|
26
|
+
Record.new(record)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Asserts the record has a +belongs_to+ association as indicated by the provided
|
30
|
+
# +field+ and that the record equals the +target+ record, if provided.
|
31
|
+
#
|
32
|
+
# * *Args*:
|
33
|
+
# - +field+ the fields to check for has_many association
|
34
|
+
# - +targets+ the target associated records
|
35
|
+
def belongs_to(field, target = nil)
|
36
|
+
clazz = @record.class
|
37
|
+
assert_respond_to @record, field, "#{clazz} cannot find associated #{field}"
|
38
|
+
|
39
|
+
one = @record.send(field)
|
40
|
+
assert_not_nil one, "#{clazz} does not have associated #{field}"
|
41
|
+
if target
|
42
|
+
assert_equal target, one, "#{field.to_s.capitalize} associated with this #{clazz.to_s.downcase} is not the target #{field}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Asserts that the record responds to the +delegated+ method and that
|
47
|
+
# the returned object is equal to the object referenced by +delegated_to+.
|
48
|
+
#
|
49
|
+
# * *Args*:
|
50
|
+
# - +field+ the fields to check for presence
|
51
|
+
def delegates(delegated, delegated_to)
|
52
|
+
clazz = @record.class
|
53
|
+
assert_respond_to @record, delegated, "#{clazz} does not respond to #{delegated}"
|
54
|
+
assert_equal delegated_to.send(delegated), @record.send(delegated), "Delegated objects do not match"
|
55
|
+
end
|
56
|
+
|
57
|
+
# Asserts that the given +field+ must be present for the record to be valid.
|
58
|
+
#
|
59
|
+
# * *Args*:
|
60
|
+
# - +field+ the fields to check for presence
|
61
|
+
def field_presence(field)
|
62
|
+
@record.send("#{field}=", nil)
|
63
|
+
|
64
|
+
clazz = @record.class
|
65
|
+
assert !@record.valid?, "#{clazz} is considered valid with nil #{field}"
|
66
|
+
assert !@record.save, "#{clazz} saved without #{field} field"
|
67
|
+
assert @record.errors[field].any?, "#{clazz} does not have an error on #{field}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Asserts that the given +field+ must be unique for the record to be valid.
|
71
|
+
#
|
72
|
+
# * *Args*:
|
73
|
+
# - +field+ the fields to check for uniqueness
|
74
|
+
def field_uniqueness(field)
|
75
|
+
dup = @record.dup
|
76
|
+
|
77
|
+
clazz = dup.class
|
78
|
+
assert !dup.valid?, "#{clazz} is considered valid with duplicate #{field}"
|
79
|
+
assert !dup.save, "#{clazz} saved with a duplicate #{field}"
|
80
|
+
assert dup.errors[field].any?, "#{clazz} does not have an error on #{field}"
|
81
|
+
end
|
82
|
+
|
83
|
+
# Asserts the record has a +has_many+ association as indicated by the provided
|
84
|
+
# +field+ and that the many records equal the +targets+ records, if provided.
|
85
|
+
#
|
86
|
+
# * *Args*:
|
87
|
+
# - +field+ the fields to check for has_many association
|
88
|
+
# - +targets+ the target associated records
|
89
|
+
def has_many(field, targets = nil)
|
90
|
+
clazz = @record.class
|
91
|
+
assert_respond_to @record, field, "#{clazz} cannot find associated #{field}"
|
92
|
+
|
93
|
+
many = @record.send(field)
|
94
|
+
assert !(many.nil? || many.empty?), "#{clazz} does not have associated #{field}"
|
95
|
+
if targets
|
96
|
+
assert_equal targets.size, many.size, "#{clazz} does not have #{targets.size} associated #{field}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
attr_writer :record
|
103
|
+
|
104
|
+
# Creates a Validity::Record for validation.
|
105
|
+
#
|
106
|
+
# * *Args*:
|
107
|
+
# - +record+ the ActiveRecord model to validate
|
108
|
+
# * *Returns*:
|
109
|
+
# - a newly created Validity::Record object
|
110
|
+
def initialize(record)
|
111
|
+
self.record = record
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
data/lib/validity.rb
CHANGED
@@ -1,12 +1,101 @@
|
|
1
|
-
# This gem
|
2
|
-
# ActiveRecord models
|
3
|
-
#
|
1
|
+
# This gem provides a library aimed at making testing easy. At this point it
|
2
|
+
# is aimed at testing ActiveRecord models, though the ultimate goal is to make
|
3
|
+
# spinning up a Ruby on Rails stack both quick and painless. The
|
4
4
|
# syntactical structure of this library is based losely upon rspec's
|
5
5
|
# expect/match syntax as it seems to lend itself well to testing readability.
|
6
|
+
# This testing library is test framework agnostic, though it currently only
|
7
|
+
# supports test-unit and rspec. Which framework you would like to use must
|
8
|
+
# be configured prior to use. Happy testing!
|
6
9
|
#
|
7
10
|
# Author:: Matt Fornaciari (mailto:mattforni@gmail.com)
|
8
11
|
# License:: MIT
|
9
12
|
|
10
13
|
require 'test/unit/assertions'
|
11
|
-
require 'validity/
|
14
|
+
require 'validity/record'
|
15
|
+
|
16
|
+
module Validity
|
17
|
+
# Configures Validity to use the provided test_module.
|
18
|
+
#
|
19
|
+
# * *Args*:
|
20
|
+
# - +test_module+ the module to use for testing
|
21
|
+
# * *Returns*:
|
22
|
+
# - the test module Validity was configured to use
|
23
|
+
# * *Raises*:
|
24
|
+
# - +Unsupported+ if the provided test module is unsupported
|
25
|
+
def self.configure(test_module)
|
26
|
+
raise Unsupported.new(test_module) if !supported?(test_module)
|
27
|
+
@@test_module = test_module
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns whether or not Validity is configured.
|
31
|
+
#
|
32
|
+
# * *Returns*:
|
33
|
+
# - whether or not Validity has been configured
|
34
|
+
def self.configured?
|
35
|
+
!@@test_module.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
# Resets Validity to an unconfigured state.
|
39
|
+
def self.reset!
|
40
|
+
@@test_module = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns a list of test modules Validity supports.
|
44
|
+
#
|
45
|
+
# * *Returns*:
|
46
|
+
# - a list of test modules Validity supports
|
47
|
+
def self.supported
|
48
|
+
SUPPORTED
|
49
|
+
end
|
50
|
+
|
51
|
+
# A Validity specific error signifying an unsupported test module.
|
52
|
+
#
|
53
|
+
# Author:: Matt Fornaciari (mailto:mattforni@gmail.com)
|
54
|
+
# License:: MIT
|
55
|
+
class Unsupported < RuntimeError
|
56
|
+
def initialize(test_module)
|
57
|
+
super(UNSUPPORTED % {test_module: test_module})
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# A Validity specific error signifying Validity is unconfigured.
|
62
|
+
#
|
63
|
+
# Author:: Matt Fornaciari (mailto:mattforni@gmail.com)
|
64
|
+
# License:: MIT
|
65
|
+
class Unconfigured < RuntimeError
|
66
|
+
def initialize
|
67
|
+
super('Validity must be configured before use')
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
# Checks if Validity is configured and raises an error if is not.
|
74
|
+
#
|
75
|
+
# * *Raises*:
|
76
|
+
# - +Unconfigured+ if Validity is not configured
|
77
|
+
def self.check_configured!
|
78
|
+
raise Unconfigured.new if !configured?
|
79
|
+
end
|
80
|
+
|
81
|
+
module TestUnit
|
82
|
+
end
|
83
|
+
|
84
|
+
SUPPORTED = [TestUnit]
|
85
|
+
UNSUPPORTED = "%{test_module} is not a supported test module, please specify one of #{SUPPORTED.join(', ')}"
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
@@test_module = nil
|
90
|
+
|
91
|
+
# Returns whether or not a test module is supported by Validity.
|
92
|
+
#
|
93
|
+
# * *Args*:
|
94
|
+
# - +test_module+ the module to check
|
95
|
+
# * *Returns*:
|
96
|
+
# - whether or not the module is supported by Validity
|
97
|
+
def self.supported?(test_module)
|
98
|
+
SUPPORTED.include?(test_module)
|
99
|
+
end
|
100
|
+
end
|
12
101
|
|
metadata
CHANGED
@@ -1,27 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Fornaciari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-05-
|
11
|
+
date: 2014-05-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activerecord
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.1'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.1'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
25
67
|
- !ruby/object:Gem::Version
|
26
68
|
version: '2'
|
27
69
|
description: The beginning of a validation library
|
@@ -31,7 +73,7 @@ extensions: []
|
|
31
73
|
extra_rdoc_files: []
|
32
74
|
files:
|
33
75
|
- lib/validity.rb
|
34
|
-
- lib/validity/
|
76
|
+
- lib/validity/record.rb
|
35
77
|
homepage: http://rubygems.org/gems/validity
|
36
78
|
licenses:
|
37
79
|
- MIT
|
@@ -42,12 +84,12 @@ require_paths:
|
|
42
84
|
- lib
|
43
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
44
86
|
requirements:
|
45
|
-
- -
|
87
|
+
- - ! '>='
|
46
88
|
- !ruby/object:Gem::Version
|
47
89
|
version: '0'
|
48
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
91
|
requirements:
|
50
|
-
- -
|
92
|
+
- - ! '>='
|
51
93
|
- !ruby/object:Gem::Version
|
52
94
|
version: '0'
|
53
95
|
requirements: []
|
@@ -1,86 +0,0 @@
|
|
1
|
-
# Author:: Matt Fornaciari (mailto:mattforni@gmail.com)
|
2
|
-
# License:: MIT
|
3
|
-
|
4
|
-
module Validity
|
5
|
-
# The Validity::ActiveRecord module contains testing logic specific to ActiveRecord
|
6
|
-
module ActiveRecord
|
7
|
-
# Creates an ActiveRecord::Wrapper to test against
|
8
|
-
def validates(record)
|
9
|
-
Wrapper.new(record)
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
# The Wrapper class is just a thin wrapper around the ActiveRecord model
|
15
|
-
# which defines several methods to validate a model behaves as it should.
|
16
|
-
# Example Usage:
|
17
|
-
# validates(@model).field_presence(:required)
|
18
|
-
class Wrapper
|
19
|
-
include Test::Unit::Assertions
|
20
|
-
|
21
|
-
# Creates a new instance of Validity::ActiveRecord::Wrapper to test against
|
22
|
-
def initialize(record)
|
23
|
-
@record = record
|
24
|
-
end
|
25
|
-
|
26
|
-
# Asserts that the record has a belongs_to association and that the
|
27
|
-
# associated record equals the +target+ record, if provided.
|
28
|
-
def belongs_to(field, target = nil)
|
29
|
-
clazz = @record.class
|
30
|
-
assert_respond_to @record, field, "#{clazz} cannot find associated #{field}"
|
31
|
-
|
32
|
-
one = @record.send(field)
|
33
|
-
assert_not_nil one, "#{clazz} does not have associated #{field}"
|
34
|
-
if target
|
35
|
-
assert_equal target, one, "#{field.to_s.capitalize} associated with this #{clazz.to_s.downcase} is not the target #{field}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Asserts that the record responds to the +delegated+ method and that
|
40
|
-
# the returned object is equal to the object referenced by +delegated_to+
|
41
|
-
def delegates(delegated, delegated_to)
|
42
|
-
clazz = @record.class
|
43
|
-
assert_respond_to @record, delegated, "#{clazz} does not respond to #{delegated}"
|
44
|
-
assert_equal delegated_to.send(delegated), @record.send(delegated), "Delegated objects do not match"
|
45
|
-
end
|
46
|
-
|
47
|
-
# Asserts that the +field+ field must be present for the record to be valid
|
48
|
-
def field_presence(field)
|
49
|
-
@record.send("#{field}=", nil)
|
50
|
-
|
51
|
-
clazz = @record.class
|
52
|
-
assert !@record.valid?, "#{clazz} is considered valid with nil #{field}"
|
53
|
-
assert !@record.save, "#{clazz} saved without #{field} field"
|
54
|
-
assert @record.errors[field].any?, "#{clazz} does not have an error on #{field}"
|
55
|
-
end
|
56
|
-
|
57
|
-
# Asserts that the +field+ field must be unique for the record to be valid
|
58
|
-
def field_uniqueness(field)
|
59
|
-
dup = @record.dup
|
60
|
-
|
61
|
-
clazz = dup.class
|
62
|
-
assert !dup.valid?, "#{clazz} is considered valid with duplicate #{field}"
|
63
|
-
assert !dup.save, "#{clazz} saved with a duplicate #{field}"
|
64
|
-
assert dup.errors[field].any?, "#{clazz} does not have an error on #{field}"
|
65
|
-
end
|
66
|
-
|
67
|
-
# Asserts that the record has a has_many association and that the
|
68
|
-
# associated records equal the +targets+ records, if provided.
|
69
|
-
def has_many(field, targets = nil)
|
70
|
-
clazz = @record.class
|
71
|
-
assert_respond_to @record, field, "#{clazz} cannot find associated #{field}"
|
72
|
-
|
73
|
-
many = @record.send(field)
|
74
|
-
assert !(many.nil? || many.empty?), "#{clazz} does not have associated #{field}"
|
75
|
-
if targets
|
76
|
-
assert_equal targets.size, many.size, "#{clazz} does not have #{targets.size} associated #{field}"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
private
|
81
|
-
|
82
|
-
attr_reader :record
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|