hash_validator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2e41604544ea1db1c1d88b8c49c59d7edcc96821
4
+ data.tar.gz: 5b5f86c50484ffdf9784534ce3e33ccf150fb0bb
5
+ SHA512:
6
+ metadata.gz: 11f7746ceca1018580e21d7f05a6ceae369339c94cd1f28ad40303e8f68534b5b9355293f96c483dd59ef9bbb2c09aa2a6c97cc764828d73e0ec7150293662ad
7
+ data.tar.gz: 3d97b917af1eba349ca698cd823dd9e4c53bec687ea82c12315682d2d283ca10bdb53c2230915c645d552d95d65e3d7881ee74ea222b2bfa2392036073cd892c
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ - 2.0.0
6
+ - jruby-19mode
7
+ - rbx-19mode
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in hash_validator.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 James Brooks
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.
@@ -0,0 +1,77 @@
1
+ # Hash Validator
2
+
3
+ [![Build Status](https://travis-ci.org/JamesBrooks/hash_validator.png)](https://travis-ci.org/JamesBrooks/hash_validator)
4
+ [![Code Climate](https://codeclimate.com/github/JamesBrooks/hash_validator.png)](https://codeclimate.com/github/JamesBrooks/git-runner)
5
+ [![Gem Version](https://badge.fury.io/rb/hash_validator.png)](http://badge.fury.io/rb/git-runner)
6
+ [![Dependency Status](https://gemnasium.com/JamesBrooks/hash_validator.png)](https://gemnasium.com/JamesBrooks/git-runner)
7
+
8
+ Ruby library to validate hashes (Hash) against user-defined requirements
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'hash_validator'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install hash_validator
23
+
24
+ ## Example
25
+ ````
26
+ # Validations hash
27
+ validations = {
28
+ user: {
29
+ first_name: 'string',
30
+ last_name: 'string',
31
+ age: 'numeric',
32
+ likes: 'array'
33
+ }
34
+ }
35
+
36
+ # Hash to validate
37
+ hash = {
38
+ foo: 1,
39
+ bar: 'baz',
40
+ user: {
41
+ first_name: 'James',
42
+ last_name: 12345
43
+ }
44
+ }
45
+
46
+ validator = HashValidator.validate(hash, validations)
47
+
48
+ validator.valid?
49
+ # => false
50
+
51
+ validator.errors
52
+ # {
53
+ :user => {
54
+ :last_name => "should be string",
55
+ :age => "numeric required",
56
+ :likes => "array required"
57
+ }
58
+ }
59
+ ````
60
+
61
+ ## Usage
62
+
63
+ Define a validation hash which will be used to validate. This has can be nested as deeply as required using the following values to validate specific value types:
64
+
65
+ * `string`
66
+ * `numeric`
67
+ * `array`
68
+ * `time`
69
+ * hashes are validates by nesting validations, or if just the presence of a hash is required `{}` can be used.
70
+
71
+ ## Contributing
72
+
73
+ 1. Fork it
74
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
75
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
76
+ 4. Push to the branch (`git push origin my-new-feature`)
77
+ 5. Create new Pull Request
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -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 'hash_validator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "hash_validator"
8
+ spec.version = HashValidator::VERSION
9
+ spec.authors = ["James Brooks"]
10
+ spec.email = ["james@gooddogdesign.com"]
11
+ spec.description = "Ruby library to validate hashes (Hash) against user-defined requirements"
12
+ spec.summary = "Ruby library to validate hashes (Hash) against user-defined requirements"
13
+ spec.homepage = "https://github.com/JamesBrooks/hash_validator"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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.3'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec', '~> 2.13.0'
24
+ end
@@ -0,0 +1,9 @@
1
+ require 'hash_validator/base'
2
+ require 'hash_validator/version'
3
+ require 'hash_validator/validators'
4
+
5
+ module HashValidator
6
+ def self.validate(*args)
7
+ Base.validate(*args)
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ class HashValidator::Base
2
+ attr_accessor :hash, :validations, :errors
3
+
4
+
5
+ def initialize(hash, validations)
6
+ self.errors = {}
7
+ self.hash = hash
8
+ self.validations = validations
9
+
10
+ validate
11
+ end
12
+
13
+ def valid?
14
+ errors.empty?
15
+ end
16
+
17
+ def self.validate(hash, validations)
18
+ new(hash, validations)
19
+ end
20
+
21
+
22
+ private
23
+ def validate
24
+ HashValidator.validator_for(hash).validate(:base, self.hash, self.validations, self.errors)
25
+ self.errors = errors[:base]
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ module HashValidator
2
+ @@validators = []
3
+
4
+
5
+ def self.append_validator(validator)
6
+ @@validators << validator
7
+ end
8
+
9
+ def self.validator_for(rhs)
10
+ @@validators.detect { |v| v.should_validate?(rhs) } || raise(StandardError.new("Could not find valid validator for: #{rhs}"))
11
+ end
12
+
13
+ module Validator
14
+ end
15
+ end
16
+
17
+ # Load validators
18
+ require 'hash_validator/validators/base'
19
+ require 'hash_validator/validators/hash_validator'
20
+ require 'hash_validator/validators/simple_type_validator'
@@ -0,0 +1,9 @@
1
+ class HashValidator::Validator::Base
2
+ def should_validate?(name)
3
+ raise StandardError.new('should_validate? should not be called directly on BaseValidator')
4
+ end
5
+
6
+ def validate(key, value, validations, errors)
7
+ raise StandardError.new('validate should not be called directly on BaseValidator')
8
+ end
9
+ end
@@ -0,0 +1,38 @@
1
+ class HashValidator::Validator::HashValidator < HashValidator::Validator::Base
2
+ def name
3
+ 'hash'
4
+ end
5
+
6
+ def should_validate?(rhs)
7
+ rhs.is_a?(Hash)
8
+ end
9
+
10
+ def validate(key, value, validations, errors)
11
+ # Validate hash
12
+ unless value.is_a?(Hash)
13
+ errors[name] = 'should be hash'
14
+ return
15
+ end
16
+
17
+ # Hashes can contain sub-elements, attempt to validator those
18
+ errors = (errors[key] = {})
19
+
20
+ validations.each do |v_key, v_value|
21
+ validator = HashValidator.validator_for(v_value)
22
+
23
+ # Key presence
24
+ unless value[v_key]
25
+ errors[v_key] = "#{validator.name} required"
26
+ next
27
+ end
28
+
29
+ validator.validate(v_key, value[v_key], v_value, errors)
30
+ end
31
+
32
+ # Cleanup errors (remove any empty nested errors)
33
+ errors.delete_if { |k,v| v.empty? }
34
+ end
35
+ end
36
+
37
+
38
+ HashValidator.append_validator(HashValidator::Validator::HashValidator.new)
@@ -0,0 +1,28 @@
1
+ class HashValidator::Validator::SimpleTypeValidator < HashValidator::Validator::Base
2
+ attr_accessor :name, :klass
3
+
4
+
5
+ def initialize(name, klass)
6
+ self.name = name
7
+ self.klass = klass
8
+ end
9
+
10
+ def should_validate?(rhs)
11
+ rhs == self.name
12
+ end
13
+
14
+ def validate(key, value, validations, errors)
15
+ unless value.is_a?(klass)
16
+ errors[key] = "should be #{name}"
17
+ end
18
+ end
19
+ end
20
+
21
+
22
+ # Create simple type validators
23
+ [
24
+ [ 'array', Array ],
25
+ [ 'numeric', Numeric ],
26
+ [ 'string', String ],
27
+ [ 'time', Time ]
28
+ ].each { |name, klass| HashValidator.append_validator(HashValidator::Validator::SimpleTypeValidator.new(name, klass)) }
@@ -0,0 +1,3 @@
1
+ module HashValidator
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,149 @@
1
+ require 'spec_helper'
2
+
3
+ describe HashValidator do
4
+ describe 'individual type validations' do
5
+ it 'should validate hash' do
6
+ validate({ v: {} }, { v: {} }).valid?.should be_true
7
+ validate({ v: '' }, { v: {} }).valid?.should be_false
8
+ end
9
+
10
+ it 'should validate string' do
11
+ validate({ v: 'test' }, { v: 'string' }).valid?.should be_true
12
+ validate({ v: 123456 }, { v: 'string' }).valid?.should be_false
13
+ end
14
+
15
+ it 'should validate numeric' do
16
+ validate({ v: 1234 }, { v: 'numeric' }).valid?.should be_true
17
+ validate({ v: '12' }, { v: 'numeric' }).valid?.should be_false
18
+ end
19
+
20
+ it 'should validate array' do
21
+ validate({ v: [ 1,2,3 ] }, { v: 'array' }).valid?.should be_true
22
+ validate({ v: ' 1,2,3 ' }, { v: 'array' }).valid?.should be_false
23
+ end
24
+
25
+ it 'should validate time' do
26
+ validate({ v: Time.now }, { v: 'time' }).valid?.should be_true
27
+ validate({ v: '2013-04-12 13:18:05 +0930' }, { v: 'time' }).valid?.should be_false
28
+ end
29
+ end
30
+
31
+ describe 'full validations' do
32
+ let(:empty_hash) {{}}
33
+
34
+ let(:simple_hash) {{
35
+ foo: 1,
36
+ bar: 'baz'
37
+ }}
38
+
39
+ let(:invalid_simple_hash) {{
40
+ foo: 1,
41
+ bar: 2
42
+ }}
43
+
44
+ let(:complex_hash) {{
45
+ foo: 1,
46
+ bar: 'baz',
47
+ user: {
48
+ first_name: 'James',
49
+ last_name: 'Brooks',
50
+ age: 27,
51
+ likes: [ 'Ruby', 'Kendo', 'Board Games' ]
52
+ }
53
+ }}
54
+
55
+ let(:invalid_complex_hash) {{
56
+ foo: 1,
57
+ bar: 2,
58
+ user: {
59
+ first_name: 'James',
60
+ last_name: 'Brooks',
61
+ likes: 'Ruby, Kendo, Board Games'
62
+ }
63
+ }}
64
+
65
+ describe 'no validations' do
66
+ let(:validations) {{}}
67
+
68
+ it 'should validate an empty hash' do
69
+ v = validate(empty_hash, validations)
70
+ v.valid?.should be_true
71
+ v.errors.should be_empty
72
+ end
73
+
74
+ it 'should validate a simple hash' do
75
+ v = validate(simple_hash, validations)
76
+ v.valid?.should be_true
77
+ v.errors.should be_empty
78
+ end
79
+
80
+ it 'should validate a simple hash 2' do
81
+ v = validate(invalid_simple_hash, validations)
82
+ v.valid?.should be_true
83
+ v.errors.should be_empty
84
+ end
85
+
86
+ it 'should validate a complex hash' do
87
+ v = validate(complex_hash, validations)
88
+ v.valid?.should be_true
89
+ v.errors.should be_empty
90
+ end
91
+
92
+ it 'should validate a complex hash 2' do
93
+ v = validate(invalid_complex_hash, validations)
94
+ v.valid?.should be_true
95
+ v.errors.should be_empty
96
+ end
97
+ end
98
+
99
+ describe 'simple validations' do
100
+ let(:validations) {{ foo: 'numeric', bar: 'string' }}
101
+
102
+ it 'should not validate an empty hash (stating missing with required)' do
103
+ v = validate(empty_hash, validations)
104
+ v.valid?.should be_false
105
+ v.errors.should eq({ foo: 'numeric required', bar: 'string required' })
106
+ end
107
+
108
+ it 'should validate a simple hash' do
109
+ v = validate(simple_hash, validations)
110
+ v.valid?.should be_true
111
+ v.errors.should be_empty
112
+ end
113
+
114
+ it 'should not validate a simple hash 2' do
115
+ v = validate(invalid_simple_hash, validations)
116
+ v.valid?.should be_false
117
+ v.errors.should eq({ bar: 'should be string' })
118
+ end
119
+
120
+ it 'should validate a complex hash' do
121
+ v = validate(complex_hash, validations)
122
+ v.valid?.should be_true
123
+ v.errors.should be_empty
124
+ end
125
+
126
+ it 'should not validate a complex hash 2' do
127
+ v = validate(invalid_complex_hash, validations)
128
+ v.valid?.should be_false
129
+ v.errors.should eq({ bar: 'should be string' })
130
+ end
131
+ end
132
+
133
+ describe 'nested validations' do
134
+ let(:validations) {{ foo: 'numeric', bar: 'string', user: { first_name: 'string', age: 'numeric', likes: 'array' } }}
135
+
136
+ it 'should validate a complex hash' do
137
+ v = validate(complex_hash, validations)
138
+ v.valid?.should be_true
139
+ v.errors.should be_empty
140
+ end
141
+
142
+ it 'should not validate a complex hash 2' do
143
+ v = validate(invalid_complex_hash, validations)
144
+ v.valid?.should be_false
145
+ v.errors.should eq({ bar: 'should be string', user: { age: 'numeric required', likes: 'should be array' } })
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,5 @@
1
+ module HashValidatorSpecHelper
2
+ def validate(hash, validations)
3
+ HashValidator.validate(hash, validations)
4
+ end
5
+ end
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'hash_validator'
4
+ require 'hash_validator_spec_helper'
5
+
6
+ RSpec.configure do |config|
7
+ config.treat_symbols_as_metadata_keys_with_true_values = true
8
+ config.run_all_when_everything_filtered = true
9
+ config.filter_run :focus
10
+
11
+ config.order = 'random'
12
+
13
+ config.include HashValidatorSpecHelper
14
+ end
metadata ADDED
@@ -0,0 +1,107 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hash_validator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - James Brooks
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-12 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
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: 2.13.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.13.0
55
+ description: Ruby library to validate hashes (Hash) against user-defined requirements
56
+ email:
57
+ - james@gooddogdesign.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - .rspec
64
+ - .travis.yml
65
+ - Gemfile
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - hash_validator.gemspec
70
+ - lib/hash_validator.rb
71
+ - lib/hash_validator/base.rb
72
+ - lib/hash_validator/validators.rb
73
+ - lib/hash_validator/validators/base.rb
74
+ - lib/hash_validator/validators/hash_validator.rb
75
+ - lib/hash_validator/validators/simple_type_validator.rb
76
+ - lib/hash_validator/version.rb
77
+ - spec/hash_validator_spec.rb
78
+ - spec/hash_validator_spec_helper.rb
79
+ - spec/spec_helper.rb
80
+ homepage: https://github.com/JamesBrooks/hash_validator
81
+ licenses:
82
+ - MIT
83
+ metadata: {}
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ requirements: []
99
+ rubyforge_project:
100
+ rubygems_version: 2.0.0
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Ruby library to validate hashes (Hash) against user-defined requirements
104
+ test_files:
105
+ - spec/hash_validator_spec.rb
106
+ - spec/hash_validator_spec_helper.rb
107
+ - spec/spec_helper.rb