sullivan 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +6 -0
- data/lib/sullivan.rb +28 -0
- data/lib/sullivan/validations/hash.rb +35 -0
- data/lib/sullivan/validations/kind_of.rb +15 -0
- data/lib/sullivan/validations/many.rb +29 -0
- data/lib/sullivan/validations/optional.rb +18 -0
- data/lib/sullivan/validations/string_matching.rb +20 -0
- data/lib/sullivan/version.rb +3 -0
- data/spec/sullivan/validations/hash_spec.rb +78 -0
- data/spec/sullivan/validations/kind_of_spec.rb +21 -0
- data/spec/sullivan/validations/many_spec.rb +67 -0
- data/spec/sullivan/validations/optional_spec.rb +33 -0
- data/spec/sullivan/validations/string_matching_spec.rb +22 -0
- data/spec/sullivan_spec.rb +19 -0
- data/sullivan.gemspec +24 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b993257c0f51eb41768a9c272798cd6ec6caa160
|
4
|
+
data.tar.gz: 5e15408676c3ad43fb4645581120072914ae60aa
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: da18cbc61e3cff2bb8e1715126a9e46dd8ead724d719a5c8534eb3717074fac16568ac9127bc461aeb32515d30981400e925e3c7c4e4511abef429f51ce8e675
|
7
|
+
data.tar.gz: 13dece6a3657c7e653b87db7847ef42ad6faee4db2c6ee70cc52d62295ab05f08c4781bb3f5913843dee6a4499a6805797a168bd849cb9475773c71ef5ad34d8
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Go Daddy Operating Company, LLC
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# Sullivan
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'sullivan'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install sullivan
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it ( http://github.com/<my-github-username>/sullivan/fork )
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/sullivan.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
module Sullivan
|
2
|
+
def self.validation(&block)
|
3
|
+
DSL.new.instance_eval(&block)
|
4
|
+
end
|
5
|
+
|
6
|
+
class DSL < BasicObject
|
7
|
+
def method_missing(method_name, *args)
|
8
|
+
constant_name = DSL.camelize(method_name.to_s)
|
9
|
+
|
10
|
+
if ::Sullivan::Validations.const_defined?(constant_name)
|
11
|
+
klass = ::Sullivan::Validations.const_get(constant_name)
|
12
|
+
klass.new(*args)
|
13
|
+
else
|
14
|
+
super
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.camelize(string)
|
19
|
+
string.split('_').map(&:capitalize).join
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
require 'sullivan/validations/hash.rb'
|
25
|
+
require 'sullivan/validations/kind_of.rb'
|
26
|
+
require 'sullivan/validations/many.rb'
|
27
|
+
require 'sullivan/validations/optional.rb'
|
28
|
+
require 'sullivan/validations/string_matching.rb'
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Sullivan
|
2
|
+
module Validations
|
3
|
+
class Hash
|
4
|
+
def initialize(validations)
|
5
|
+
@validations = validations
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate(hash)
|
9
|
+
return 'must be a hash' unless hash.respond_to?(:to_hash)
|
10
|
+
hash = hash.to_hash
|
11
|
+
|
12
|
+
errors = @validations.each_with_object({}) { |(key, validation), h|
|
13
|
+
error = validation.validate(hash[key])
|
14
|
+
h[key] = error unless error.nil?
|
15
|
+
}
|
16
|
+
|
17
|
+
errors.merge! (hash.keys - @validations.keys).each_with_object({}) { |unexpected_key, h| h[unexpected_key] = 'is unexpected' }
|
18
|
+
|
19
|
+
errors unless errors.empty?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class StringHash < Hash
|
24
|
+
def initialize(validations)
|
25
|
+
super stringify_keys(validations)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def stringify_keys(hash)
|
31
|
+
hash.each_with_object({}) { |(k, v), h| h[k.to_s] = v }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Sullivan
|
2
|
+
module Validations
|
3
|
+
class Many
|
4
|
+
def initialize(validation, at_least: nil, at_most: nil)
|
5
|
+
@validation = validation
|
6
|
+
@at_least = at_least
|
7
|
+
@at_most = at_most
|
8
|
+
end
|
9
|
+
|
10
|
+
def validate(values)
|
11
|
+
return 'must be an array' unless values.respond_to?(:map)
|
12
|
+
return "must contain at least #{num_elements(@at_least)}" if @at_least && values.size < @at_least
|
13
|
+
return "must contain at most #{num_elements(@at_most)}" if @at_most && values.size > @at_most
|
14
|
+
|
15
|
+
errors = values.map do |value|
|
16
|
+
@validation.validate(value)
|
17
|
+
end
|
18
|
+
|
19
|
+
errors unless errors.all?(&:nil?)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def num_elements(n)
|
25
|
+
"#{n} #{n == 1 ? 'element' : 'elements'}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sullivan
|
2
|
+
module Validations
|
3
|
+
class Optional
|
4
|
+
def initialize(validation)
|
5
|
+
@validation = validation
|
6
|
+
end
|
7
|
+
|
8
|
+
def validate(value)
|
9
|
+
unless value.nil?
|
10
|
+
error = @validation.validate(value)
|
11
|
+
if error
|
12
|
+
error.respond_to?(:to_str) ? "#{error.to_str}, if present" : error
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sullivan
|
2
|
+
module Validations
|
3
|
+
class StringMatching
|
4
|
+
def initialize(regex, error: nil)
|
5
|
+
@regex = regex
|
6
|
+
@custom_error = error
|
7
|
+
end
|
8
|
+
|
9
|
+
def validate(value)
|
10
|
+
error unless value.respond_to?(:to_str) && value.to_str =~ @regex
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def error
|
16
|
+
@custom_error || "must be a string matching #{@regex.inspect}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'sullivan/validations/hash'
|
2
|
+
require 'sullivan/validations/kind_of'
|
3
|
+
|
4
|
+
describe Sullivan::Validations::Hash do
|
5
|
+
def hash(validations)
|
6
|
+
Sullivan::Validations::Hash.new(validations)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:kind_of_string) { Sullivan::Validations::KindOf.new(String) }
|
10
|
+
|
11
|
+
it 'accepts a hash with matching keys' do
|
12
|
+
error = hash(a: kind_of_string).validate({a: 'a string'})
|
13
|
+
expect(error).to be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'does not accept a hash with non-matching keys' do
|
17
|
+
error = hash(a: kind_of_string).validate({a: 1})
|
18
|
+
expect(error).to eq({a: 'must be a kind of String'})
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'does not accept a hash with extra keys' do
|
22
|
+
error = hash({}).validate({a: 'a string'})
|
23
|
+
expect(error).to eq({a: 'is unexpected'})
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not accept a hash with missing keys' do
|
27
|
+
error = hash(a: kind_of_string).validate({})
|
28
|
+
expect(error).to eq({a: 'must be a kind of String'})
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not accept a non-hash' do
|
32
|
+
error = hash({a: kind_of_string}).validate('a')
|
33
|
+
expect(error).to eq('must be a hash')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'nests' do
|
37
|
+
error = hash(a: hash(b: kind_of_string)).validate({a: {b: 1}})
|
38
|
+
expect(error).to eq({a: {b: 'must be a kind of String'}})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Sullivan::Validations::StringHash do
|
43
|
+
def string_hash(validations)
|
44
|
+
Sullivan::Validations::StringHash.new(validations)
|
45
|
+
end
|
46
|
+
|
47
|
+
let(:kind_of_string) { Sullivan::Validations::KindOf.new(String) }
|
48
|
+
|
49
|
+
it 'accepts a hash with matching keys' do
|
50
|
+
error = string_hash(a: kind_of_string).validate({'a' => 'a string'})
|
51
|
+
expect(error).to be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not accept a hash with non-matching keys' do
|
55
|
+
error = string_hash(a: kind_of_string).validate({'a' => 1})
|
56
|
+
expect(error).to eq({'a' => 'must be a kind of String'})
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'does not accept a hash with extra keys' do
|
60
|
+
error = string_hash({}).validate({'a' => 'a string'})
|
61
|
+
expect(error).to eq({'a' => 'is unexpected'})
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'does not accept a hash with missing keys' do
|
65
|
+
error = string_hash(a: kind_of_string).validate({})
|
66
|
+
expect(error).to eq({'a' => 'must be a kind of String'})
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'does not accept a non-hash' do
|
70
|
+
error = string_hash({'a' => kind_of_string}).validate('a')
|
71
|
+
expect(error).to eq('must be a hash')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'nests' do
|
75
|
+
error = string_hash(a: string_hash(b: kind_of_string)).validate({'a' => {'b' => 1}})
|
76
|
+
expect(error).to eq({'a' => {'b' => 'must be a kind of String'}})
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'sullivan/validations/kind_of'
|
2
|
+
|
3
|
+
describe Sullivan::Validations::KindOf do
|
4
|
+
let(:validation) { Sullivan::Validations::KindOf.new(String) }
|
5
|
+
|
6
|
+
it 'accepts an object of the given type' do
|
7
|
+
error = validation.validate("a string")
|
8
|
+
expect(error).to be_nil
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'accepts an object of a subtype of the given type' do
|
12
|
+
special_string_class = Class.new(String)
|
13
|
+
error = validation.validate(special_string_class.new("a string"))
|
14
|
+
expect(error).to be_nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'does not accept an object of an unrelated type' do
|
18
|
+
error = validation.validate(1)
|
19
|
+
expect(error).to eq("must be a kind of String")
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'sullivan/validations/many'
|
2
|
+
require 'sullivan/validations/kind_of'
|
3
|
+
require 'sullivan/validations/hash'
|
4
|
+
|
5
|
+
describe Sullivan::Validations::Many do
|
6
|
+
def many(validation, **opts)
|
7
|
+
Sullivan::Validations::Many.new(validation, **opts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def hash(validations)
|
11
|
+
Sullivan::Validations::Hash.new(validations)
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:kind_of_string) { Sullivan::Validations::KindOf.new(String) }
|
15
|
+
|
16
|
+
it 'accepts an empty array' do
|
17
|
+
error = many(kind_of_string).validate([])
|
18
|
+
expect(error).to be_nil
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'accepts an array of matching elements' do
|
22
|
+
error = many(kind_of_string).validate(['a', 'b'])
|
23
|
+
expect(error).to be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not accept an array including a non-matching element' do
|
27
|
+
error = many(kind_of_string).validate(['a', 2])
|
28
|
+
expect(error).to eq([nil, 'must be a kind of String'])
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'accepts an array of matching hashes' do
|
32
|
+
error = many(hash(v: kind_of_string)).validate([{v: 'a'}, {v: 'b'}])
|
33
|
+
expect(error).to be_nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'does not accept an array including a non-matching element' do
|
37
|
+
error = many(hash(v: kind_of_string)).validate([{v: 'a'}, {v: 2}])
|
38
|
+
expect(error).to eq([nil, {v: 'must be a kind of String'}])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not accept a non-enumerable' do
|
42
|
+
error = many(hash(v: kind_of_string)).validate('a')
|
43
|
+
expect(error).to eq('must be an array')
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with size requirements" do
|
47
|
+
it 'does not accept an array with too few elements' do
|
48
|
+
error = many(kind_of_string, at_least: 1).validate([])
|
49
|
+
expect(error).to eq('must contain at least 1 element')
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'accepts an array with enough elements' do
|
53
|
+
error = many(kind_of_string, at_least: 1).validate(['a'])
|
54
|
+
expect(error).to be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'does not accept an array with too many elements' do
|
58
|
+
error = many(kind_of_string, at_most: 2).validate(['a', 'b', 'c'])
|
59
|
+
expect(error).to eq('must contain at most 2 elements')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'accepts an array with few enough elements' do
|
63
|
+
error = many(kind_of_string, at_most: 2).validate(['a', 'b'])
|
64
|
+
expect(error).to be_nil
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'sullivan/validations/optional'
|
2
|
+
|
3
|
+
describe Sullivan::Validations::Optional do
|
4
|
+
def optional(validation)
|
5
|
+
Sullivan::Validations::Optional.new(validation)
|
6
|
+
end
|
7
|
+
|
8
|
+
def hash(validations)
|
9
|
+
Sullivan::Validations::Hash.new(validations)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:kind_of_string) { Sullivan::Validations::KindOf.new(String) }
|
13
|
+
|
14
|
+
it 'should accept a missing value' do
|
15
|
+
error = optional(kind_of_string).validate(nil)
|
16
|
+
expect(error).to be_nil
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should accept a present, matching value' do
|
20
|
+
error = optional(kind_of_string).validate('foo')
|
21
|
+
expect(error).to be_nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should reject a present, non-matching value' do
|
25
|
+
error = optional(kind_of_string).validate(123)
|
26
|
+
expect(error).to eq('must be a kind of String, if present')
|
27
|
+
end
|
28
|
+
|
29
|
+
it "doesn't try to add 'if present' to structured errors" do
|
30
|
+
error = optional(hash(a: kind_of_string)).validate(a: 123)
|
31
|
+
expect(error).to eq(a: 'must be a kind of String')
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'sullivan/validations/string_matching'
|
2
|
+
|
3
|
+
describe Sullivan::Validations::StringMatching do
|
4
|
+
def string_matching(validation, **opts)
|
5
|
+
Sullivan::Validations::StringMatching.new(validation, **opts)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "accepts a string which matches" do
|
9
|
+
error = string_matching(/please/).validate('Gimme, please.')
|
10
|
+
expect(error).to be_nil
|
11
|
+
end
|
12
|
+
|
13
|
+
it "does not accept a string which doesn't match" do
|
14
|
+
error = string_matching(/please/).validate('Gimme.')
|
15
|
+
expect(error).to eq('must be a string matching /please/')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "takes a custom message" do
|
19
|
+
error = string_matching(/abc/, error: 'must contain the magic word').validate('Gimme.')
|
20
|
+
expect(error).to eq('must contain the magic word')
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'sullivan'
|
2
|
+
|
3
|
+
describe Sullivan do
|
4
|
+
describe ".validation" do
|
5
|
+
it "provides a convenient way to access the built-in validations" do
|
6
|
+
v = Sullivan.validation do
|
7
|
+
hash(
|
8
|
+
string_matching: string_matching(/\Al(ol)+\z/, error: "must be be a laugh"),
|
9
|
+
kind_of: kind_of(Numeric),
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
error = v.validate({})
|
14
|
+
|
15
|
+
expect(error[:string_matching]).to eq("must be be a laugh")
|
16
|
+
expect(error[:kind_of]).to eq("must be a kind of Numeric")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/sullivan.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sullivan/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sullivan"
|
8
|
+
spec.version = Sullivan::VERSION
|
9
|
+
spec.authors = ["Peter Jaros"]
|
10
|
+
spec.email = ["peter.a.jaros@gmail.com"]
|
11
|
+
spec.summary = %q{A simple, composable way to validate the structure of data.}
|
12
|
+
spec.description = %q{A simple, composable way to validate the structure of data. "Form ever follows function. This is the law." — Louis Henry Sullivan}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.1.5"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sullivan
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter Jaros
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.1.5
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.5
|
55
|
+
description: A simple, composable way to validate the structure of data. "Form ever
|
56
|
+
follows function. This is the law." — Louis Henry Sullivan
|
57
|
+
email:
|
58
|
+
- peter.a.jaros@gmail.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- lib/sullivan.rb
|
69
|
+
- lib/sullivan/validations/hash.rb
|
70
|
+
- lib/sullivan/validations/kind_of.rb
|
71
|
+
- lib/sullivan/validations/many.rb
|
72
|
+
- lib/sullivan/validations/optional.rb
|
73
|
+
- lib/sullivan/validations/string_matching.rb
|
74
|
+
- lib/sullivan/version.rb
|
75
|
+
- spec/sullivan/validations/hash_spec.rb
|
76
|
+
- spec/sullivan/validations/kind_of_spec.rb
|
77
|
+
- spec/sullivan/validations/many_spec.rb
|
78
|
+
- spec/sullivan/validations/optional_spec.rb
|
79
|
+
- spec/sullivan/validations/string_matching_spec.rb
|
80
|
+
- spec/sullivan_spec.rb
|
81
|
+
- sullivan.gemspec
|
82
|
+
homepage: ''
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
requirements: []
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.2.0
|
103
|
+
signing_key:
|
104
|
+
specification_version: 4
|
105
|
+
summary: A simple, composable way to validate the structure of data.
|
106
|
+
test_files:
|
107
|
+
- spec/sullivan/validations/hash_spec.rb
|
108
|
+
- spec/sullivan/validations/kind_of_spec.rb
|
109
|
+
- spec/sullivan/validations/many_spec.rb
|
110
|
+
- spec/sullivan/validations/optional_spec.rb
|
111
|
+
- spec/sullivan/validations/string_matching_spec.rb
|
112
|
+
- spec/sullivan_spec.rb
|
113
|
+
has_rdoc:
|