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