smart_core 0.0.0 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -2
- data/.rspec +1 -1
- data/.rubocop.yml +15 -0
- data/.travis.yml +14 -3
- data/CHANGELOG.md +6 -0
- data/Gemfile +4 -2
- data/LICENSE.txt +1 -1
- data/README.md +9 -40
- data/Rakefile +16 -4
- data/bin/console +5 -11
- data/lib/smart_core/validator/attribute.rb +45 -0
- data/lib/smart_core/validator/attribute_set.rb +75 -0
- data/lib/smart_core/validator/command_set.rb +68 -0
- data/lib/smart_core/validator/commands/add_nested_validations.rb +48 -0
- data/lib/smart_core/validator/commands/add_validation.rb +32 -0
- data/lib/smart_core/validator/commands/base.rb +12 -0
- data/lib/smart_core/validator/commands/validate_with.rb +48 -0
- data/lib/smart_core/validator/commands/work_with_nesteds_mixin.rb +42 -0
- data/lib/smart_core/validator/commands.rb +9 -0
- data/lib/smart_core/validator/dsl.rb +95 -0
- data/lib/smart_core/validator/error_set.rb +94 -0
- data/lib/smart_core/validator/exceptions.rb +15 -0
- data/lib/smart_core/validator/invoker.rb +75 -0
- data/lib/smart_core/validator.rb +125 -0
- data/lib/smart_core/version.rb +7 -1
- data/lib/smart_core.rb +5 -2
- data/smart_core.gemspec +24 -19
- metadata +86 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 386622ee9696b78aaf7e86cfcc5eaa6e11591bab6607a355d85b9fbfa90d513a
|
4
|
+
data.tar.gz: 9a905a991a12f36dc775076afa4f9069c099c33351e1d19911be4087789f8858
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1d7d6a650e4b4656e932883da4669b3eb2659a1b32e68d70db5eaf48f6d37edd8470ac2400ab3822df60a475ebd669c761899ed08d4613282ef8738be22eda5f
|
7
|
+
data.tar.gz: 648eb736394268e455e478431df012b7658cb434e8fc5ab506fe16f3f81a005fd7fa3fa1c1d1777a0395cd8899490ffc1a47c1f3e05314cf5a1aca078c4662b1
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
inherit_gem:
|
2
|
+
armitage-rubocop:
|
3
|
+
- lib/rubocop.general.yml
|
4
|
+
- lib/rubocop.rspec.yml
|
5
|
+
|
6
|
+
AllCops:
|
7
|
+
UseCache: true
|
8
|
+
TargetRubyVersion: 2.6.0
|
9
|
+
Include:
|
10
|
+
- bin/console
|
11
|
+
- lib/**/*.rb
|
12
|
+
- spec/**/*.rb
|
13
|
+
- Gemfile
|
14
|
+
- Rakefile
|
15
|
+
- smart_core.gemspec
|
data/.travis.yml
CHANGED
@@ -1,5 +1,16 @@
|
|
1
|
-
sudo: false
|
2
1
|
language: ruby
|
2
|
+
sudo: false
|
3
|
+
before_install: gem install bundler
|
4
|
+
cache: bundler
|
3
5
|
rvm:
|
4
|
-
|
5
|
-
|
6
|
+
- 2.3.8
|
7
|
+
- 2.4.5
|
8
|
+
- 2.5.3
|
9
|
+
- 2.6.0
|
10
|
+
- ruby-head
|
11
|
+
- jruby-head
|
12
|
+
script:
|
13
|
+
- bundle exec rspec
|
14
|
+
notifications:
|
15
|
+
slack:
|
16
|
+
secure: CUM3xnSJvn/y6Z+epQrO5uSk1EUuP4S+ugcS+48nlWD6eEzhYZwcBAK9tvD6kYGOPzoWyKSbW6Is1kzSunNr6f8ICc8HtrVHzoHE8UCzwZ7FpjgD0JgMgC4+xLLBO6lV0Hc7dNh4KLAhy4Zvbr09DPjcG8UW9/QgUdn+wBf9LHMgA+2SpBPEzMwz6pMbWW/+kkoCz2KU877kEfuFFGfvoOEFWTxUUhuCYi5a1SmTjm9A7CFTEWNkX8yHJwdgVgONjvm9lnhTeV0DvMeEOhk8Kx/hzQ2OGIicXZXWyZFkzNzpQm5xE12Hs4rY7mGPbo3bsYRDH9Ys6yf4fpNf0oZ/1agzl/gnDzacA2wL2b+eq1uZblE/fdwrNp+GIH0R+Ec2rsVKM7kh71sA6Xp1pzFb2DnHj5O4QFaPMsLyIZqD0BkVt4pNfwi4ZUB56sWkYeRQGm8x2Beh02IyFfxI65lY5kZrW6GjXx5eFeOHcmzQzeADWLSBf4iw01G/A/QqwZzlZ3fm0fRJi8BKDh3Jj0IrGndE9Bl+E7uOClKKngTPxOVLOLo/vY5mfI8M94f99kr0J45XkoAdc0SQfi3hDa/tHaakI5GJsmByjgOQwV7OU/2wzJoXAg/RPYjsYcwnTgzm9bLXPhQzfM8rUS5vLTOWIW+N0QKmWml7eWVtiedcwXA=
|
data/CHANGELOG.md
ADDED
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in smart_core.gemspec
|
6
8
|
gemspec
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,43 +1,12 @@
|
|
1
|
-
# SmartCore
|
1
|
+
# SmartCore · [![Build Status](https://travis-ci.org/0exp/smart_core.svg?branch=master)](https://travis-ci.org/0exp/smart_core) [![Coverage Status](https://coveralls.io/repos/github/0exp/smart_core/badge.svg?branch=master)](https://coveralls.io/github/0exp/smart_core?branch=master)
|
2
2
|
|
3
|
-
|
3
|
+
In active development.
|
4
4
|
|
5
|
-
|
5
|
+
#### Completed abstractions:
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install smart_core
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
TODO: Write usage instructions here
|
26
|
-
|
27
|
-
## Development
|
28
|
-
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
|
-
## Contributing
|
34
|
-
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/smart_core. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
|
-
|
37
|
-
## License
|
38
|
-
|
39
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
40
|
-
|
41
|
-
## Code of Conduct
|
42
|
-
|
43
|
-
Everyone interacting in the SmartCore project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/smart_core/blob/master/CODE_OF_CONDUCT.md).
|
7
|
+
- **Validation object** (`SmartCore::Validator`)
|
8
|
+
- support for nested validations;
|
9
|
+
- inheritance works as expected `:)`;
|
10
|
+
- command-style DSL;
|
11
|
+
- thread-safe;
|
12
|
+
- no dependencies;
|
data/Rakefile
CHANGED
@@ -1,6 +1,18 @@
|
|
1
|
-
|
2
|
-
require "rspec/core/rake_task"
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'rubocop'
|
6
|
+
require 'rubocop-rspec'
|
7
|
+
require 'rubocop/rake_task'
|
5
8
|
|
6
|
-
|
9
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
10
|
+
config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
|
11
|
+
|
12
|
+
t.options = ['--config', config_path]
|
13
|
+
t.requires << 'rubocop-rspec'
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec::Core::RakeTask.new(:rspec)
|
17
|
+
|
18
|
+
task default: :rspec
|
data/bin/console
CHANGED
@@ -1,14 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'smart_core'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
-
# require "pry"
|
11
|
-
# Pry.start
|
12
|
-
|
13
|
-
require "irb"
|
14
|
-
IRB.start(__FILE__)
|
7
|
+
require 'pry'
|
8
|
+
Pry.start
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Validator::Attribute
|
6
|
+
# @return [Symbol]
|
7
|
+
#
|
8
|
+
# @api private
|
9
|
+
# @since 0.1.0
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @param name [String, Symbol]
|
13
|
+
# @param default_value [Proc, Object]
|
14
|
+
# @return [void]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.1.0
|
18
|
+
def initialize(name, default_value = nil)
|
19
|
+
unless name.is_a?(Symbol) || name.is_a?(String)
|
20
|
+
raise(
|
21
|
+
SmartCore::Validator::IncorrectAttributeNameError,
|
22
|
+
'Attribute name should be a symbol or a string'
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
@name = name.to_sym
|
27
|
+
@default_value = default_value
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Any]
|
31
|
+
#
|
32
|
+
# @api private
|
33
|
+
# @since 0.1.0
|
34
|
+
def default_value
|
35
|
+
@default_value.is_a?(Proc) ? @default_value.call : @default_value
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [SmartCore::Validator::Attribute]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def dup
|
43
|
+
self.class.new(name, @default_value)
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Validator::AttributeSet
|
6
|
+
# @since 0.1.0
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# @return [Hash<Symbol, SmartCore::Validator::Attribute>]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
attr_reader :attributes
|
14
|
+
|
15
|
+
# @return [void]
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
# @since 0.1.0
|
19
|
+
def initialize
|
20
|
+
@attributes = {}
|
21
|
+
@access_lock = Mutex.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param attribute [Symbiont::Validator::Attribute]
|
25
|
+
# @return [void]
|
26
|
+
#
|
27
|
+
# @api private
|
28
|
+
# @since 0.1.0
|
29
|
+
def add_attribute(attribute)
|
30
|
+
thread_safe { attributes[attribute.name] = attribute }
|
31
|
+
end
|
32
|
+
alias_method :<<, :add_attribute
|
33
|
+
|
34
|
+
# @param attribute_set [SmartCore::Validator::AttributeSet]
|
35
|
+
# @return [void]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @sinec 0.1.0
|
39
|
+
def concat(attribute_set)
|
40
|
+
thread_safe { attributes.merge!(attribute_set.dup.attributes) }
|
41
|
+
end
|
42
|
+
|
43
|
+
# @return [SmartCore::Validator::AttributeSet]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
# @since 0.1.0
|
47
|
+
def dup
|
48
|
+
thread_safe do
|
49
|
+
self.class.new.tap do |duplicate|
|
50
|
+
attributes.each_value do |attribute|
|
51
|
+
duplicate.add_attribute(attribute.dup)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Enumerable]
|
58
|
+
#
|
59
|
+
# @api private
|
60
|
+
# @since 0.1.0
|
61
|
+
def each(&block)
|
62
|
+
thread_safe { block_given? ? attributes.each_value(&block) : attributes.each_value }
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# @param block [Proc]
|
68
|
+
# @return [Any]
|
69
|
+
#
|
70
|
+
# @api private
|
71
|
+
# @since 0.1.0
|
72
|
+
def thread_safe(&block)
|
73
|
+
@access_lock.synchronize(&block)
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Validator::CommandSet
|
6
|
+
# @since 0.1.0
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
# @return [Array<SmartCore::Validator::Commands::Base>]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
attr_reader :commands
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
# @since 0.1.0
|
17
|
+
def initialize
|
18
|
+
@commands = []
|
19
|
+
@access_lock = Mutex.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param command [SmartCore::Validator::Commands::Base]
|
23
|
+
# @return [void]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @since 0.1.0
|
27
|
+
def add_command(command)
|
28
|
+
thread_safe { commands << command }
|
29
|
+
end
|
30
|
+
alias_method :<<, :add_command
|
31
|
+
|
32
|
+
# @yield [SmartCore::Validator::Commands::Base]
|
33
|
+
# @return [Enumerable]
|
34
|
+
#
|
35
|
+
# @api private
|
36
|
+
# @since 0.1.0
|
37
|
+
def each(&block)
|
38
|
+
thread_safe { block_given? ? commands.each(&block) : commands.each }
|
39
|
+
end
|
40
|
+
|
41
|
+
# @param command_set [SmartCore::Validator::CommandSet]
|
42
|
+
# @return [void]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.1.0
|
46
|
+
def concat(command_set)
|
47
|
+
thread_safe { commands.concat(command_set.commands) }
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [void]
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
# @since 0.1.0
|
54
|
+
def clear
|
55
|
+
thread_safe { commands.clear }
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
# @param block [Proc]
|
61
|
+
# @return [Any]
|
62
|
+
#
|
63
|
+
# @api private
|
64
|
+
# @since 0.1.0
|
65
|
+
def thread_safe(&block)
|
66
|
+
@access_lock.synchronize(&block)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Validator::Commands
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class AddNestedValidations < Base
|
7
|
+
# @since 0.1.0
|
8
|
+
include WorkWithNestedsMixin
|
9
|
+
|
10
|
+
# @return [Symbol, String]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
attr_reader :validating_method
|
15
|
+
|
16
|
+
# @return [Proc]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.1.0
|
20
|
+
attr_reader :nested_validations
|
21
|
+
|
22
|
+
# @param validating_method [Symbol, String]
|
23
|
+
# @param nested_validations [Proc]
|
24
|
+
# @return [void]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.1.0
|
28
|
+
def initialize(validating_method, nested_validations)
|
29
|
+
@validating_method = validating_method
|
30
|
+
@nested_validations = nested_validations
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param validator [SmartCore::Validator]
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
def call(validator)
|
39
|
+
errors = SmartCore::Validator::Invoker.call(validator, validating_method)
|
40
|
+
|
41
|
+
if errors.empty?
|
42
|
+
check_nested_validations(validator, nested_validations)
|
43
|
+
else
|
44
|
+
validator.__append_errors__(errors)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Validator::Commands
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class AddValidation < Base
|
7
|
+
# @return [Symbol, String]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
attr_reader :validating_method
|
12
|
+
|
13
|
+
# @param validating_method [String, Symbol]
|
14
|
+
# @return [void]
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
# @since 0.1.0
|
18
|
+
def initialize(validating_method)
|
19
|
+
@validating_method = validating_method
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param validator [SmartCore::Validator]
|
23
|
+
# @return [void]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @since 0.1.0
|
27
|
+
def call(validator)
|
28
|
+
errors = SmartCore::Validator::Invoker.call(validator, validating_method)
|
29
|
+
validator.__append_errors__(errors) unless errors.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Validator::Commands
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class ValidateWith < Base
|
7
|
+
# @since 0.1.0
|
8
|
+
include WorkWithNestedsMixin
|
9
|
+
|
10
|
+
# @return [Class<SmartCore::Validator>]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
attr_reader :validating_klass
|
15
|
+
|
16
|
+
# @return [Proc]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
# @since 0.1.0
|
20
|
+
attr_reader :nested_validations
|
21
|
+
|
22
|
+
# @param validating_klass [Class<SmartCore::Validator>]
|
23
|
+
# @param nested_validations [Proc]
|
24
|
+
# @return [void]
|
25
|
+
#
|
26
|
+
# @api private
|
27
|
+
# @since 0.1.0
|
28
|
+
def initialize(validating_klass, nested_validations)
|
29
|
+
@validating_klass = validating_klass
|
30
|
+
@nested_validations = nested_validations
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param validator [SmartCore::Validator]
|
34
|
+
# @return [void]
|
35
|
+
#
|
36
|
+
# @api private
|
37
|
+
# @since 0.1.0
|
38
|
+
def call(validator)
|
39
|
+
sub_validator = build_sub_validator(validator, validating_klass)
|
40
|
+
|
41
|
+
if sub_validator.valid?
|
42
|
+
check_nested_validations(validator, nested_validations)
|
43
|
+
else
|
44
|
+
validator.__append_errors__(sub_validator.__validation_errors__)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
module SmartCore::Validator::Commands::WorkWithNestedsMixin
|
6
|
+
# @param validator [SmartCore::Validator]
|
7
|
+
# @param nested_validations [Proc]
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
# @api private
|
11
|
+
# @since 0.1.0
|
12
|
+
def check_nested_validations(validator, nested_validations)
|
13
|
+
nested_validator = build_nested_validator(validator, nested_validations)
|
14
|
+
|
15
|
+
unless nested_validator.valid?
|
16
|
+
validator.__append_errors__(nested_validator.__validation_errors__)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param validator [SmartCore::Validator]
|
21
|
+
# @param nested_validations [Proc]
|
22
|
+
# @return [SmartCore::Validator]
|
23
|
+
#
|
24
|
+
# @api private
|
25
|
+
# @since 0.1.0
|
26
|
+
def build_nested_validator(validator, nested_validations)
|
27
|
+
Class.new(validator.class).tap do |klass|
|
28
|
+
klass.clear_commands
|
29
|
+
klass.instance_eval(&nested_validations)
|
30
|
+
end.new(**validator.__attributes__)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param validator [SmartCore::Validator]
|
34
|
+
# @param another_validating_klass [Class<SmartCore::Validator>]
|
35
|
+
# @return [SmartCore::Validator]
|
36
|
+
#
|
37
|
+
# @api private
|
38
|
+
# @since 0.1.0
|
39
|
+
def build_sub_validator(validator, another_validating_klass)
|
40
|
+
another_validating_klass.new(**validator.__attributes__)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SmartCore::Validator::Commands
|
4
|
+
require_relative 'commands/base'
|
5
|
+
require_relative 'commands/work_with_nesteds_mixin'
|
6
|
+
require_relative 'commands/add_validation'
|
7
|
+
require_relative 'commands/add_nested_validations'
|
8
|
+
require_relative 'commands/validate_with'
|
9
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api private
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Validator
|
6
|
+
module DSL
|
7
|
+
class << self
|
8
|
+
# @param base_klass [Class]
|
9
|
+
# @return [void]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
# @since 0.1.0
|
13
|
+
def extended(base_klass)
|
14
|
+
base_klass.instance_variable_set(:@__commands__, CommandSet.new)
|
15
|
+
base_klass.instance_variable_set(:@__attributes__, AttributeSet.new)
|
16
|
+
|
17
|
+
base_klass.singleton_class.prepend(Module.new do
|
18
|
+
def inherited(child_klass)
|
19
|
+
child_klass.instance_variable_set(:@__commands__, CommandSet.new)
|
20
|
+
child_klass.instance_variable_set(:@__attributes__, AttributeSet.new)
|
21
|
+
|
22
|
+
child_klass.commands.concat(commands)
|
23
|
+
child_klass.attributes.concat(attributes)
|
24
|
+
|
25
|
+
super(child_klass)
|
26
|
+
end
|
27
|
+
end)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @param attribute_name [String, Symbol]
|
32
|
+
# @return [void]
|
33
|
+
#
|
34
|
+
# @api private
|
35
|
+
# @since 0.1.0
|
36
|
+
def attribute(attribute_name, default: nil)
|
37
|
+
attribute = SmartCore::Validator::Attribute.new(attribute_name, default)
|
38
|
+
attributes << attribute
|
39
|
+
attr_reader attribute.name
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [SmartCore::Validator::AttributeSet]
|
43
|
+
#
|
44
|
+
# @api private
|
45
|
+
# @since 0.1.0
|
46
|
+
def attributes
|
47
|
+
@__attributes__
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [SmartCore::Validator::CommandSet]
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
# @since 0.1.0
|
54
|
+
def commands
|
55
|
+
@__commands__
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [void]
|
59
|
+
#
|
60
|
+
# @api private
|
61
|
+
# @since 0.1.0
|
62
|
+
def clear_commands
|
63
|
+
commands.clear
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param validating_method [Symbol, String]
|
67
|
+
# @param nested_validations [Proc]
|
68
|
+
# @return [void]
|
69
|
+
#
|
70
|
+
# @see SmartCore::Validator::Commands::AddValidation
|
71
|
+
# @see SmartCore::Validator::Commands::AddNestedValidations
|
72
|
+
#
|
73
|
+
# @api public
|
74
|
+
# @since 0.1.0
|
75
|
+
def validate(validating_method, &nested_validations)
|
76
|
+
if block_given?
|
77
|
+
commands << Commands::AddNestedValidations.new(validating_method, nested_validations)
|
78
|
+
else
|
79
|
+
commands << Commands::AddValidation.new(validating_method)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param validating_klass [Class<SmartCore::Validator>]
|
84
|
+
# @param nested_validations [Proc]
|
85
|
+
# @return [void]
|
86
|
+
#
|
87
|
+
# @see SmartCore::Validator::Commands::ValidateWith
|
88
|
+
#
|
89
|
+
# @api private
|
90
|
+
# @since 0.1.0
|
91
|
+
def validate_with(validating_klass, &nested_validations)
|
92
|
+
commands << Commands::ValidateWith.new(validating_klass, nested_validations)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SmartCore::Validator
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class ErrorSet
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
# @since 0.1.0
|
11
|
+
def initialize
|
12
|
+
@errors = Set.new
|
13
|
+
@access_lock = Mutex.new
|
14
|
+
end
|
15
|
+
|
16
|
+
# @param error_codes [Arrray<Symbol>]
|
17
|
+
# @return [void]
|
18
|
+
#
|
19
|
+
# @api private
|
20
|
+
# @since 0.1.0
|
21
|
+
def add_error(error_code)
|
22
|
+
thread_safe { store_error(error_code) }
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param error_set [SmartCore::Validator::ErrorSet]
|
26
|
+
# @return [void]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.1.0
|
30
|
+
def concat(error_set)
|
31
|
+
thread_safe do
|
32
|
+
error_set.codes.each do |error_code|
|
33
|
+
store_error(error_code)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# @return [Boolean]
|
39
|
+
#
|
40
|
+
# @api private
|
41
|
+
# @since 0.1.0
|
42
|
+
def empty?
|
43
|
+
thread_safe { errors.empty? }
|
44
|
+
end
|
45
|
+
|
46
|
+
# @return [void]
|
47
|
+
#
|
48
|
+
# @api private
|
49
|
+
# @since 0.1.0
|
50
|
+
def clear
|
51
|
+
thread_safe { errors.clear }
|
52
|
+
end
|
53
|
+
|
54
|
+
# @return [Array<Symbol>]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
# @since 0.1.0
|
58
|
+
def codes
|
59
|
+
thread_safe { errors.to_a }
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
# @return [Array<Symbol>]
|
65
|
+
#
|
66
|
+
# @api private
|
67
|
+
# @since 0.1.0
|
68
|
+
attr_reader :errors
|
69
|
+
|
70
|
+
# @param error_code [Symbol, String]
|
71
|
+
# @return [void]
|
72
|
+
#
|
73
|
+
# @raise [SmartCore::Validator::IncorrectErrorCodeError]
|
74
|
+
#
|
75
|
+
# @api private
|
76
|
+
# @since 0.1.0
|
77
|
+
def store_error(error_code)
|
78
|
+
unless error_code.is_a?(Symbol) || error_code.is_a?(String)
|
79
|
+
raise IncorrectErrorCodeError, 'Error code should be a symbol or a string'
|
80
|
+
end
|
81
|
+
|
82
|
+
errors << error_code.to_sym
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param block [Proc]
|
86
|
+
# @return [Any]
|
87
|
+
#
|
88
|
+
# @api private
|
89
|
+
# @since 0.1.0
|
90
|
+
def thread_safe(&block)
|
91
|
+
@access_lock.synchronize(&block)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SmartCore::Validator
|
4
|
+
# @api public
|
5
|
+
# @since 0.1.0
|
6
|
+
Error = Class.new(StandardError)
|
7
|
+
|
8
|
+
# @api public
|
9
|
+
# @since 0.1.0
|
10
|
+
IncorrectErrorCodeError = Class.new(Error)
|
11
|
+
|
12
|
+
# @api public
|
13
|
+
# @since 0.1.0
|
14
|
+
IncorrectAttributeNameError = Class.new(Error)
|
15
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class SmartCore::Validator
|
4
|
+
# @api private
|
5
|
+
# @since 0.1.0
|
6
|
+
class Invoker
|
7
|
+
class << self
|
8
|
+
# @param validator [SmartCore::Validator]
|
9
|
+
# @param validating_method [Symbol, String]
|
10
|
+
# @return [SmartCore::Validator::ErrorSet]
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
# @since 0.1.0
|
14
|
+
def call(validator, validating_method)
|
15
|
+
new(validator).call(validating_method)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [SmartCore::Validator]
|
20
|
+
#
|
21
|
+
# @api private
|
22
|
+
# @since 0.1.0k
|
23
|
+
attr_reader :validator
|
24
|
+
|
25
|
+
# @param validator [SmartCore::Validator]
|
26
|
+
# @return [void]
|
27
|
+
#
|
28
|
+
# @api private
|
29
|
+
# @since 0.1.0
|
30
|
+
def initialize(validator)
|
31
|
+
@validator = validator
|
32
|
+
@access_lock = Mutex.new
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param validating_method [String, Symbol]
|
36
|
+
# @return [SmartCore::Validator::ErrorSet]
|
37
|
+
#
|
38
|
+
# @api private
|
39
|
+
# @since 0.1.0
|
40
|
+
def call(validating_method)
|
41
|
+
thread_safe do
|
42
|
+
ErrorSet.new.tap do |outer_errors|
|
43
|
+
extended_validator(outer_errors).send(validating_method)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
# Creates new validator object cloned from the original validator object
|
51
|
+
# with the new functionality: error code interception.
|
52
|
+
#
|
53
|
+
# @param outer_errors [SmartCore::Validator::ErrorSet]
|
54
|
+
# @return [SmartCore::Validator]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
# @since 0.1.0
|
58
|
+
def extended_validator(outer_errors)
|
59
|
+
validator.dup.tap do |validator_clone|
|
60
|
+
validator_clone.define_singleton_method(:error) do |error_code|
|
61
|
+
outer_errors.add_error(error_code)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# @param block [Proc]
|
67
|
+
# @return [Any]
|
68
|
+
#
|
69
|
+
# @api private
|
70
|
+
# @since 0.1.0
|
71
|
+
def thread_safe(&block)
|
72
|
+
@access_lock.synchronize(&block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# @api public
|
4
|
+
# @since 0.1.0
|
5
|
+
class SmartCore::Validator
|
6
|
+
require_relative 'validator/exceptions'
|
7
|
+
require_relative 'validator/command_set'
|
8
|
+
require_relative 'validator/attribute'
|
9
|
+
require_relative 'validator/attribute_set'
|
10
|
+
require_relative 'validator/error_set'
|
11
|
+
require_relative 'validator/invoker'
|
12
|
+
require_relative 'validator/commands'
|
13
|
+
require_relative 'validator/dsl'
|
14
|
+
|
15
|
+
# @since 0.1.0
|
16
|
+
extend DSL
|
17
|
+
|
18
|
+
class << self
|
19
|
+
# @param argumants [Any]
|
20
|
+
# @param options [Hash<Symbol, Object>]
|
21
|
+
# @return [void]
|
22
|
+
#
|
23
|
+
# @api public
|
24
|
+
# @since 0.1.0
|
25
|
+
def new(*arguments, **options)
|
26
|
+
allocate.tap do |object|
|
27
|
+
object.instance_variable_set(:@__validation_errors__, ErrorSet.new)
|
28
|
+
object.instance_variable_set(:@__invokation_lock__, Mutex.new)
|
29
|
+
object.instance_variable_set(:@__access_lock__, Mutex.new)
|
30
|
+
|
31
|
+
attributes.each do |attribute|
|
32
|
+
attribute_name = attribute.name
|
33
|
+
|
34
|
+
attribute_value =
|
35
|
+
if options.key?(attribute_name)
|
36
|
+
options[attribute_name]
|
37
|
+
else
|
38
|
+
attribute.default_value
|
39
|
+
end
|
40
|
+
|
41
|
+
object.instance_variable_set("@#{attribute_name}", attribute_value)
|
42
|
+
end
|
43
|
+
|
44
|
+
object.send(:initialize, *arguments, **options)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# @return [SmartCore::Validator::ErrorSet]
|
50
|
+
#
|
51
|
+
# @api private
|
52
|
+
# @since 0.1.0
|
53
|
+
attr_reader :__validation_errors__
|
54
|
+
|
55
|
+
# @return [void]
|
56
|
+
#
|
57
|
+
# @api public
|
58
|
+
# @since 0.1.0
|
59
|
+
def initialize(*, **); end
|
60
|
+
|
61
|
+
# @return [Boolean]
|
62
|
+
#
|
63
|
+
# @api public
|
64
|
+
# @since 0.1.0
|
65
|
+
def valid?
|
66
|
+
__thread_safe_invokation__ do
|
67
|
+
__validation_errors__.clear
|
68
|
+
self.class.commands.each { |command| command.call(self) }
|
69
|
+
__validation_errors__.empty?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# @return [Array<Symbol>]
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
# @since 0.1.0
|
77
|
+
def errors
|
78
|
+
__thread_safe_access__ do
|
79
|
+
__validation_errors__.codes
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# @param error_set [SmartCore::Validator::ErrorSet]
|
84
|
+
# @return [void]
|
85
|
+
#
|
86
|
+
# @api private
|
87
|
+
# @since 0.1.0
|
88
|
+
def __append_errors__(error_set)
|
89
|
+
__thread_safe_access__ do
|
90
|
+
__validation_errors__.concat(error_set)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# @return [Hash<Symbol, Object>]
|
95
|
+
#
|
96
|
+
# @api private
|
97
|
+
# @since 0.1.0
|
98
|
+
def __attributes__
|
99
|
+
__thread_safe_access__ do
|
100
|
+
self.class.attributes.each_with_object({}) do |attribute, accumulator|
|
101
|
+
accumulator[attribute.name] = instance_variable_get("@#{attribute.name}")
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
# @param block [Proc]
|
109
|
+
# @return [Any]
|
110
|
+
#
|
111
|
+
# @api private
|
112
|
+
# @since 0.1.0
|
113
|
+
def __thread_safe_invokation__(&block)
|
114
|
+
@__invokation_lock__.synchronize(&block)
|
115
|
+
end
|
116
|
+
|
117
|
+
# @param block [Proc]
|
118
|
+
# @return [Any]
|
119
|
+
#
|
120
|
+
# @api private
|
121
|
+
# @since 0.1.0
|
122
|
+
def __thread_safe_access__(&block)
|
123
|
+
@__access_lock__.synchronize(&block)
|
124
|
+
end
|
125
|
+
end
|
data/lib/smart_core/version.rb
CHANGED
data/lib/smart_core.rb
CHANGED
data/smart_core.gemspec
CHANGED
@@ -1,29 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'smart_core/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.
|
8
|
+
spec.required_ruby_version = '>= 2.3.8'
|
9
|
+
|
10
|
+
spec.name = 'smart_core'
|
8
11
|
spec.version = SmartCore::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
12
|
+
spec.authors = ['Rustam Ibragimov']
|
13
|
+
spec.email = ['iamdaiver@icloud.com']
|
14
|
+
spec.summary = '(in active development) A set of common abstractions'
|
15
|
+
spec.description = '(in active development) A set of common abstractions'
|
16
|
+
spec.homepage = 'https://github.com/0exp/smart_core'
|
17
|
+
spec.license = 'MIT'
|
11
18
|
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
spec.license = "MIT"
|
19
|
+
spec.bindir = 'bin'
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ['lib']
|
16
22
|
|
17
|
-
|
18
|
-
|
19
|
-
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
20
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
23
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features)/}) }
|
21
25
|
end
|
22
|
-
spec.bindir = "exe"
|
23
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
-
spec.require_paths = ["lib"]
|
25
26
|
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
28
|
-
spec.add_development_dependency
|
27
|
+
spec.add_development_dependency 'coveralls', '~> 0.8.22'
|
28
|
+
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
29
|
+
spec.add_development_dependency 'armitage-rubocop', '~> 0.16.0'
|
30
|
+
spec.add_development_dependency 'rspec', '~> 3.8.0'
|
31
|
+
spec.add_development_dependency 'bundler', '~> 1.17'
|
32
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
33
|
+
spec.add_development_dependency 'pry', '~> 0.12'
|
29
34
|
end
|
metadata
CHANGED
@@ -1,58 +1,114 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rustam Ibragimov
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: coveralls
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.8.22
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.8.22
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: simplecov
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.16.1
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.16.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: armitage-rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.16.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.16.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.8.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.8.0
|
13
69
|
- !ruby/object:Gem::Dependency
|
14
70
|
name: bundler
|
15
71
|
requirement: !ruby/object:Gem::Requirement
|
16
72
|
requirements:
|
17
73
|
- - "~>"
|
18
74
|
- !ruby/object:Gem::Version
|
19
|
-
version: '1.
|
75
|
+
version: '1.17'
|
20
76
|
type: :development
|
21
77
|
prerelease: false
|
22
78
|
version_requirements: !ruby/object:Gem::Requirement
|
23
79
|
requirements:
|
24
80
|
- - "~>"
|
25
81
|
- !ruby/object:Gem::Version
|
26
|
-
version: '1.
|
82
|
+
version: '1.17'
|
27
83
|
- !ruby/object:Gem::Dependency
|
28
84
|
name: rake
|
29
85
|
requirement: !ruby/object:Gem::Requirement
|
30
86
|
requirements:
|
31
87
|
- - "~>"
|
32
88
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
89
|
+
version: '12.3'
|
34
90
|
type: :development
|
35
91
|
prerelease: false
|
36
92
|
version_requirements: !ruby/object:Gem::Requirement
|
37
93
|
requirements:
|
38
94
|
- - "~>"
|
39
95
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
96
|
+
version: '12.3'
|
41
97
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
98
|
+
name: pry
|
43
99
|
requirement: !ruby/object:Gem::Requirement
|
44
100
|
requirements:
|
45
101
|
- - "~>"
|
46
102
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
103
|
+
version: '0.12'
|
48
104
|
type: :development
|
49
105
|
prerelease: false
|
50
106
|
version_requirements: !ruby/object:Gem::Requirement
|
51
107
|
requirements:
|
52
108
|
- - "~>"
|
53
109
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
55
|
-
description:
|
110
|
+
version: '0.12'
|
111
|
+
description: "(in active development) A set of common abstractions"
|
56
112
|
email:
|
57
113
|
- iamdaiver@icloud.com
|
58
114
|
executables: []
|
@@ -61,7 +117,9 @@ extra_rdoc_files: []
|
|
61
117
|
files:
|
62
118
|
- ".gitignore"
|
63
119
|
- ".rspec"
|
120
|
+
- ".rubocop.yml"
|
64
121
|
- ".travis.yml"
|
122
|
+
- CHANGELOG.md
|
65
123
|
- CODE_OF_CONDUCT.md
|
66
124
|
- Gemfile
|
67
125
|
- LICENSE.txt
|
@@ -70,6 +128,20 @@ files:
|
|
70
128
|
- bin/console
|
71
129
|
- bin/setup
|
72
130
|
- lib/smart_core.rb
|
131
|
+
- lib/smart_core/validator.rb
|
132
|
+
- lib/smart_core/validator/attribute.rb
|
133
|
+
- lib/smart_core/validator/attribute_set.rb
|
134
|
+
- lib/smart_core/validator/command_set.rb
|
135
|
+
- lib/smart_core/validator/commands.rb
|
136
|
+
- lib/smart_core/validator/commands/add_nested_validations.rb
|
137
|
+
- lib/smart_core/validator/commands/add_validation.rb
|
138
|
+
- lib/smart_core/validator/commands/base.rb
|
139
|
+
- lib/smart_core/validator/commands/validate_with.rb
|
140
|
+
- lib/smart_core/validator/commands/work_with_nesteds_mixin.rb
|
141
|
+
- lib/smart_core/validator/dsl.rb
|
142
|
+
- lib/smart_core/validator/error_set.rb
|
143
|
+
- lib/smart_core/validator/exceptions.rb
|
144
|
+
- lib/smart_core/validator/invoker.rb
|
73
145
|
- lib/smart_core/version.rb
|
74
146
|
- smart_core.gemspec
|
75
147
|
homepage: https://github.com/0exp/smart_core
|
@@ -84,16 +156,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
156
|
requirements:
|
85
157
|
- - ">="
|
86
158
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
159
|
+
version: 2.3.8
|
88
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
161
|
requirements:
|
90
162
|
- - ">="
|
91
163
|
- !ruby/object:Gem::Version
|
92
164
|
version: '0'
|
93
165
|
requirements: []
|
94
|
-
|
95
|
-
rubygems_version: 2.7.6
|
166
|
+
rubygems_version: 3.0.1
|
96
167
|
signing_key:
|
97
168
|
specification_version: 4
|
98
|
-
summary:
|
169
|
+
summary: "(in active development) A set of common abstractions"
|
99
170
|
test_files: []
|