smart_validator 0.4.0
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/.github/workflows/test.yml +39 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +32 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +158 -0
- data/LICENSE.txt +21 -0
- data/README.md +47 -0
- data/Rakefile +21 -0
- data/bin/console +8 -0
- data/bin/setup +8 -0
- data/lib/smart_core/validator/class_state/container.rb +53 -0
- data/lib/smart_core/validator/class_state/initialize_mixin.rb +25 -0
- data/lib/smart_core/validator/class_state.rb +6 -0
- data/lib/smart_core/validator/contract.rb +78 -0
- data/lib/smart_core/validator/errors.rb +41 -0
- data/lib/smart_core/validator/errors_controller/base.rb +28 -0
- data/lib/smart_core/validator/errors_controller/error_per_attribute.rb +15 -0
- data/lib/smart_core/validator/errors_controller/many_errors_per_attribute.rb +15 -0
- data/lib/smart_core/validator/errors_controller.rb +23 -0
- data/lib/smart_core/validator/result.rb +36 -0
- data/lib/smart_core/validator/rule.rb +25 -0
- data/lib/smart_core/validator/rule_execition_context/failure.rb +10 -0
- data/lib/smart_core/validator/rule_execition_context/result.rb +3 -0
- data/lib/smart_core/validator/rule_execution_context.rb +38 -0
- data/lib/smart_core/validator/utils.rb +13 -0
- data/lib/smart_core/validator/version.rb +7 -0
- data/lib/smart_core/validator.rb +22 -0
- data/smart_validator.gemspec +45 -0
- metadata +231 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 69d6afe21ce43c069bc1b567d47ae1b844182c6fac2d83017613274a3787018e
|
|
4
|
+
data.tar.gz: f349084e071c1edaed03fae856c8799f053144c7a79e65cb07a5252ed644b51b
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b3d3660286a1991c372dfc98f95c37fa10fc531ebd6ed24aa6083c8c776376a86f329d6104eb55bd0935a445da7b244c4b9b157eedca84f6eba570a11487bd55
|
|
7
|
+
data.tar.gz: 70f2a6e985189aa11bfb932b8026edd4932126fcca922cd95c8643dea661698e4462fc8d3bdcd4b9df778facced655e4d34b90522661e3a38db2c969f7da32b2
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Build
|
|
2
|
+
on: [push, pull_request]
|
|
3
|
+
env:
|
|
4
|
+
FULL_COVERAGE_CHECK: true
|
|
5
|
+
jobs:
|
|
6
|
+
full-check:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
steps:
|
|
9
|
+
- uses: actions/checkout@v2
|
|
10
|
+
- uses: ruby/setup-ruby@v1
|
|
11
|
+
with:
|
|
12
|
+
ruby-version: 3
|
|
13
|
+
bundler-cache: true
|
|
14
|
+
- name: Run Linter
|
|
15
|
+
run: bundle exec ci-helper RubocopLint
|
|
16
|
+
- name: Check missed spec suffixes
|
|
17
|
+
run: bundle exec ci-helper CheckSpecSuffixes --extra-paths spec/*.rb --ignored-paths spec/*_helper.rb
|
|
18
|
+
- name: Run specs
|
|
19
|
+
run: bundle exec ci-helper RunSpecs
|
|
20
|
+
- name: Audit
|
|
21
|
+
run: bundle exec ci-helper BundlerAudit
|
|
22
|
+
- name: Coveralls
|
|
23
|
+
uses: coverallsapp/github-action@master
|
|
24
|
+
with:
|
|
25
|
+
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
26
|
+
specs:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
ruby: [3.0, 3.1, 3.2]
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v2
|
|
34
|
+
- uses: ruby/setup-ruby@v1
|
|
35
|
+
with:
|
|
36
|
+
ruby-version: ${{ matrix.ruby }}
|
|
37
|
+
bundler-cache: true
|
|
38
|
+
- name: Run specs
|
|
39
|
+
run: bundle exec rspec
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
inherit_gem:
|
|
2
|
+
armitage-rubocop:
|
|
3
|
+
- lib/rubocop.general.yml
|
|
4
|
+
- lib/rubocop.rake.yml
|
|
5
|
+
- lib/rubocop.rspec.yml
|
|
6
|
+
|
|
7
|
+
AllCops:
|
|
8
|
+
TargetRubyVersion: 3.0
|
|
9
|
+
NewCops: enable
|
|
10
|
+
Include:
|
|
11
|
+
- lib/**/*.rb
|
|
12
|
+
- spec/**/*.rb
|
|
13
|
+
- Gemfile
|
|
14
|
+
- Rakefile
|
|
15
|
+
- smart_validator.gemspec
|
|
16
|
+
- bin/console
|
|
17
|
+
DisplayCopNames: true
|
|
18
|
+
SuggestExtensions: false
|
|
19
|
+
|
|
20
|
+
Naming/MethodParameterName:
|
|
21
|
+
AllowedNames: ["x", "y", "z"]
|
|
22
|
+
|
|
23
|
+
Style/HashConversion:
|
|
24
|
+
Exclude:
|
|
25
|
+
- spec/**/*_spec.rb
|
|
26
|
+
|
|
27
|
+
Naming/RescuedExceptionsVariableName:
|
|
28
|
+
Enabled: false
|
|
29
|
+
|
|
30
|
+
Naming/FileName:
|
|
31
|
+
Exclude:
|
|
32
|
+
- lib/smart-validator.rb
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
smart_validator (0.4.0)
|
|
5
|
+
qonfig (~> 0.28)
|
|
6
|
+
smart_initializer (~> 0.11)
|
|
7
|
+
smart_schema (~> 0.11)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
activesupport (7.1.3.2)
|
|
13
|
+
base64
|
|
14
|
+
bigdecimal
|
|
15
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
16
|
+
connection_pool (>= 2.2.5)
|
|
17
|
+
drb
|
|
18
|
+
i18n (>= 1.6, < 2)
|
|
19
|
+
minitest (>= 5.1)
|
|
20
|
+
mutex_m
|
|
21
|
+
tzinfo (~> 2.0)
|
|
22
|
+
armitage-rubocop (1.59.0)
|
|
23
|
+
rubocop (= 1.59.0)
|
|
24
|
+
rubocop-capybara (= 2.19.0)
|
|
25
|
+
rubocop-factory_bot (= 2.24.0)
|
|
26
|
+
rubocop-performance (= 1.20.1)
|
|
27
|
+
rubocop-rails (= 2.23.1)
|
|
28
|
+
rubocop-rake (= 0.6.0)
|
|
29
|
+
rubocop-rspec (= 2.25.0)
|
|
30
|
+
ast (2.4.2)
|
|
31
|
+
base64 (0.2.0)
|
|
32
|
+
bigdecimal (3.1.7)
|
|
33
|
+
bundler-audit (0.9.1)
|
|
34
|
+
bundler (>= 1.2.0, < 3)
|
|
35
|
+
thor (~> 1.0)
|
|
36
|
+
ci-helper (0.6.0)
|
|
37
|
+
colorize (~> 1.1)
|
|
38
|
+
dry-inflector (~> 1.0)
|
|
39
|
+
umbrellio-sequel-plugins (~> 0.14)
|
|
40
|
+
coderay (1.1.3)
|
|
41
|
+
colorize (1.1.0)
|
|
42
|
+
concurrent-ruby (1.2.3)
|
|
43
|
+
connection_pool (2.4.1)
|
|
44
|
+
diff-lcs (1.5.1)
|
|
45
|
+
docile (1.4.0)
|
|
46
|
+
drb (2.2.1)
|
|
47
|
+
dry-inflector (1.0.0)
|
|
48
|
+
i18n (1.14.4)
|
|
49
|
+
concurrent-ruby (~> 1.0)
|
|
50
|
+
json (2.7.1)
|
|
51
|
+
language_server-protocol (3.17.0.3)
|
|
52
|
+
method_source (1.0.0)
|
|
53
|
+
minitest (5.22.3)
|
|
54
|
+
mutex_m (0.2.0)
|
|
55
|
+
parallel (1.24.0)
|
|
56
|
+
parser (3.3.0.5)
|
|
57
|
+
ast (~> 2.4.1)
|
|
58
|
+
racc
|
|
59
|
+
pry (0.14.2)
|
|
60
|
+
coderay (~> 1.1)
|
|
61
|
+
method_source (~> 1.0)
|
|
62
|
+
qonfig (0.28.0)
|
|
63
|
+
racc (1.7.3)
|
|
64
|
+
rack (3.0.9.1)
|
|
65
|
+
rainbow (3.1.1)
|
|
66
|
+
rake (13.1.0)
|
|
67
|
+
regexp_parser (2.9.0)
|
|
68
|
+
rexml (3.2.6)
|
|
69
|
+
rspec (3.13.0)
|
|
70
|
+
rspec-core (~> 3.13.0)
|
|
71
|
+
rspec-expectations (~> 3.13.0)
|
|
72
|
+
rspec-mocks (~> 3.13.0)
|
|
73
|
+
rspec-core (3.13.0)
|
|
74
|
+
rspec-support (~> 3.13.0)
|
|
75
|
+
rspec-expectations (3.13.0)
|
|
76
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
77
|
+
rspec-support (~> 3.13.0)
|
|
78
|
+
rspec-mocks (3.13.0)
|
|
79
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
|
80
|
+
rspec-support (~> 3.13.0)
|
|
81
|
+
rspec-support (3.13.1)
|
|
82
|
+
rubocop (1.59.0)
|
|
83
|
+
json (~> 2.3)
|
|
84
|
+
language_server-protocol (>= 3.17.0)
|
|
85
|
+
parallel (~> 1.10)
|
|
86
|
+
parser (>= 3.2.2.4)
|
|
87
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
88
|
+
regexp_parser (>= 1.8, < 3.0)
|
|
89
|
+
rexml (>= 3.2.5, < 4.0)
|
|
90
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
91
|
+
ruby-progressbar (~> 1.7)
|
|
92
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
|
93
|
+
rubocop-ast (1.31.2)
|
|
94
|
+
parser (>= 3.3.0.4)
|
|
95
|
+
rubocop-capybara (2.19.0)
|
|
96
|
+
rubocop (~> 1.41)
|
|
97
|
+
rubocop-factory_bot (2.24.0)
|
|
98
|
+
rubocop (~> 1.33)
|
|
99
|
+
rubocop-performance (1.20.1)
|
|
100
|
+
rubocop (>= 1.48.1, < 2.0)
|
|
101
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
102
|
+
rubocop-rails (2.23.1)
|
|
103
|
+
activesupport (>= 4.2.0)
|
|
104
|
+
rack (>= 1.1)
|
|
105
|
+
rubocop (>= 1.33.0, < 2.0)
|
|
106
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
107
|
+
rubocop-rake (0.6.0)
|
|
108
|
+
rubocop (~> 1.0)
|
|
109
|
+
rubocop-rspec (2.25.0)
|
|
110
|
+
rubocop (~> 1.40)
|
|
111
|
+
rubocop-capybara (~> 2.17)
|
|
112
|
+
rubocop-factory_bot (~> 2.22)
|
|
113
|
+
ruby-progressbar (1.13.0)
|
|
114
|
+
sequel (5.78.0)
|
|
115
|
+
bigdecimal
|
|
116
|
+
simplecov (0.22.0)
|
|
117
|
+
docile (~> 1.1)
|
|
118
|
+
simplecov-html (~> 0.11)
|
|
119
|
+
simplecov_json_formatter (~> 0.1)
|
|
120
|
+
simplecov-html (0.12.3)
|
|
121
|
+
simplecov-lcov (0.8.0)
|
|
122
|
+
simplecov_json_formatter (0.1.4)
|
|
123
|
+
smart_engine (0.17.0)
|
|
124
|
+
smart_initializer (0.11.1)
|
|
125
|
+
qonfig (~> 0.24)
|
|
126
|
+
smart_engine (~> 0.16)
|
|
127
|
+
smart_types (~> 0.8)
|
|
128
|
+
smart_schema (0.11.0)
|
|
129
|
+
smart_engine (~> 0.17)
|
|
130
|
+
smart_types (~> 0.8)
|
|
131
|
+
smart_types (0.8.0)
|
|
132
|
+
smart_engine (~> 0.11)
|
|
133
|
+
symbiont-ruby (0.7.0)
|
|
134
|
+
thor (1.3.1)
|
|
135
|
+
tzinfo (2.0.6)
|
|
136
|
+
concurrent-ruby (~> 1.0)
|
|
137
|
+
umbrellio-sequel-plugins (0.14.0.192)
|
|
138
|
+
sequel
|
|
139
|
+
symbiont-ruby
|
|
140
|
+
unicode-display_width (2.5.0)
|
|
141
|
+
|
|
142
|
+
PLATFORMS
|
|
143
|
+
arm64-darwin-23
|
|
144
|
+
ruby
|
|
145
|
+
|
|
146
|
+
DEPENDENCIES
|
|
147
|
+
armitage-rubocop (~> 1.59)
|
|
148
|
+
bundler-audit (~> 0.9)
|
|
149
|
+
ci-helper (~> 0.6)
|
|
150
|
+
pry (~> 0.14)
|
|
151
|
+
rake (~> 13.1)
|
|
152
|
+
rspec (~> 3.13)
|
|
153
|
+
simplecov (~> 0.22)
|
|
154
|
+
simplecov-lcov (~> 0.8)
|
|
155
|
+
smart_validator!
|
|
156
|
+
|
|
157
|
+
BUNDLED WITH
|
|
158
|
+
2.5.3
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 AnotherRegularDude (https://github.com/AnotherRegularDude)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# SmartCore::Validator
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
<img src="https://github.com/Cado-Labs/cado-labs-resources/blob/main/cado_labs_supporting_rounded.svg" alt="Supported by Cado Labs" />
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem 'smart_validator'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```shell
|
|
16
|
+
bundle install
|
|
17
|
+
# --- or ---
|
|
18
|
+
gem install smart_validator
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
require 'smart_core/validator'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
- soon (you can check specs for usage examples at this moment)
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Contributing
|
|
34
|
+
|
|
35
|
+
- Fork it ( https://github.com/smart-rb/smart_validator )
|
|
36
|
+
- Create your feature branch (`git checkout -b feature/my-new-feature`)
|
|
37
|
+
- Commit your changes (`git commit -am '[feature_context] Add some feature'`)
|
|
38
|
+
- Push to the branch (`git push origin feature/my-new-feature`)
|
|
39
|
+
- Create new Pull Request
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
Released under MIT License.
|
|
44
|
+
|
|
45
|
+
## Authors
|
|
46
|
+
|
|
47
|
+
[AnotherRegularDude] (https://github.com/AnotherRegularDude)
|
data/Rakefile
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/gem_tasks'
|
|
4
|
+
require 'rspec/core/rake_task'
|
|
5
|
+
require 'rubocop'
|
|
6
|
+
require 'rubocop/rake_task'
|
|
7
|
+
require 'rubocop-performance'
|
|
8
|
+
require 'rubocop-rspec'
|
|
9
|
+
require 'rubocop-rake'
|
|
10
|
+
|
|
11
|
+
RuboCop::RakeTask.new(:rubocop) do |t|
|
|
12
|
+
config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
|
|
13
|
+
t.options = ['--config', config_path]
|
|
14
|
+
t.requires << 'rubocop-rspec'
|
|
15
|
+
t.requires << 'rubocop-performance'
|
|
16
|
+
t.requires << 'rubocop-rake'
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
RSpec::Core::RakeTask.new(:rspec)
|
|
20
|
+
|
|
21
|
+
task default: :rspec
|
data/bin/console
ADDED
data/bin/setup
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::ClassState::Container
|
|
4
|
+
attr_accessor :schema_class
|
|
5
|
+
attr_accessor :configuration
|
|
6
|
+
attr_accessor :rules
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def new(*args)
|
|
10
|
+
super.freeze
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_base_container
|
|
14
|
+
new(build_base_config)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# TODO: Use global config until #configure is called on the class.
|
|
20
|
+
def build_base_config
|
|
21
|
+
config = Qonfig::DataSet.build do
|
|
22
|
+
setting :errors_managing_type, :error_per_attribute
|
|
23
|
+
setting :smart_initializer do
|
|
24
|
+
# TODO: After calling configure method,
|
|
25
|
+
# also apply changes to the #__settings__ of the Contract class.
|
|
26
|
+
compose SmartCore::Initializer::Configuration.config.class
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
validate :errors_managing_type do |value|
|
|
30
|
+
SmartCore::Validator::ErrorsController::ALLOWED_MANAGING_TYPES.key?(value)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
config.tap(&:freeze!)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def initialize(duplicated_configuration)
|
|
39
|
+
self.schema_class = Class.new(SmartCore::Schema)
|
|
40
|
+
self.configuration = duplicated_configuration
|
|
41
|
+
self.rules = []
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def initialize_copy(parent_container)
|
|
47
|
+
super
|
|
48
|
+
self.schema_class = Class.new(SmartCore::Schema)
|
|
49
|
+
self.rules = []
|
|
50
|
+
self.configuration = parent_container.configuration.dup
|
|
51
|
+
freeze
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator::ClassState
|
|
4
|
+
module InitializeMixin
|
|
5
|
+
def self.included(mod)
|
|
6
|
+
super
|
|
7
|
+
|
|
8
|
+
mod.singleton_class.attr_accessor :__state_container__
|
|
9
|
+
mod.singleton_class.send(:protected, :__state_container__=)
|
|
10
|
+
mod.instance_variable_set(:@__state_container__, Container.create_base_container)
|
|
11
|
+
add_delegators_to(mod)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.add_delegators_to(mod)
|
|
15
|
+
mod.instance_eval do
|
|
16
|
+
extend Forwardable
|
|
17
|
+
extend SingleForwardable
|
|
18
|
+
|
|
19
|
+
def_single_delegators :__state_container__, :schema_class, :configuration, :rules
|
|
20
|
+
def_single_delegators :configuration, :configure, :settings
|
|
21
|
+
def_instance_delegators 'self.class', :settings, :rules, :schema_class
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator
|
|
4
|
+
class Contract
|
|
5
|
+
include SmartCore::Initializer
|
|
6
|
+
include ClassState::InitializeMixin
|
|
7
|
+
|
|
8
|
+
class << self
|
|
9
|
+
def inherited(subclass)
|
|
10
|
+
super
|
|
11
|
+
subclass.__state_container__ = __state_container__.dup
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def param(*)
|
|
15
|
+
raise NotImplementedError, 'params are not permitted to use in validators'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# NOTE: In Ruby 2.6.x need to initialize instance without arguments if they not expected.
|
|
19
|
+
def call(data_to_validate, **kwargs)
|
|
20
|
+
instance = kwargs.empty? ? new : new(**kwargs)
|
|
21
|
+
instance.call(data_to_validate)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def schema(&block)
|
|
25
|
+
schema_class.schema(&block)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# TODO: Delegate all this logic to the Rules.
|
|
29
|
+
def rule(checked_value, &block)
|
|
30
|
+
rules << Rule.new(checked_value, block)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def rule_for_each(*checked_values, &block)
|
|
34
|
+
checked_values.each { |checked_value| rule(checked_value, &block) }
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def call(data_to_validate)
|
|
39
|
+
self.data = Utils.deeply_symbolize_freeze(data_to_validate)
|
|
40
|
+
self.errors_controller = ErrorsController.resolve_from(settings.errors_managing_type)
|
|
41
|
+
self.rule_execution_context = build_rule_execution_context
|
|
42
|
+
|
|
43
|
+
result = build_schema_instance.validate(data)
|
|
44
|
+
errors_controller.process_smart_schema_result!(result)
|
|
45
|
+
return build_result if errors_controller.validation_fails?
|
|
46
|
+
|
|
47
|
+
check_with_rules!
|
|
48
|
+
build_result
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
attr_accessor :data
|
|
54
|
+
attr_accessor :errors_controller
|
|
55
|
+
attr_accessor :rule_execution_context
|
|
56
|
+
|
|
57
|
+
def build_rule_execution_context
|
|
58
|
+
RuleExecutionContext.new(data, __options__)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def build_schema_instance
|
|
62
|
+
schema_class.new
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def build_result
|
|
66
|
+
Result.build_from_state(data, errors_controller)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def check_with_rules!
|
|
70
|
+
rules.each do |rule|
|
|
71
|
+
next if errors_controller.error_will_be_skipped?(rule.checked_attr)
|
|
72
|
+
|
|
73
|
+
result = rule_execution_context.execute!(rule)
|
|
74
|
+
errors_controller.process_rule!(result)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::Errors
|
|
4
|
+
extend Forwardable
|
|
5
|
+
include Enumerable
|
|
6
|
+
|
|
7
|
+
def_delegators :@errors_container, :each, :as_json, :to_json
|
|
8
|
+
|
|
9
|
+
def initialize
|
|
10
|
+
self.errors_container = {}
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def safely_add!(attr_path:, error_code:)
|
|
14
|
+
errors_container[attr_path.to_s] ||= error_code
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def safely_merge!(attr_path:, errors_enum:)
|
|
18
|
+
errors_container[attr_path.to_s] ||= Set.new
|
|
19
|
+
errors_container[attr_path.to_s].merge(errors_enum)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def [](attr_path)
|
|
23
|
+
errors_container[attr_path.to_s]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def freeze
|
|
27
|
+
super.tap { errors_container.transform_values(&:freeze) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def to_h
|
|
31
|
+
errors_container.dup
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def attribute_already_exists?(attr_path)
|
|
35
|
+
errors_container.key?(attr_path.to_s)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
attr_accessor :errors_container
|
|
41
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::ErrorsController::Base
|
|
4
|
+
attr_reader :errors
|
|
5
|
+
|
|
6
|
+
def initialize
|
|
7
|
+
@errors = SmartCore::Validator::Errors.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def process_smart_schema_result!(result)
|
|
11
|
+
result.errors.each do |attr_path, error_codes|
|
|
12
|
+
apply_data_to_errors!(attr_path, *error_codes)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def process_rule!(result)
|
|
17
|
+
return if result == nil
|
|
18
|
+
|
|
19
|
+
apply_data_to_errors!(result.attr_path, result.code)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def validation_fails?
|
|
23
|
+
@validation_fails ||= errors.any?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @!method apply_data_to_errors!
|
|
27
|
+
# @!method error_will_be_skipped?
|
|
28
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator::ErrorsController
|
|
4
|
+
class ErrorPerAttribute < Base
|
|
5
|
+
def error_will_be_skipped?(attr_path)
|
|
6
|
+
errors.attribute_already_exists?(attr_path)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def apply_data_to_errors!(attr_path, *error_codes)
|
|
12
|
+
errors.safely_add!(attr_path: attr_path, error_code: error_codes.first)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator::ErrorsController
|
|
4
|
+
class ManyErrorsPerAttribute < Base
|
|
5
|
+
def error_will_be_skipped?(_attr_path)
|
|
6
|
+
false
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def apply_data_to_errors!(attr_path, *error_codes)
|
|
12
|
+
errors.safely_merge!(attr_path: attr_path, errors_enum: error_codes)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator::ErrorsController
|
|
4
|
+
require_relative 'errors_controller/base'
|
|
5
|
+
require_relative 'errors_controller/error_per_attribute'
|
|
6
|
+
require_relative 'errors_controller/many_errors_per_attribute'
|
|
7
|
+
|
|
8
|
+
extend self
|
|
9
|
+
|
|
10
|
+
ALLOWED_MANAGING_TYPES = {
|
|
11
|
+
error_per_attribute: 'ErrorPerAttribute',
|
|
12
|
+
many_errors_per_attribute: 'ManyErrorsPerAttribute'
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
def resolve_from(managing_type)
|
|
16
|
+
unless ALLOWED_MANAGING_TYPES.key?(managing_type)
|
|
17
|
+
raise ArgumentError, "invalid handling type. allowed is: #{ALLOWED_MANAGING_TYPES.keys}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
name = ALLOWED_MANAGING_TYPES[managing_type]
|
|
21
|
+
::SmartCore::Validator::ErrorsController.const_get(name).new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::Result
|
|
4
|
+
attr_accessor :errors
|
|
5
|
+
attr_accessor :data
|
|
6
|
+
attr_accessor :failed
|
|
7
|
+
|
|
8
|
+
def self.build_from_state(input_data, errors_controller)
|
|
9
|
+
res = new(
|
|
10
|
+
data: input_data,
|
|
11
|
+
errors: errors_controller.errors,
|
|
12
|
+
failed: errors_controller.validation_fails?
|
|
13
|
+
)
|
|
14
|
+
res.freeze
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize(errors:, data:, failed:)
|
|
18
|
+
self.errors = errors
|
|
19
|
+
self.data = data
|
|
20
|
+
self.failed = failed
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def success?
|
|
24
|
+
!failed
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def freeze
|
|
28
|
+
super.tap do
|
|
29
|
+
errors.freeze
|
|
30
|
+
data.freeze
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
alias_method :failed?, :failed
|
|
35
|
+
alias_method :to_h, :data
|
|
36
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::Rule
|
|
4
|
+
attr_reader :checked_attr
|
|
5
|
+
|
|
6
|
+
def initialize(checked_attr, checking_block)
|
|
7
|
+
@checked_attr = checked_attr.to_s
|
|
8
|
+
@attr_path = @checked_attr.split('.').map(&:to_sym)
|
|
9
|
+
@checking_block = checking_block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def executable?(data)
|
|
13
|
+
checked_path, checked_key = @attr_path[..-2], @attr_path.last
|
|
14
|
+
data = data.dig(*checked_path) if checked_path.any?
|
|
15
|
+
data&.key?(checked_key)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def value_from(data)
|
|
19
|
+
data.dig(*@attr_path)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def to_proc
|
|
23
|
+
@checking_block
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class SmartCore::Validator::RuleExecutionContext
|
|
4
|
+
require_relative 'rule_execition_context/failure'
|
|
5
|
+
require_relative 'rule_execition_context/result'
|
|
6
|
+
|
|
7
|
+
def initialize(data, dependencies_to_bind)
|
|
8
|
+
self.data = data
|
|
9
|
+
bind_to_self!(dependencies_to_bind)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def execute!(rule)
|
|
13
|
+
self.value = rule.value_from(data)
|
|
14
|
+
instance_eval(&rule) if rule.executable?(data)
|
|
15
|
+
nil
|
|
16
|
+
rescue Failure => e
|
|
17
|
+
Result.new(rule.checked_attr, e.code).freeze
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
attr_accessor :data
|
|
23
|
+
attr_accessor :value
|
|
24
|
+
|
|
25
|
+
def bind_to_self!(dependencies)
|
|
26
|
+
dependencies.each do |name, value|
|
|
27
|
+
if singleton_class.method_defined?(name)
|
|
28
|
+
raise ArgumentError, "dependency name conflicts with standard method: #{name}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
define_singleton_method(name) { value }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def failure(code)
|
|
36
|
+
raise Failure, code
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module SmartCore::Validator::Utils
|
|
4
|
+
extend self
|
|
5
|
+
|
|
6
|
+
def deeply_symbolize_freeze(hash)
|
|
7
|
+
hash.dup.freeze.transform_keys(&:to_sym).transform_values do |value|
|
|
8
|
+
next value.dup.freeze unless value.is_a?(Hash)
|
|
9
|
+
|
|
10
|
+
deeply_symbolize_freeze(value)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'qonfig'
|
|
4
|
+
require 'forwardable'
|
|
5
|
+
require 'smart_core/schema'
|
|
6
|
+
require 'smart_core/initializer'
|
|
7
|
+
|
|
8
|
+
module SmartCore
|
|
9
|
+
module Validator
|
|
10
|
+
ERROR_CODE_HANDLING_TYPES = %i[one many].freeze
|
|
11
|
+
|
|
12
|
+
require_relative 'validator/version'
|
|
13
|
+
require_relative 'validator/utils'
|
|
14
|
+
require_relative 'validator/errors_controller'
|
|
15
|
+
require_relative 'validator/errors'
|
|
16
|
+
require_relative 'validator/class_state'
|
|
17
|
+
require_relative 'validator/rule'
|
|
18
|
+
require_relative 'validator/rule_execution_context'
|
|
19
|
+
require_relative 'validator/result'
|
|
20
|
+
require_relative 'validator/contract'
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'lib/smart_core/validator/version'
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 3.0')
|
|
7
|
+
|
|
8
|
+
spec.name = 'smart_validator'
|
|
9
|
+
spec.version = SmartCore::Validator::VERSION
|
|
10
|
+
spec.authors = ['JustAnotherDude']
|
|
11
|
+
spec.email = ['vanyaz158@gmail.com']
|
|
12
|
+
|
|
13
|
+
spec.summary = 'Custom DSL-first validator with a conviniet declarative API.'
|
|
14
|
+
spec.description = 'Validation layer for any business logic with a declarative rule-oriented API.'
|
|
15
|
+
spec.homepage = 'https://github.com/smart-rb/smart_validator'
|
|
16
|
+
spec.license = 'MIT'
|
|
17
|
+
|
|
18
|
+
spec.metadata['homepage_uri'] =
|
|
19
|
+
spec.homepage
|
|
20
|
+
spec.metadata['source_code_uri'] =
|
|
21
|
+
'https://github.com/smart-rb/smart_validator/blob/master'
|
|
22
|
+
spec.metadata['changelog_uri'] =
|
|
23
|
+
'https://github.com/smart-rb/smart_validator/blob/master/CHANGELOG.md'
|
|
24
|
+
|
|
25
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
26
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
spec.bindir = 'exe'
|
|
30
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
31
|
+
spec.require_paths = ['lib']
|
|
32
|
+
|
|
33
|
+
spec.add_dependency 'qonfig', '~> 0.28'
|
|
34
|
+
spec.add_dependency 'smart_initializer', '~> 0.11'
|
|
35
|
+
spec.add_dependency 'smart_schema', '~> 0.11'
|
|
36
|
+
|
|
37
|
+
spec.add_development_dependency 'bundler-audit', '~> 0.9'
|
|
38
|
+
spec.add_development_dependency 'ci-helper', '~> 0.6'
|
|
39
|
+
spec.add_development_dependency 'pry', '~> 0.14'
|
|
40
|
+
spec.add_development_dependency 'rake', '~> 13.1'
|
|
41
|
+
spec.add_development_dependency 'rspec', '~> 3.13'
|
|
42
|
+
spec.add_development_dependency 'armitage-rubocop', '~> 1.59'
|
|
43
|
+
spec.add_development_dependency 'simplecov', '~> 0.22'
|
|
44
|
+
spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
|
45
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: smart_validator
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- JustAnotherDude
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2024-03-14 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: qonfig
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0.28'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0.28'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: smart_initializer
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0.11'
|
|
34
|
+
type: :runtime
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '0.11'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: smart_schema
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0.11'
|
|
48
|
+
type: :runtime
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0.11'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: bundler-audit
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0.9'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0.9'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: ci-helper
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0.6'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0.6'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: pry
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.14'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.14'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: rake
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '13.1'
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: '13.1'
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: rspec
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '3.13'
|
|
118
|
+
type: :development
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '3.13'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: armitage-rubocop
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '1.59'
|
|
132
|
+
type: :development
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '1.59'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: simplecov
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.22'
|
|
146
|
+
type: :development
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.22'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: simplecov-lcov
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0.8'
|
|
160
|
+
type: :development
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0.8'
|
|
167
|
+
description: Validation layer for any business logic with a declarative rule-oriented
|
|
168
|
+
API.
|
|
169
|
+
email:
|
|
170
|
+
- vanyaz158@gmail.com
|
|
171
|
+
executables: []
|
|
172
|
+
extensions: []
|
|
173
|
+
extra_rdoc_files: []
|
|
174
|
+
files:
|
|
175
|
+
- ".github/workflows/test.yml"
|
|
176
|
+
- ".gitignore"
|
|
177
|
+
- ".rspec"
|
|
178
|
+
- ".rubocop.yml"
|
|
179
|
+
- CHANGELOG.md
|
|
180
|
+
- Gemfile
|
|
181
|
+
- Gemfile.lock
|
|
182
|
+
- LICENSE.txt
|
|
183
|
+
- README.md
|
|
184
|
+
- Rakefile
|
|
185
|
+
- bin/console
|
|
186
|
+
- bin/setup
|
|
187
|
+
- lib/smart_core/validator.rb
|
|
188
|
+
- lib/smart_core/validator/class_state.rb
|
|
189
|
+
- lib/smart_core/validator/class_state/container.rb
|
|
190
|
+
- lib/smart_core/validator/class_state/initialize_mixin.rb
|
|
191
|
+
- lib/smart_core/validator/contract.rb
|
|
192
|
+
- lib/smart_core/validator/errors.rb
|
|
193
|
+
- lib/smart_core/validator/errors_controller.rb
|
|
194
|
+
- lib/smart_core/validator/errors_controller/base.rb
|
|
195
|
+
- lib/smart_core/validator/errors_controller/error_per_attribute.rb
|
|
196
|
+
- lib/smart_core/validator/errors_controller/many_errors_per_attribute.rb
|
|
197
|
+
- lib/smart_core/validator/result.rb
|
|
198
|
+
- lib/smart_core/validator/rule.rb
|
|
199
|
+
- lib/smart_core/validator/rule_execition_context/failure.rb
|
|
200
|
+
- lib/smart_core/validator/rule_execition_context/result.rb
|
|
201
|
+
- lib/smart_core/validator/rule_execution_context.rb
|
|
202
|
+
- lib/smart_core/validator/utils.rb
|
|
203
|
+
- lib/smart_core/validator/version.rb
|
|
204
|
+
- smart_validator.gemspec
|
|
205
|
+
homepage: https://github.com/smart-rb/smart_validator
|
|
206
|
+
licenses:
|
|
207
|
+
- MIT
|
|
208
|
+
metadata:
|
|
209
|
+
homepage_uri: https://github.com/smart-rb/smart_validator
|
|
210
|
+
source_code_uri: https://github.com/smart-rb/smart_validator/blob/master
|
|
211
|
+
changelog_uri: https://github.com/smart-rb/smart_validator/blob/master/CHANGELOG.md
|
|
212
|
+
post_install_message:
|
|
213
|
+
rdoc_options: []
|
|
214
|
+
require_paths:
|
|
215
|
+
- lib
|
|
216
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
217
|
+
requirements:
|
|
218
|
+
- - ">="
|
|
219
|
+
- !ruby/object:Gem::Version
|
|
220
|
+
version: '3.0'
|
|
221
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
222
|
+
requirements:
|
|
223
|
+
- - ">="
|
|
224
|
+
- !ruby/object:Gem::Version
|
|
225
|
+
version: '0'
|
|
226
|
+
requirements: []
|
|
227
|
+
rubygems_version: 3.5.3
|
|
228
|
+
signing_key:
|
|
229
|
+
specification_version: 4
|
|
230
|
+
summary: Custom DSL-first validator with a conviniet declarative API.
|
|
231
|
+
test_files: []
|