validates_subset 1.0.2
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 +7 -0
- data/.gitignore +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +84 -0
- data/Guardfile +5 -0
- data/README.md +124 -0
- data/lib/arguments.rb +44 -0
- data/lib/validates_subset.rb +98 -0
- data/spec/integration/modifiers/allow_blank_spec.rb +63 -0
- data/spec/integration/modifiers/allow_nil_spec.rb +63 -0
- data/spec/integration/modifiers/if_spec.rb +58 -0
- data/spec/integration/modifiers/message_spec.rb +47 -0
- data/spec/integration/modifiers/multiple_spec.rb +73 -0
- data/spec/integration/modifiers/on_spec.rb +21 -0
- data/spec/integration/modifiers/strict_spec.rb +77 -0
- data/spec/integration/modifiers/unless_spec.rb +76 -0
- data/spec/integration/validations_spec.rb +46 -0
- data/spec/lib/arguments_spec.rb +84 -0
- data/spec/lib/validates_subset_spec.rb +77 -0
- data/validates_subset.gemspec +26 -0
- data/version.rb +3 -0
- metadata +132 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6ac3e5de7a80d20cdddb2d41527f9228a767cc5f
|
4
|
+
data.tar.gz: 7fbf538b71f54145550823de261b4ac6fb356b7e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4f8b260d9e133cd883f4bede331137c57aa51a68ea7883a026e5c6c5306cc2c822584b6c2d4870cb02f0027f1d6fba8d739025e6ba3592a8effc62751ebf5ccb
|
7
|
+
data.tar.gz: aec647c12952a02a976d09fd4c84c4c2b6629b66a40db0dd45eea4d74cd23fa6b616b59c8005680ebfb7ce5949893cc5777623a6310739b05f969b4511e753aa
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.ruby-*
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (4.2.1)
|
5
|
+
activesupport (= 4.2.1)
|
6
|
+
builder (~> 3.1)
|
7
|
+
activesupport (4.2.1)
|
8
|
+
i18n (~> 0.7)
|
9
|
+
json (~> 1.7, >= 1.7.7)
|
10
|
+
minitest (~> 5.1)
|
11
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
12
|
+
tzinfo (~> 1.1)
|
13
|
+
builder (3.2.2)
|
14
|
+
celluloid (0.16.0)
|
15
|
+
timers (~> 4.0.0)
|
16
|
+
coderay (1.1.0)
|
17
|
+
diff-lcs (1.2.5)
|
18
|
+
ffi (1.9.8)
|
19
|
+
formatador (0.2.5)
|
20
|
+
guard (2.12.5)
|
21
|
+
formatador (>= 0.2.4)
|
22
|
+
listen (~> 2.7)
|
23
|
+
lumberjack (~> 1.0)
|
24
|
+
nenv (~> 0.1)
|
25
|
+
notiffany (~> 0.0)
|
26
|
+
pry (>= 0.9.12)
|
27
|
+
shellany (~> 0.0)
|
28
|
+
thor (>= 0.18.1)
|
29
|
+
guard-compat (1.2.1)
|
30
|
+
guard-rspec (4.5.2)
|
31
|
+
guard (~> 2.1)
|
32
|
+
guard-compat (~> 1.1)
|
33
|
+
rspec (>= 2.99.0, < 4.0)
|
34
|
+
hitimes (1.2.2)
|
35
|
+
i18n (0.7.0)
|
36
|
+
json (1.8.3)
|
37
|
+
listen (2.10.0)
|
38
|
+
celluloid (~> 0.16.0)
|
39
|
+
rb-fsevent (>= 0.9.3)
|
40
|
+
rb-inotify (>= 0.9)
|
41
|
+
lumberjack (1.0.9)
|
42
|
+
method_source (0.8.2)
|
43
|
+
minitest (5.7.0)
|
44
|
+
nenv (0.2.0)
|
45
|
+
notiffany (0.0.6)
|
46
|
+
nenv (~> 0.1)
|
47
|
+
shellany (~> 0.0)
|
48
|
+
pry (0.10.1)
|
49
|
+
coderay (~> 1.1.0)
|
50
|
+
method_source (~> 0.8.1)
|
51
|
+
slop (~> 3.4)
|
52
|
+
rb-fsevent (0.9.5)
|
53
|
+
rb-inotify (0.9.5)
|
54
|
+
ffi (>= 0.5.0)
|
55
|
+
rspec (3.2.0)
|
56
|
+
rspec-core (~> 3.2.0)
|
57
|
+
rspec-expectations (~> 3.2.0)
|
58
|
+
rspec-mocks (~> 3.2.0)
|
59
|
+
rspec-core (3.2.3)
|
60
|
+
rspec-support (~> 3.2.0)
|
61
|
+
rspec-expectations (3.2.1)
|
62
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
63
|
+
rspec-support (~> 3.2.0)
|
64
|
+
rspec-mocks (3.2.1)
|
65
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
66
|
+
rspec-support (~> 3.2.0)
|
67
|
+
rspec-support (3.2.2)
|
68
|
+
shellany (0.0.1)
|
69
|
+
slop (3.6.0)
|
70
|
+
thor (0.19.1)
|
71
|
+
thread_safe (0.3.5)
|
72
|
+
timers (4.0.1)
|
73
|
+
hitimes
|
74
|
+
tzinfo (1.2.2)
|
75
|
+
thread_safe (~> 0.1)
|
76
|
+
|
77
|
+
PLATFORMS
|
78
|
+
ruby
|
79
|
+
|
80
|
+
DEPENDENCIES
|
81
|
+
activemodel
|
82
|
+
guard-rspec
|
83
|
+
pry
|
84
|
+
rspec
|
data/Guardfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
## validates_subset
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
### Subset validator for Rails
|
6
|
+
|
7
|
+
#### Purpose
|
8
|
+
|
9
|
+
Validate that an attribute is a subset of another. If an attribute saved to the database (or simply kept in memory) needs to be a subset of another, this is the way to go.
|
10
|
+
|
11
|
+
#### Usage
|
12
|
+
|
13
|
+
##### With ActiveRecord
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class Foo < ActiveRecord::Base
|
17
|
+
attr_accessor :bar
|
18
|
+
|
19
|
+
# validate that the attribute :bar is a subset of the set [2, 4, 5]
|
20
|
+
validates_subset :bar, [2, 4, 5]
|
21
|
+
end
|
22
|
+
|
23
|
+
# Example usage:
|
24
|
+
foo = Foo.new(bar: [2])
|
25
|
+
foo.valid?
|
26
|
+
# => true
|
27
|
+
|
28
|
+
foo = Foo.new(bar: [7])
|
29
|
+
foo.valid?
|
30
|
+
# => false
|
31
|
+
|
32
|
+
foo = Foo.new(bar: 'banana')
|
33
|
+
foo.valid?
|
34
|
+
# => false
|
35
|
+
```
|
36
|
+
|
37
|
+
##### With ActiveModel
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
class Bar
|
41
|
+
include ActiveModel
|
42
|
+
|
43
|
+
attr_accessor :foo
|
44
|
+
|
45
|
+
# validate that the attribute :foo is a subset of the set ['a', 'b', 'c']
|
46
|
+
validates_subset :foo, ['a', 'b', 'c']
|
47
|
+
end
|
48
|
+
|
49
|
+
# Example usage:
|
50
|
+
bar = Bar.new(foo: ['a'])
|
51
|
+
bar.valid?
|
52
|
+
# => true
|
53
|
+
|
54
|
+
bar = Bar.new(foo: ['q'])
|
55
|
+
bar.valid?
|
56
|
+
# => false
|
57
|
+
|
58
|
+
bar = Bar.new(foo: 123)
|
59
|
+
bar.valid?
|
60
|
+
# => false
|
61
|
+
```
|
62
|
+
|
63
|
+
##### With `validates` syntax
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
class Banana < ActiveRecord::Base
|
67
|
+
|
68
|
+
attr_accessor :peel
|
69
|
+
|
70
|
+
# validate that the attribute :peel is a subset of the set ['yellow', 'green']
|
71
|
+
validates :peel, subset: ['yellow', 'green']
|
72
|
+
end
|
73
|
+
|
74
|
+
# Example usage:
|
75
|
+
banana = Banana.new(peel: ['yellow'])
|
76
|
+
banana.valid?
|
77
|
+
# => true
|
78
|
+
|
79
|
+
banana = Banana.new(peel: ['brown']) # Who wants a brown peel? No one.
|
80
|
+
banana.valid?
|
81
|
+
# => false
|
82
|
+
|
83
|
+
banana = Banana.new(peel: 123)
|
84
|
+
banana.valid?
|
85
|
+
# => false
|
86
|
+
```
|
87
|
+
|
88
|
+
##### With multiple modifiers
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
class Foo < ActiveRecord::Base
|
92
|
+
attr_accessor :baz
|
93
|
+
|
94
|
+
# validate that attribute :baz is a subset of [1, 2, 3] with a custom error message
|
95
|
+
# only if :conditional_method evaluates to true
|
96
|
+
validates_subset :baz, [1, 2, 3],
|
97
|
+
message: 'Baz is not a subset of [1, 2, 3], make it so!',
|
98
|
+
if: :conditional_method
|
99
|
+
|
100
|
+
def conditional_method
|
101
|
+
# some kind of logic that is important to pass
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
# Example usage:
|
106
|
+
foo = Foo.new(baz: [1])
|
107
|
+
|
108
|
+
foo.valid?
|
109
|
+
# => true
|
110
|
+
|
111
|
+
foo = Foo.new(baz: [99999])
|
112
|
+
|
113
|
+
# When the conditional method is true
|
114
|
+
foo.conditional_method
|
115
|
+
# => true
|
116
|
+
foo.valid?
|
117
|
+
# => false
|
118
|
+
|
119
|
+
# When the conditional method is false
|
120
|
+
foo.conditional_method
|
121
|
+
# => false
|
122
|
+
foo.valid?
|
123
|
+
# => true
|
124
|
+
```
|
data/lib/arguments.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module ValidatesSubset
|
2
|
+
# Wrapper class for arguments consumed by validates_with
|
3
|
+
class Arguments
|
4
|
+
# @initialize
|
5
|
+
# param: attribute_name <Symbol> - Name of attribute that will be validated
|
6
|
+
# param: superset <Array> - Superset of attributes to validate set against
|
7
|
+
# param: options <Hash> - Extra options to pass along to the validator
|
8
|
+
# i.e. allow_nil: true, message: 'my custom message'
|
9
|
+
# return: nil
|
10
|
+
def initialize(attribute_name, superset, options)
|
11
|
+
@attribute_name = attribute_name
|
12
|
+
@superset = superset
|
13
|
+
@options = options.is_a?(Hash) ? options : {}
|
14
|
+
end
|
15
|
+
|
16
|
+
# format expected by _merge_attributes
|
17
|
+
#
|
18
|
+
# @to_validation_attributes
|
19
|
+
# return: <Array> - cardinality of 2
|
20
|
+
def to_validation_attributes
|
21
|
+
[@attribute_name, merged_options]
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
# helper method to compact all the options together along
|
27
|
+
# with the subset for validation
|
28
|
+
#
|
29
|
+
# @merged_options
|
30
|
+
# return: <Hash>
|
31
|
+
def merged_options
|
32
|
+
subset.merge(@options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# helper method to impose the subset for validation into an option
|
36
|
+
# that will be merged later
|
37
|
+
#
|
38
|
+
# @subset
|
39
|
+
# return: <Hash>
|
40
|
+
def subset
|
41
|
+
{ :subset => @superset }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'active_model'
|
2
|
+
|
3
|
+
require_relative './arguments'
|
4
|
+
|
5
|
+
module ActiveModel
|
6
|
+
module Validations
|
7
|
+
class SubsetValidator < ActiveModel::EachValidator
|
8
|
+
# @initialize
|
9
|
+
# param: options <Hash> - options hash of how to validate this attribute
|
10
|
+
# including custom messaging due to failures, specifying
|
11
|
+
# the subset the attribute to validate against, etc.
|
12
|
+
# return: result of ActiveModel::Validations::EachValidator initialize
|
13
|
+
def initialize(options)
|
14
|
+
options[:superset] = options.delete(:subset)
|
15
|
+
|
16
|
+
merged_options = {
|
17
|
+
:message => "is expected to be a subset of #{ options[:superset] } and is not."
|
18
|
+
}.merge(options)
|
19
|
+
|
20
|
+
super(merged_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
# Validate that the array is a subset of what we expect
|
24
|
+
#
|
25
|
+
# @validate_each
|
26
|
+
# param: record <Object> - subject containing attribute to validate
|
27
|
+
# param: attribute <Symbol> - name of attribute to validate
|
28
|
+
# param: value <Variable> - value of attribute to validate
|
29
|
+
# return: nil
|
30
|
+
def validate_each(record, attribute, value)
|
31
|
+
add_errors_or_raise(options, record, attribute) unless is_subset?(value, options[:superset])
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def is_subset?(set, superset)
|
37
|
+
set.is_a?(Array) && (set & superset) == set
|
38
|
+
end
|
39
|
+
|
40
|
+
# Helper method to either add messages to the errors object
|
41
|
+
# or raise an exception in :strict mode
|
42
|
+
#
|
43
|
+
# @add_errors_or_raise
|
44
|
+
# param: options <Hash> - options hash with strict flag or class
|
45
|
+
# param: record <Object> - subject containg attribute to validate
|
46
|
+
# param: attribute <Symbol> - name of attribute under validation
|
47
|
+
# return: nil
|
48
|
+
def add_errors_or_raise(options, record, attribute)
|
49
|
+
error = options_error(options[:strict])
|
50
|
+
|
51
|
+
raise error unless error.nil?
|
52
|
+
|
53
|
+
record.errors.add(attribute, options[:message])
|
54
|
+
end
|
55
|
+
|
56
|
+
# Helper method to return the base expected error:
|
57
|
+
# ActiveModel::StrictValidationFailed, a custom error, or nil
|
58
|
+
#
|
59
|
+
# @options_error
|
60
|
+
# param: strict_error <true or subclass of Exception> - either the flag
|
61
|
+
# to raise an error or the actual error to raise
|
62
|
+
# return: custom error, ActiveModel::StrictValidationFailed, or nil
|
63
|
+
def options_error(strict_error)
|
64
|
+
return if strict_error.nil?
|
65
|
+
|
66
|
+
if strict_error == true
|
67
|
+
ActiveModel::StrictValidationFailed
|
68
|
+
elsif strict_error.ancestors.include?(Exception)
|
69
|
+
strict_error
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
module ClassMethods
|
75
|
+
# Validates that an attribute is a subset of an expected set:
|
76
|
+
#
|
77
|
+
# class Foo
|
78
|
+
# include ActiveModel::Validations
|
79
|
+
#
|
80
|
+
# attr_accessor :thing, :something
|
81
|
+
#
|
82
|
+
# validates_subset :thing, ['something', 'another thing', 'a third thing']
|
83
|
+
# validates_subset :something, [:foo, :bar]
|
84
|
+
# end
|
85
|
+
#
|
86
|
+
# @validates_subset
|
87
|
+
# param: attribute_name <Symbol> - name of attribute to validate
|
88
|
+
# param: set <Array> - superset of all desired members
|
89
|
+
# param: options <Hash> - other common options to validate methods calls
|
90
|
+
# i.e. message: 'my custom error message'
|
91
|
+
# return: nil
|
92
|
+
def validates_subset(attribute_name, superset, options = {})
|
93
|
+
args = ValidatesSubset::Arguments.new(attribute_name, superset, options)
|
94
|
+
validates_with SubsetValidator, _merge_attributes(args.to_validation_attributes)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
class TestAllowBlank
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :foo
|
7
|
+
|
8
|
+
validates_subset :foo, [1, 2, 3], allow_blank: true
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'allow blank' do
|
12
|
+
subject { sub = TestAllowBlank.new; sub.foo = value; sub }
|
13
|
+
|
14
|
+
context 'value is not blank' do
|
15
|
+
context 'value is a valid subset' do
|
16
|
+
let(:value) { [1] }
|
17
|
+
|
18
|
+
specify do
|
19
|
+
expect(subject).to be_valid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'value is not a valid subset' do
|
24
|
+
let(:value) { %i[a b c] }
|
25
|
+
|
26
|
+
specify do
|
27
|
+
expect(subject).to_not be_valid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'value is not an array' do
|
32
|
+
let(:value) { 'bar' }
|
33
|
+
|
34
|
+
specify do
|
35
|
+
expect(subject).to_not be_valid
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'value is blank' do
|
41
|
+
let(:value) { nil }
|
42
|
+
|
43
|
+
specify do
|
44
|
+
expect(subject).to be_valid
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'an empty array' do
|
48
|
+
let(:value) { [] }
|
49
|
+
|
50
|
+
specify do
|
51
|
+
expect(subject).to be_valid
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'an empty hash' do
|
56
|
+
let(:value) { {} }
|
57
|
+
|
58
|
+
specify do
|
59
|
+
expect(subject).to be_valid
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
class TestAllowNil
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :foo
|
7
|
+
|
8
|
+
validates_subset :foo, [1, 2, 3], allow_nil: true
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'allow nil' do
|
12
|
+
subject { sub = TestAllowNil.new; sub.foo = value; sub }
|
13
|
+
|
14
|
+
context 'value is not nil' do
|
15
|
+
context 'value is a valid subset' do
|
16
|
+
let(:value) { [1] }
|
17
|
+
|
18
|
+
specify do
|
19
|
+
expect(subject).to be_valid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'value is not a valid subset' do
|
24
|
+
let(:value) { %i[a b c] }
|
25
|
+
|
26
|
+
specify do
|
27
|
+
expect(subject).to_not be_valid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'value is not an array' do
|
32
|
+
let(:value) { 'bar' }
|
33
|
+
|
34
|
+
specify do
|
35
|
+
expect(subject).to_not be_valid
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'value is nil' do
|
41
|
+
let(:value) { nil }
|
42
|
+
|
43
|
+
specify do
|
44
|
+
expect(subject).to be_valid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'an empty array' do
|
49
|
+
let(:value) { [] }
|
50
|
+
|
51
|
+
specify do
|
52
|
+
expect(subject).to be_valid
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'an empty hash' do
|
57
|
+
let(:value) { {} }
|
58
|
+
|
59
|
+
specify do
|
60
|
+
expect(subject).to_not be_valid
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
describe 'if condition' do
|
4
|
+
subject { sub = TestIfTrue.new; sub.foo = value; sub }
|
5
|
+
|
6
|
+
context 'if condition results in true' do
|
7
|
+
|
8
|
+
class TestIfTrue
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
attr_accessor :foo
|
12
|
+
|
13
|
+
validates_subset :foo, [1, 2, 3], if: -> { true }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'value is a valid subset' do
|
17
|
+
let(:value) { [1] }
|
18
|
+
|
19
|
+
specify do
|
20
|
+
expect(subject).to be_valid
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'value is not a valid subset' do
|
25
|
+
let(:value) { %i[a b c] }
|
26
|
+
|
27
|
+
specify do
|
28
|
+
expect(subject).to_not be_valid
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'value is not an array' do
|
33
|
+
let(:value) { 'bar' }
|
34
|
+
|
35
|
+
specify do
|
36
|
+
expect(subject).to_not be_valid
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'condition results is not true' do
|
42
|
+
class TestIfFalse
|
43
|
+
include ActiveModel::Validations
|
44
|
+
|
45
|
+
attr_accessor :foo
|
46
|
+
|
47
|
+
validates_subset :foo, [1, 2, 3], if: -> { false }
|
48
|
+
end
|
49
|
+
|
50
|
+
subject { sub = TestIfFalse.new; sub.foo = value; sub }
|
51
|
+
|
52
|
+
let(:value) { anything }
|
53
|
+
|
54
|
+
specify do
|
55
|
+
expect(subject).to be_valid
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
class TestMessage
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :foo
|
7
|
+
|
8
|
+
validates_subset :foo, [1, 2, 3], message: 'Oh no spaghettios'
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'custom messaging' do
|
12
|
+
subject { sub = TestMessage.new; sub.foo = value; sub }
|
13
|
+
|
14
|
+
context 'value is a valid subset' do
|
15
|
+
let(:value) { [1] }
|
16
|
+
|
17
|
+
specify do
|
18
|
+
expect(subject).to be_valid
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'value is not a valid subset' do
|
23
|
+
let(:value) { %i[a b c] }
|
24
|
+
|
25
|
+
specify do
|
26
|
+
expect(subject).to_not be_valid
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'sets the custom error message' do
|
30
|
+
subject.validate
|
31
|
+
expect(subject.errors[:foo].first).to match(/Oh no spaghettios/)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'value is not an array' do
|
36
|
+
let(:value) { 'bar' }
|
37
|
+
|
38
|
+
specify do
|
39
|
+
expect(subject).to_not be_valid
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets the custom error message' do
|
43
|
+
subject.validate
|
44
|
+
expect(subject.errors[:foo].first).to match(/Oh no spaghettios/)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
class TestMultiple
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :foo
|
7
|
+
|
8
|
+
validates_subset :foo, [1, 2, 3], allow_blank: true, message: 'oh no spaghettios'
|
9
|
+
end
|
10
|
+
|
11
|
+
describe 'multiple validations' do
|
12
|
+
subject { sub = TestMultiple.new; sub.foo = value; sub }
|
13
|
+
|
14
|
+
context 'value is not blank' do
|
15
|
+
context 'value is a valid subset' do
|
16
|
+
let(:value) { [1] }
|
17
|
+
|
18
|
+
specify do
|
19
|
+
expect(subject).to be_valid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'value is not a valid subset' do
|
24
|
+
let(:value) { %i[a b c] }
|
25
|
+
|
26
|
+
specify do
|
27
|
+
expect(subject).to_not be_valid
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'has the specified error message' do
|
31
|
+
subject.validate
|
32
|
+
expect(subject.errors.full_messages.to_s).to match(/oh no spaghettios/)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'value is not an array' do
|
37
|
+
let(:value) { 'bar' }
|
38
|
+
|
39
|
+
specify do
|
40
|
+
expect(subject).to_not be_valid
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'has the specified error message' do
|
44
|
+
subject.validate
|
45
|
+
expect(subject.errors.full_messages.to_s).to match(/oh no spaghettios/)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'value is blank' do
|
51
|
+
let(:value) { nil }
|
52
|
+
|
53
|
+
specify do
|
54
|
+
expect(subject).to be_valid
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'an empty array' do
|
58
|
+
let(:value) { [] }
|
59
|
+
|
60
|
+
specify do
|
61
|
+
expect(subject).to be_valid
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'an empty hash' do
|
66
|
+
let(:value) { {} }
|
67
|
+
|
68
|
+
specify do
|
69
|
+
expect(subject).to be_valid
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
describe 'on' do
|
4
|
+
class TestOn
|
5
|
+
include ActiveModel::Validations
|
6
|
+
|
7
|
+
attr_accessor :foo
|
8
|
+
|
9
|
+
validates_subset :foo, [1, 2, 3], on: :special_method
|
10
|
+
|
11
|
+
def special_method; end
|
12
|
+
end
|
13
|
+
|
14
|
+
subject { sub = TestOn.new; sub.foo = value; sub }
|
15
|
+
|
16
|
+
it 'adds the options to the validation' do
|
17
|
+
options = TestOn.validators_on(:foo).first.options
|
18
|
+
expect(options).to include(:on)
|
19
|
+
expect(options[:on]).to eq(:special_method)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
describe 'strict' do
|
4
|
+
context 'default exception for strict validation' do
|
5
|
+
class TestStrictDefault
|
6
|
+
include ActiveModel::Validations
|
7
|
+
|
8
|
+
attr_accessor :foo
|
9
|
+
|
10
|
+
validates_subset :foo, [1, 2, 3], strict: true
|
11
|
+
end
|
12
|
+
|
13
|
+
subject { sub = TestStrictDefault.new; sub.foo = value; sub }
|
14
|
+
|
15
|
+
context 'input is valid' do
|
16
|
+
let(:value) { [1] }
|
17
|
+
|
18
|
+
it 'is valid' do
|
19
|
+
expect(subject).to be_valid
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'does not raise any errors' do
|
23
|
+
expect do
|
24
|
+
subject.valid?
|
25
|
+
end.to_not raise_error
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'input is invalid' do
|
30
|
+
let(:value) { 'banana' }
|
31
|
+
|
32
|
+
it 'raises an error' do
|
33
|
+
expect do
|
34
|
+
subject.valid?
|
35
|
+
end.to raise_error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'specific exception for strict validation' do
|
41
|
+
class TestStrictSpecific
|
42
|
+
class SomeStrictError < StandardError; end
|
43
|
+
|
44
|
+
include ActiveModel::Validations
|
45
|
+
|
46
|
+
attr_accessor :foo
|
47
|
+
|
48
|
+
validates_subset :foo, [1, 2, 3], strict: SomeStrictError
|
49
|
+
end
|
50
|
+
|
51
|
+
subject { sub = TestStrictSpecific.new; sub.foo = value; sub }
|
52
|
+
|
53
|
+
context 'input is valid' do
|
54
|
+
let(:value) { [1] }
|
55
|
+
|
56
|
+
it 'is valid' do
|
57
|
+
expect(subject).to be_valid
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not raise any errors' do
|
61
|
+
expect do
|
62
|
+
subject.valid?
|
63
|
+
end.to_not raise_error
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'input is invalid' do
|
68
|
+
let(:value) { 'banana' }
|
69
|
+
|
70
|
+
it 'raises the custom error' do
|
71
|
+
expect do
|
72
|
+
subject.valid?
|
73
|
+
end.to raise_error(TestStrictSpecific::SomeStrictError)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative '../../../lib/validates_subset'
|
2
|
+
|
3
|
+
describe 'unless condition' do
|
4
|
+
subject { sub = TestUnlessTrue.new; sub.foo = value; sub }
|
5
|
+
|
6
|
+
context 'if condition results in true' do
|
7
|
+
|
8
|
+
class TestUnlessTrue
|
9
|
+
include ActiveModel::Validations
|
10
|
+
|
11
|
+
attr_accessor :foo
|
12
|
+
|
13
|
+
validates_subset :foo, [1, 2, 3], unless: -> { true }
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'value is a valid subset' do
|
17
|
+
let(:value) { [1] }
|
18
|
+
|
19
|
+
specify do
|
20
|
+
expect(subject).to be_valid
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'value is not a valid subset' do
|
25
|
+
let(:value) { %i[a b c] }
|
26
|
+
|
27
|
+
specify do
|
28
|
+
expect(subject).to be_valid
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context 'value is not an array' do
|
33
|
+
let(:value) { 'bar' }
|
34
|
+
|
35
|
+
specify do
|
36
|
+
expect(subject).to be_valid
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'condition results is not true' do
|
42
|
+
class TestUnlessFalse
|
43
|
+
include ActiveModel::Validations
|
44
|
+
|
45
|
+
attr_accessor :foo
|
46
|
+
|
47
|
+
validates_subset :foo, [1, 2, 3], unless: -> { false }
|
48
|
+
end
|
49
|
+
|
50
|
+
subject { sub = TestUnlessFalse.new; sub.foo = value; sub }
|
51
|
+
|
52
|
+
context 'value is a valid subset' do
|
53
|
+
let(:value) { [1] }
|
54
|
+
|
55
|
+
specify do
|
56
|
+
expect(subject).to be_valid
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'value is not a valid subset' do
|
61
|
+
let(:value) { %i[a b c] }
|
62
|
+
|
63
|
+
specify do
|
64
|
+
expect(subject).to_not be_valid
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'value is not an array' do
|
69
|
+
let(:value) { 'bar' }
|
70
|
+
|
71
|
+
specify do
|
72
|
+
expect(subject).to_not be_valid
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require_relative '../../lib/validates_subset'
|
2
|
+
|
3
|
+
class ActiveModelTestClass
|
4
|
+
include ActiveModel::Validations
|
5
|
+
|
6
|
+
attr_accessor :foo
|
7
|
+
|
8
|
+
validates_subset :foo, [1, 2, 3]
|
9
|
+
|
10
|
+
def initialize(foo)
|
11
|
+
@foo = foo
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ValidatesSubset do
|
16
|
+
subject { ActiveModelTestClass.new(attribute_value) }
|
17
|
+
|
18
|
+
context 'attribute is a valid subset' do
|
19
|
+
let(:attribute_value) { [1, 2] }
|
20
|
+
|
21
|
+
it 'is valid' do
|
22
|
+
expect(subject).to be_valid
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'attribute is not a valid subset' do
|
27
|
+
context 'value is still an array' do
|
28
|
+
let(:attribute_value) { [5, 6] }
|
29
|
+
|
30
|
+
it 'does not error' do
|
31
|
+
expect do
|
32
|
+
subject.validate
|
33
|
+
end.to_not raise_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'is not valid' do
|
37
|
+
expect(subject).to_not be_valid
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'has an error message with the key of the validated attribute' do
|
41
|
+
subject.validate
|
42
|
+
expect(subject.errors).to have_key(:foo)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require_relative '../../lib/arguments'
|
2
|
+
|
3
|
+
module ValidatesSubset
|
4
|
+
describe Arguments do
|
5
|
+
|
6
|
+
let(:attribute_name) { :foo }
|
7
|
+
let(:superset) { %w(bar qux) }
|
8
|
+
let(:options) { { extra: :options } }
|
9
|
+
|
10
|
+
subject { described_class.new(attribute_name, superset, options) }
|
11
|
+
|
12
|
+
describe '#to_validation_attributes' do
|
13
|
+
context 'all pertinent attributes are present' do
|
14
|
+
specify do
|
15
|
+
expect(subject.to_validation_attributes).to eq([attribute_name, { subset: superset }.merge(options)])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'superset is nil' do
|
20
|
+
let(:superset) { nil }
|
21
|
+
|
22
|
+
specify do
|
23
|
+
expect(subject.to_validation_attributes).to eq([attribute_name, { subset: superset }.merge(options)])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'attribute_name is nil' do
|
28
|
+
let(:attribute_name) { nil }
|
29
|
+
|
30
|
+
specify do
|
31
|
+
expect(subject.to_validation_attributes).to eq([attribute_name, { subset: superset }.merge(options)])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'options is nil' do
|
36
|
+
let(:options) { nil }
|
37
|
+
|
38
|
+
specify do
|
39
|
+
expect(subject.to_validation_attributes).to eq([attribute_name, { subset: superset }])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#subset' do
|
45
|
+
context 'subset is given' do
|
46
|
+
specify do
|
47
|
+
expect(subject.send(:subset)).to eq({ subset: superset })
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'subset is nil' do
|
52
|
+
let(:superset) { nil }
|
53
|
+
|
54
|
+
specify do
|
55
|
+
expect(subject.send(:subset)).to eq({ subset: nil })
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#merged_options' do
|
61
|
+
context 'options are present' do
|
62
|
+
specify do
|
63
|
+
expect(subject.send(:merged_options)).to eq({ subset: superset }.merge(options))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'options is nil' do
|
68
|
+
let(:options) { nil }
|
69
|
+
|
70
|
+
specify do
|
71
|
+
expect(subject.send(:merged_options)).to eq({ subset: superset })
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'options is a blank hash' do
|
76
|
+
let(:options) { {} }
|
77
|
+
|
78
|
+
specify do
|
79
|
+
expect(subject.send(:merged_options)).to eq({ subset: superset })
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require_relative '../../lib/validates_subset'
|
2
|
+
|
3
|
+
module ActiveModel
|
4
|
+
module Validations
|
5
|
+
describe SubsetValidator do
|
6
|
+
describe '#initialize' do
|
7
|
+
let(:options) { { attributes: [:thing], foo: :bar, subset: [] } }
|
8
|
+
subject { described_class.new(options) }
|
9
|
+
|
10
|
+
it 'sets the options instance variable' do
|
11
|
+
expect(subject.instance_variable_get(:@options)).to_not be_nil
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'removes the attributes from the options' do
|
15
|
+
expect(subject.instance_variable_get(:@options)).to_not have_key(:attributes)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'adds a message to the options' do
|
19
|
+
expect(subject.instance_variable_get(:@options)).to have_key(:message)
|
20
|
+
expect(subject.instance_variable_get(:@options)[:message]).to_not be_blank
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#validate_each' do
|
25
|
+
let(:return_value) { nil }
|
26
|
+
subject { described_class.new(attributes: [:foo]) }
|
27
|
+
|
28
|
+
before do
|
29
|
+
allow(subject).to receive(:is_subset?) { return_value }
|
30
|
+
allow(subject).to receive(:add_errors_or_raise) { nil }
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'calls the validation logic' do
|
34
|
+
expect(subject).to receive(:is_subset?)
|
35
|
+
subject.validate_each(anything, anything, anything)
|
36
|
+
end
|
37
|
+
|
38
|
+
context 'validation passes' do
|
39
|
+
let(:return_value) { true }
|
40
|
+
|
41
|
+
it 'does not add errors on the validated model' do
|
42
|
+
expect(subject).to_not receive(:add_errors_or_raise)
|
43
|
+
subject.validate_each(anything, anything, anything)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'does not throw any errors' do
|
47
|
+
expect do
|
48
|
+
subject.validate_each(anything, anything, anything)
|
49
|
+
end.to_not raise_error
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'validation fails' do
|
54
|
+
let(:return_value) { false }
|
55
|
+
|
56
|
+
it 'adds values to the errors on the validated model' do
|
57
|
+
expect(subject).to receive(:add_errors_or_raise)
|
58
|
+
subject.validate_each(anything, anything, anything)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe '.validate_subset' do
|
65
|
+
class IncludedClass
|
66
|
+
include ActiveModel::Validations
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'validates with SubsetValidator' do
|
70
|
+
included_class = IncludedClass
|
71
|
+
expect(included_class).to receive(:validates_with)
|
72
|
+
.with(SubsetValidator, anything)
|
73
|
+
included_class.validates_subset(anything, anything)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
require_relative './version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'validates_subset'
|
7
|
+
s.version = ValidatesSubset::VERSION
|
8
|
+
s.summary = %q{Subset validation for ActiveModel/ActiveRecord models}
|
9
|
+
s.description = %q{This library helps validate that an attribute is a subset of a specified set}
|
10
|
+
s.authors = ['Jake Yesbeck']
|
11
|
+
s.email = 'yesbeckjs@gmail.com'
|
12
|
+
s.homepage = 'http://rubygems.org/gems/validates_subset'
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = s.files.grep(/^spec\//)
|
18
|
+
|
19
|
+
s.required_ruby_version = '>= 1.9.3'
|
20
|
+
|
21
|
+
s.add_dependency 'activemodel', '>= 3.0'
|
22
|
+
|
23
|
+
s.add_development_dependency 'bundler', '~> 1.3'
|
24
|
+
s.add_development_dependency 'rake', '~> 10.0'
|
25
|
+
s.add_development_dependency 'rspec', '~> 3.0'
|
26
|
+
end
|
data/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: validates_subset
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jake Yesbeck
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-06-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activemodel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.0'
|
69
|
+
description: This library helps validate that an attribute is a subset of a specified
|
70
|
+
set
|
71
|
+
email: yesbeckjs@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- Gemfile.lock
|
80
|
+
- Guardfile
|
81
|
+
- README.md
|
82
|
+
- lib/arguments.rb
|
83
|
+
- lib/validates_subset.rb
|
84
|
+
- spec/integration/modifiers/allow_blank_spec.rb
|
85
|
+
- spec/integration/modifiers/allow_nil_spec.rb
|
86
|
+
- spec/integration/modifiers/if_spec.rb
|
87
|
+
- spec/integration/modifiers/message_spec.rb
|
88
|
+
- spec/integration/modifiers/multiple_spec.rb
|
89
|
+
- spec/integration/modifiers/on_spec.rb
|
90
|
+
- spec/integration/modifiers/strict_spec.rb
|
91
|
+
- spec/integration/modifiers/unless_spec.rb
|
92
|
+
- spec/integration/validations_spec.rb
|
93
|
+
- spec/lib/arguments_spec.rb
|
94
|
+
- spec/lib/validates_subset_spec.rb
|
95
|
+
- validates_subset.gemspec
|
96
|
+
- version.rb
|
97
|
+
homepage: http://rubygems.org/gems/validates_subset
|
98
|
+
licenses:
|
99
|
+
- MIT
|
100
|
+
metadata: {}
|
101
|
+
post_install_message:
|
102
|
+
rdoc_options: []
|
103
|
+
require_paths:
|
104
|
+
- lib
|
105
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 1.9.3
|
110
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
|
+
requirements:
|
112
|
+
- - ">="
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project:
|
117
|
+
rubygems_version: 2.4.6
|
118
|
+
signing_key:
|
119
|
+
specification_version: 4
|
120
|
+
summary: Subset validation for ActiveModel/ActiveRecord models
|
121
|
+
test_files:
|
122
|
+
- spec/integration/modifiers/allow_blank_spec.rb
|
123
|
+
- spec/integration/modifiers/allow_nil_spec.rb
|
124
|
+
- spec/integration/modifiers/if_spec.rb
|
125
|
+
- spec/integration/modifiers/message_spec.rb
|
126
|
+
- spec/integration/modifiers/multiple_spec.rb
|
127
|
+
- spec/integration/modifiers/on_spec.rb
|
128
|
+
- spec/integration/modifiers/strict_spec.rb
|
129
|
+
- spec/integration/modifiers/unless_spec.rb
|
130
|
+
- spec/integration/validations_spec.rb
|
131
|
+
- spec/lib/arguments_spec.rb
|
132
|
+
- spec/lib/validates_subset_spec.rb
|