definition 0.2.0 → 0.3.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 +4 -4
- data/Changelog.md +4 -0
- data/README.md +34 -0
- data/benchmark/coercion.rb +1 -1
- data/benchmark/complex_example.rb +2 -2
- data/benchmark/validation_only.rb +1 -1
- data/config/locales/en.yml +22 -0
- data/definition.gemspec +3 -0
- data/lib/definition.rb +1 -0
- data/lib/definition/conform_error.rb +41 -2
- data/lib/definition/conform_result.rb +44 -4
- data/lib/definition/dsl.rb +3 -3
- data/lib/definition/dsl/comparators.rb +9 -9
- data/lib/definition/i18n.rb +3 -0
- data/lib/definition/key_conform_error.rb +32 -0
- data/lib/definition/types/and.rb +2 -2
- data/lib/definition/types/base.rb +3 -2
- data/lib/definition/types/each.rb +10 -5
- data/lib/definition/types/include.rb +2 -3
- data/lib/definition/types/keys.rb +23 -8
- data/lib/definition/types/lambda.rb +3 -3
- data/lib/definition/types/or.rb +1 -1
- data/lib/definition/types/type.rb +1 -1
- data/lib/definition/version.rb +1 -1
- data/tags +155 -0
- metadata +34 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3f3d334a06ce14e9f9f6eecccbc59206c11a293cd66b06cb8d20661698fb198
|
4
|
+
data.tar.gz: 59df3ceb4ff7643eea3eac301ad735969fafe31e7cbd6de89227fa4383beb348
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9e41d56a6e2eba1cc0e11adda3b69de22ce94d5de3d6ce01973c48548908745a8eb88329aa9b3f09d57f54231fc87a8eca0e614635902e1a9bb79809eed29816
|
7
|
+
data.tar.gz: b475ec666afc58aa64ac440be548b9c475c55ec4598ba7de97d9d413d9d11f12492a96736c6cb639d6bf65fdb7cf04c9197c67b0d2ca36bf4cfac7794ad09eba
|
data/Changelog.md
CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
5
5
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
+
## [0.3.0] - 2019-02-03
|
8
|
+
### Added
|
9
|
+
- Added I18n translation support for errors
|
10
|
+
|
7
11
|
## [0.2.0] - 2019-01-13
|
8
12
|
### Added
|
9
13
|
- Added built in definitions for common usecases (e.g. string length validation)
|
data/README.md
CHANGED
@@ -38,6 +38,12 @@ conform_result.passed? # => true
|
|
38
38
|
conform_result = schema.conform({first_name: "John", last_name: "Doe", birthday: "2018/02/09"})
|
39
39
|
conform_result.passed? # => false
|
40
40
|
conform_result.error_message # => hash fails validation for key birthday: { Is of type String instead of Date }
|
41
|
+
conform_result.error_hash # =>
|
42
|
+
# {
|
43
|
+
# :birthday => [
|
44
|
+
# [0] "Value is of wrong type, needs to be a Date"
|
45
|
+
# ]
|
46
|
+
# }
|
41
47
|
```
|
42
48
|
|
43
49
|
But it can also transform those data structures at the same time. The following
|
@@ -289,6 +295,34 @@ Definition.Equal("foo").conform("foo") # => pass
|
|
289
295
|
|
290
296
|
Check out the [integration specs](./spec/integration) for more usage examples.
|
291
297
|
|
298
|
+
### I18n translations
|
299
|
+
|
300
|
+
Every error object has a method `translated_error` that will give you a translated
|
301
|
+
version of the error message. You can load the default English translations shipped
|
302
|
+
with the gem by adding them to your I18n load path.
|
303
|
+
|
304
|
+
If you use the `error_hash` method on a `ConformResult` you also get the translated
|
305
|
+
error messages
|
306
|
+
|
307
|
+
```ruby
|
308
|
+
chema = Definition.Keys do
|
309
|
+
required :title, Definition.Type(String)
|
310
|
+
required :body, Definition.Type(String)
|
311
|
+
required(:author, Definition.Keys do
|
312
|
+
required :name, Definition.Type(String)
|
313
|
+
required :email, Definition.Type(String)
|
314
|
+
end)
|
315
|
+
end
|
316
|
+
result.error_hash # =>
|
317
|
+
# {
|
318
|
+
# :author => {
|
319
|
+
# :email => [
|
320
|
+
# [0] "Value is of wrong type, needs to be a String"
|
321
|
+
# ]
|
322
|
+
# }
|
323
|
+
# }
|
324
|
+
```
|
325
|
+
|
292
326
|
## Development
|
293
327
|
|
294
328
|
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.
|
data/benchmark/coercion.rb
CHANGED
@@ -4,11 +4,11 @@ require "bundler/inline"
|
|
4
4
|
|
5
5
|
gemfile do
|
6
6
|
source "https://rubygems.org"
|
7
|
-
gem "definition"
|
8
7
|
gem "dry-validation"
|
9
8
|
gem "awesome_print"
|
10
9
|
gem "benchmark-ips"
|
11
10
|
gem "pry"
|
11
|
+
gem "definition", path: File.expand_path("../.", __dir__)
|
12
12
|
end
|
13
13
|
|
14
14
|
DryTimeCoercionType = Dry::Types["strict.string"].constructor do |value|
|
@@ -4,11 +4,11 @@ require "bundler/inline"
|
|
4
4
|
|
5
5
|
gemfile do
|
6
6
|
source "https://rubygems.org"
|
7
|
-
gem "definition"
|
8
7
|
gem "dry-validation"
|
9
8
|
gem "awesome_print"
|
10
9
|
gem "benchmark-ips"
|
11
10
|
gem "pry"
|
11
|
+
gem "definition", path: File.expand_path("../.", __dir__)
|
12
12
|
end
|
13
13
|
|
14
14
|
DryTimeCoercionType = Dry::Types["strict.string"].constructor do |value|
|
@@ -56,7 +56,7 @@ MAX_LENGTH = Definition.Lambda(:max_length) do |value|
|
|
56
56
|
end
|
57
57
|
MAX_STRING_LENGTH = Definition.And(
|
58
58
|
Definition.Type(String),
|
59
|
-
|
59
|
+
Definition.MaxSize(1000)
|
60
60
|
)
|
61
61
|
MILLISECONDS_TIME = Definition.Lambda(:milliseconds_time) do |v|
|
62
62
|
conform_with(Time.at(v / 1000.0).utc) if v.is_a?(Integer)
|
@@ -4,10 +4,10 @@ require "bundler/inline"
|
|
4
4
|
|
5
5
|
gemfile do
|
6
6
|
source "https://rubygems.org"
|
7
|
-
gem "definition"
|
8
7
|
gem "dry-validation"
|
9
8
|
gem "awesome_print"
|
10
9
|
gem "benchmark-ips"
|
10
|
+
gem "definition", path: File.expand_path("../.", __dir__)
|
11
11
|
end
|
12
12
|
|
13
13
|
DrySchema = Dry::Validation.Params do
|
@@ -0,0 +1,22 @@
|
|
1
|
+
en:
|
2
|
+
definition:
|
3
|
+
max_size: "Value is bigger then %{max_size}"
|
4
|
+
min_size: "Value is smaller then %{min_size}"
|
5
|
+
greater_then: "Value must be greater then %{min_value}"
|
6
|
+
greater_then_equal: "Value must be greater or eqaul to %{min_value}"
|
7
|
+
less_then: "Value must be less then %{max_value}"
|
8
|
+
less_then_equal: "Value must be less or eqaul to %{max_value}"
|
9
|
+
equal: "Value must be equal to '%{expected_value}'"
|
10
|
+
empty: "Value must be empty"
|
11
|
+
non_empty: "Value must not be empty"
|
12
|
+
nil: "Value must be nil"
|
13
|
+
type: "Value is of wrong type, needs to be a %{class}"
|
14
|
+
enum: "Value is not one of: %{allowed_values}"
|
15
|
+
each: "Not all values are valid"
|
16
|
+
and: "Not all definitions conform"
|
17
|
+
or: "None of the definitions conform"
|
18
|
+
non_empty_string: "Value must be a non empty string"
|
19
|
+
regex: "Value dos not match regex %{regex}"
|
20
|
+
keys:
|
21
|
+
has_extra_key: "Hash has unexpected key %{key}"
|
22
|
+
has_missing_key: "Hash is missing key %{key}"
|
data/definition.gemspec
CHANGED
@@ -21,6 +21,9 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
22
|
spec.require_paths = ["lib"]
|
23
23
|
|
24
|
+
spec.add_dependency "activesupport"
|
25
|
+
spec.add_dependency "i18n"
|
26
|
+
|
24
27
|
spec.add_development_dependency "approvals", "~> 0.0"
|
25
28
|
spec.add_development_dependency "awesome_print"
|
26
29
|
spec.add_development_dependency "benchmark-ips"
|
data/lib/definition.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "i18n"
|
4
|
+
|
3
5
|
module Definition
|
4
6
|
class ConformError
|
5
|
-
def initialize(definition, message, sub_errors: [])
|
7
|
+
def initialize(definition, message, sub_errors: [], i18n_key: definition.name)
|
6
8
|
self.definition = definition
|
7
9
|
self.message = message
|
8
10
|
self.sub_errors = sub_errors
|
11
|
+
self.i18n_key = i18n_key
|
12
|
+
assign_parents
|
9
13
|
end
|
10
14
|
|
11
|
-
attr_accessor :definition, :sub_errors
|
15
|
+
attr_accessor :definition, :sub_errors, :parent, :i18n_key
|
12
16
|
attr_writer :message
|
13
17
|
|
14
18
|
def message
|
@@ -18,5 +22,40 @@ module Definition
|
|
18
22
|
"#{@message}: { " + sub_errors.map(&:message).join(", ") + " }"
|
19
23
|
end
|
20
24
|
end
|
25
|
+
|
26
|
+
def error_path
|
27
|
+
current = self
|
28
|
+
path = current.is_a?(KeyConformError) ? [key] : []
|
29
|
+
while (current = current.parent)
|
30
|
+
next unless current.is_a?(KeyConformError)
|
31
|
+
|
32
|
+
path += [current.key]
|
33
|
+
end
|
34
|
+
path.reverse
|
35
|
+
end
|
36
|
+
|
37
|
+
def json_pointer
|
38
|
+
"/#{error_path.join('/')}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def leaf_errors
|
42
|
+
return [self] if sub_errors.empty?
|
43
|
+
|
44
|
+
sub_errors.map(&:leaf_errors).flatten
|
45
|
+
end
|
46
|
+
|
47
|
+
def translated_error(namespace = "definition", vars: {})
|
48
|
+
namespace ||= "definition"
|
49
|
+
vars[:key] = key if respond_to?(:key)
|
50
|
+
::I18n.t("#{namespace}.#{i18n_key}", definition.context.merge!(vars))
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def assign_parents
|
56
|
+
sub_errors.each do |error|
|
57
|
+
error.parent = self
|
58
|
+
end
|
59
|
+
end
|
21
60
|
end
|
22
61
|
end
|
@@ -1,20 +1,60 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
|
3
5
|
module Definition
|
4
6
|
class ConformResult
|
5
7
|
def initialize(value, errors: [])
|
6
8
|
self.value = value
|
7
|
-
self.
|
9
|
+
self.conform_errors = errors
|
8
10
|
end
|
9
11
|
|
10
|
-
attr_accessor :value
|
12
|
+
attr_accessor :value
|
11
13
|
|
12
14
|
def passed?
|
13
|
-
|
15
|
+
conform_errors.empty?
|
16
|
+
end
|
17
|
+
alias conformed? passed?
|
18
|
+
|
19
|
+
def descriptive_errors
|
20
|
+
errors.map do |e|
|
21
|
+
{
|
22
|
+
description: e.message,
|
23
|
+
pointer: e.json_pointer
|
24
|
+
}
|
25
|
+
end
|
14
26
|
end
|
15
27
|
|
16
28
|
def error_message
|
17
|
-
|
29
|
+
error_tree.map(&:message).join(", ")
|
18
30
|
end
|
31
|
+
|
32
|
+
def errors
|
33
|
+
conform_errors.map(&:leaf_errors).flatten
|
34
|
+
end
|
35
|
+
|
36
|
+
def error_hash(i18n_namespace: nil)
|
37
|
+
{}.tap do |error_hash|
|
38
|
+
errors.each do |error|
|
39
|
+
next if error.error_path.empty?
|
40
|
+
|
41
|
+
message = error.translated_error(i18n_namespace)
|
42
|
+
path_hash = error.error_path.reverse
|
43
|
+
.inject([message]) { |messages, key| { key => messages } }
|
44
|
+
|
45
|
+
error_hash.deep_merge!(path_hash) do |_key, old, new|
|
46
|
+
old + new if old.is_a?(Array) && new.is_a?(Array) # concat arrays during deep_merge
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def error_tree
|
53
|
+
conform_errors
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
attr_accessor :conform_errors
|
19
59
|
end
|
20
60
|
end
|
data/lib/definition/dsl.rb
CHANGED
@@ -53,14 +53,14 @@ module Definition
|
|
53
53
|
# Lambda(:even) do |value|
|
54
54
|
# value.even?
|
55
55
|
# end
|
56
|
-
def Lambda(name, &block) # rubocop:disable Naming/MethodName
|
57
|
-
Types::Lambda.new(name, &block)
|
56
|
+
def Lambda(name, context: {}, &block) # rubocop:disable Naming/MethodName
|
57
|
+
Types::Lambda.new(name, context: context, &block)
|
58
58
|
end
|
59
59
|
|
60
60
|
# Example:
|
61
61
|
# Enum("allowed_value1", "allowed_value2")
|
62
62
|
def Enum(*allowed_values) # rubocop:disable Naming/MethodName
|
63
|
-
Lambda("enum
|
63
|
+
Lambda("enum", context: { allowed_values: allowed_values }) do |value|
|
64
64
|
conform_with(value) if allowed_values.include?(value)
|
65
65
|
end
|
66
66
|
end
|
@@ -6,7 +6,7 @@ module Definition
|
|
6
6
|
# Example:
|
7
7
|
# MaxSize(5)
|
8
8
|
def MaxSize(max_size) # rubocop:disable Naming/MethodName
|
9
|
-
Types::Lambda.new(:max_size) do |value|
|
9
|
+
Types::Lambda.new(:max_size, context: { max_size: max_size }) do |value|
|
10
10
|
case value
|
11
11
|
when String, Enumerable
|
12
12
|
conform_with(value) if value.size <= max_size
|
@@ -19,7 +19,7 @@ module Definition
|
|
19
19
|
# Example:
|
20
20
|
# MinSize(5)
|
21
21
|
def MinSize(min_size) # rubocop:disable Naming/MethodName
|
22
|
-
Types::Lambda.new(:min_size) do |value|
|
22
|
+
Types::Lambda.new(:min_size, context: { min_size: min_size }) do |value|
|
23
23
|
case value
|
24
24
|
when String, Enumerable
|
25
25
|
conform_with(value) if value.size >= min_size
|
@@ -38,7 +38,7 @@ module Definition
|
|
38
38
|
# Example:
|
39
39
|
# GreaterThen(5)
|
40
40
|
def GreaterThen(min_value) # rubocop:disable Naming/MethodName
|
41
|
-
Types::Lambda.new("
|
41
|
+
Types::Lambda.new("greater_then", context: { min_value: min_value }) do |value|
|
42
42
|
conform_with(value) if value.is_a?(Numeric) && value > min_value
|
43
43
|
end
|
44
44
|
end
|
@@ -46,7 +46,7 @@ module Definition
|
|
46
46
|
# Example:
|
47
47
|
# GreaterThenEqual(5)
|
48
48
|
def GreaterThenEqual(min_value) # rubocop:disable Naming/MethodName
|
49
|
-
Types::Lambda.new("
|
49
|
+
Types::Lambda.new("greater_then_equal", context: { min_value: min_value }) do |value|
|
50
50
|
conform_with(value) if value.is_a?(Numeric) && value >= min_value
|
51
51
|
end
|
52
52
|
end
|
@@ -54,7 +54,7 @@ module Definition
|
|
54
54
|
# Example:
|
55
55
|
# LessThen(5)
|
56
56
|
def LessThen(max_value) # rubocop:disable Naming/MethodName
|
57
|
-
Types::Lambda.new("
|
57
|
+
Types::Lambda.new("less_then", context: { max_value: max_value }) do |value|
|
58
58
|
conform_with(value) if value.is_a?(Numeric) && value < max_value
|
59
59
|
end
|
60
60
|
end
|
@@ -62,7 +62,7 @@ module Definition
|
|
62
62
|
# Example:
|
63
63
|
# LessThenEqual(5)
|
64
64
|
def LessThenEqual(max_value) # rubocop:disable Naming/MethodName
|
65
|
-
Types::Lambda.new("
|
65
|
+
Types::Lambda.new("less_then_equal", context: { max_value: max_value }) do |value|
|
66
66
|
conform_with(value) if value.is_a?(Numeric) && value <= max_value
|
67
67
|
end
|
68
68
|
end
|
@@ -70,7 +70,7 @@ module Definition
|
|
70
70
|
# Example:
|
71
71
|
# Equal("value")
|
72
72
|
def Equal(expected_value) # rubocop:disable Naming/MethodName
|
73
|
-
Types::Lambda.new(:equal) do |value|
|
73
|
+
Types::Lambda.new(:equal, context: { expected_value: expected_value }) do |value|
|
74
74
|
conform_with(value) if value == expected_value
|
75
75
|
end
|
76
76
|
end
|
@@ -103,8 +103,8 @@ module Definition
|
|
103
103
|
|
104
104
|
# Example:
|
105
105
|
# Regex
|
106
|
-
def Regex(regex) # rubocop:disable Naming/MethodName
|
107
|
-
Types::Lambda.new(
|
106
|
+
def Regex(regex, name: :regex) # rubocop:disable Naming/MethodName
|
107
|
+
Types::Lambda.new(name, context: { regex: regex.inspect }) do |value|
|
108
108
|
case value
|
109
109
|
when String
|
110
110
|
conform_with(value) unless regex.match(value).nil?
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "definition/conform_error"
|
4
|
+
|
5
|
+
module Definition
|
6
|
+
class KeyConformError < ConformError
|
7
|
+
def initialize(definition, message, key:, sub_errors: [], i18n_key: definition.name)
|
8
|
+
self.key = key
|
9
|
+
super(definition, message, sub_errors: sub_errors, i18n_key: i18n_key)
|
10
|
+
end
|
11
|
+
|
12
|
+
attr_accessor :key
|
13
|
+
|
14
|
+
def error_key_path
|
15
|
+
path = [key]
|
16
|
+
while (current = parent)
|
17
|
+
next unless current.is_a?(KeyConformError)
|
18
|
+
|
19
|
+
path += [current.key]
|
20
|
+
end
|
21
|
+
path.reverse
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def assign_parents
|
27
|
+
sub_errors.each do |error|
|
28
|
+
error.parent = self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/definition/types/and.rb
CHANGED
@@ -31,12 +31,12 @@ module Definition
|
|
31
31
|
def conform(value)
|
32
32
|
results = conform_all(value)
|
33
33
|
|
34
|
-
if results.all?
|
34
|
+
if results.all?(&:conformed?)
|
35
35
|
ConformResult.new(results.last.value)
|
36
36
|
else
|
37
37
|
ConformResult.new(value, errors: [
|
38
38
|
ConformError.new(definition, "Not all definitions are valid for #{definition.name}",
|
39
|
-
sub_errors: results.map(&:
|
39
|
+
sub_errors: results.map(&:error_tree).flatten)
|
40
40
|
])
|
41
41
|
end
|
42
42
|
end
|
@@ -6,10 +6,11 @@ require "definition/conform_error"
|
|
6
6
|
module Definition
|
7
7
|
module Types
|
8
8
|
class Base
|
9
|
-
attr_accessor :name
|
9
|
+
attr_accessor :name, :context
|
10
10
|
|
11
|
-
def initialize(name)
|
11
|
+
def initialize(name, context: {})
|
12
12
|
self.name = name
|
13
|
+
self.context = context
|
13
14
|
end
|
14
15
|
|
15
16
|
def explain(value)
|
@@ -26,7 +26,7 @@ module Definition
|
|
26
26
|
|
27
27
|
results = conform_all(value)
|
28
28
|
|
29
|
-
if results.all?
|
29
|
+
if results.all?(&:conformed?)
|
30
30
|
ConformResult.new(results.map(&:value))
|
31
31
|
else
|
32
32
|
ConformResult.new(value, errors: [ConformError.new(definition,
|
@@ -40,13 +40,18 @@ module Definition
|
|
40
40
|
attr_accessor :definition
|
41
41
|
|
42
42
|
def errors(results)
|
43
|
-
|
44
|
-
|
43
|
+
errors = []
|
44
|
+
results.each_with_index do |result, index|
|
45
|
+
next if result.passed?
|
46
|
+
|
47
|
+
errors << KeyConformError.new(
|
45
48
|
definition,
|
46
|
-
"Item #{
|
47
|
-
|
49
|
+
"Item #{result.value.inspect} did not conform to #{definition.name}",
|
50
|
+
key: index,
|
51
|
+
sub_errors: result.error_tree
|
48
52
|
)
|
49
53
|
end
|
54
|
+
errors
|
50
55
|
end
|
51
56
|
|
52
57
|
def conform_all(values)
|
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# frozen_string_literal: true
|
4
|
-
|
5
3
|
require "definition/types/base"
|
4
|
+
require "definition/key_conform_error"
|
6
5
|
|
7
6
|
module Definition
|
8
7
|
module Types
|
@@ -39,7 +38,7 @@ module Definition
|
|
39
38
|
definition.required_items.map do |item|
|
40
39
|
next if value.include?(item)
|
41
40
|
|
42
|
-
|
41
|
+
KeyConformError.new(definition, "#{definition.name} does not include #{item.inspect}", key: item)
|
43
42
|
end.compact
|
44
43
|
end
|
45
44
|
|
@@ -4,6 +4,7 @@
|
|
4
4
|
|
5
5
|
require "definition/types/base"
|
6
6
|
require "definition/types/include"
|
7
|
+
require "definition/key_conform_error"
|
7
8
|
|
8
9
|
module Definition
|
9
10
|
module Types
|
@@ -58,10 +59,14 @@ module Definition
|
|
58
59
|
extra_keys = value.keys - all_keys
|
59
60
|
return if extra_keys.empty?
|
60
61
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
62
|
+
extra_keys.each do |key|
|
63
|
+
errors.push(KeyConformError.new(
|
64
|
+
definition,
|
65
|
+
"#{definition.name} has extra key: #{key.inspect}",
|
66
|
+
key: key,
|
67
|
+
i18n_key: "keys.has_extra_key"
|
68
|
+
))
|
69
|
+
end
|
65
70
|
end
|
66
71
|
|
67
72
|
def conform_all_keys
|
@@ -99,9 +104,10 @@ module Definition
|
|
99
104
|
result_value[key] = result.value
|
100
105
|
next if result.passed?
|
101
106
|
|
102
|
-
errors.push(
|
103
|
-
|
104
|
-
|
107
|
+
errors.push(KeyConformError.new(key_definition,
|
108
|
+
"#{definition.name} fails validation for key #{key}",
|
109
|
+
key: key,
|
110
|
+
sub_errors: result.error_tree))
|
105
111
|
end
|
106
112
|
end
|
107
113
|
|
@@ -114,7 +120,16 @@ module Definition
|
|
114
120
|
result = required_definition.conform(value)
|
115
121
|
return if result.passed?
|
116
122
|
|
117
|
-
|
123
|
+
result.errors.each do |error|
|
124
|
+
errors.push(missing_key_error(error.key))
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def missing_key_error(key)
|
129
|
+
KeyConformError.new(definition,
|
130
|
+
"#{definition.name} is missing key #{key.inspect}",
|
131
|
+
key: key,
|
132
|
+
i18n_key: "keys.has_missing_key")
|
118
133
|
end
|
119
134
|
|
120
135
|
attr_accessor :definition, :value
|
@@ -10,11 +10,11 @@ module Definition
|
|
10
10
|
ConformResult.new(value)
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
13
|
include Dsl
|
15
|
-
|
14
|
+
|
15
|
+
def initialize(name, context: {}, &test_lambda)
|
16
16
|
self.test_lambda = test_lambda
|
17
|
-
super(name)
|
17
|
+
super(name, context: context)
|
18
18
|
end
|
19
19
|
|
20
20
|
def conform(value)
|
data/lib/definition/types/or.rb
CHANGED
data/lib/definition/version.rb
CHANGED
data/tags
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
2
|
+
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
3
|
+
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
4
|
+
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
5
|
+
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
6
|
+
!_TAG_PROGRAM_VERSION 5.9~svn20110310 //
|
7
|
+
And lib/definition/dsl.rb /^ def And(*definitions) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
8
|
+
And lib/definition/types/and.rb /^ class And < Base$/;" c class:Definition.Types
|
9
|
+
Base lib/definition/types/base.rb /^ class Base$/;" c class:Definition.Types
|
10
|
+
CoercibleType lib/definition/dsl.rb /^ def CoercibleType(klass) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
11
|
+
Comparators lib/definition/dsl/comparators.rb /^ module Comparators$/;" m class:Definition.Dsl
|
12
|
+
ConformError lib/definition/conform_error.rb /^ class ConformError$/;" c class:Definition
|
13
|
+
ConformResult lib/definition/conform_result.rb /^ class ConformResult$/;" c class:Definition
|
14
|
+
Conformer lib/definition/types/and.rb /^ class Conformer$/;" c class:Definition.Types.And
|
15
|
+
Conformer lib/definition/types/each.rb /^ class Conformer$/;" c class:Definition.Types.Each
|
16
|
+
Conformer lib/definition/types/include.rb /^ class Conformer$/;" c class:Definition.Types.Include
|
17
|
+
Conformer lib/definition/types/keys.rb /^ class Conformer$/;" c class:Definition.Types.Keys
|
18
|
+
Conformer lib/definition/types/or.rb /^ class Conformer$/;" c class:Definition.Types.Or
|
19
|
+
Definition lib/definition.rb /^module Definition$/;" m
|
20
|
+
Definition lib/definition/conform_error.rb /^module Definition$/;" m
|
21
|
+
Definition lib/definition/conform_result.rb /^module Definition$/;" m
|
22
|
+
Definition lib/definition/dsl.rb /^module Definition$/;" m
|
23
|
+
Definition lib/definition/dsl/comparators.rb /^module Definition$/;" m
|
24
|
+
Definition lib/definition/dsl/nil.rb /^module Definition$/;" m
|
25
|
+
Definition lib/definition/key_conform_error.rb /^module Definition$/;" m
|
26
|
+
Definition lib/definition/types/and.rb /^module Definition$/;" m
|
27
|
+
Definition lib/definition/types/base.rb /^module Definition$/;" m
|
28
|
+
Definition lib/definition/types/each.rb /^module Definition$/;" m
|
29
|
+
Definition lib/definition/types/include.rb /^module Definition$/;" m
|
30
|
+
Definition lib/definition/types/keys.rb /^module Definition$/;" m
|
31
|
+
Definition lib/definition/types/lambda.rb /^module Definition$/;" m
|
32
|
+
Definition lib/definition/types/or.rb /^module Definition$/;" m
|
33
|
+
Definition lib/definition/types/type.rb /^module Definition$/;" m
|
34
|
+
Definition lib/definition/value_object.rb /^module Definition$/;" m
|
35
|
+
Definition lib/definition/version.rb /^module Definition$/;" m
|
36
|
+
Dsl lib/definition/dsl.rb /^ module Dsl$/;" m class:Definition
|
37
|
+
Dsl lib/definition/dsl/comparators.rb /^ module Dsl$/;" m class:Definition
|
38
|
+
Dsl lib/definition/dsl/nil.rb /^ module Dsl$/;" m class:Definition
|
39
|
+
Dsl lib/definition/types/and.rb /^ module Dsl$/;" m class:Definition.Types.And
|
40
|
+
Dsl lib/definition/types/keys.rb /^ module Dsl$/;" m class:Definition.Types.Keys
|
41
|
+
Dsl lib/definition/types/lambda.rb /^ module Dsl$/;" m class:Definition.Types.Lambda
|
42
|
+
Dsl lib/definition/types/or.rb /^ module Dsl$/;" m class:Definition.Types.Or
|
43
|
+
Each lib/definition/dsl.rb /^ def Each(definition) # rubocop:disable Naming\/MethodName$/;" f class:Definition
|
44
|
+
Each lib/definition/types/each.rb /^ class Each < Base$/;" c class:Definition.Types
|
45
|
+
Empty lib/definition/dsl/comparators.rb /^ def Empty # rubocop:disable Naming\/MethodName$/;" f
|
46
|
+
Enum lib/definition/dsl.rb /^ def Enum(*allowed_values) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
47
|
+
Equal lib/definition/dsl/comparators.rb /^ def Equal(expected_value) # rubocop:disable Naming\/MethodName$/;" f
|
48
|
+
GreaterThen lib/definition/dsl/comparators.rb /^ def GreaterThen(min_value) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl.Comparators
|
49
|
+
GreaterThenEqual lib/definition/dsl/comparators.rb /^ def GreaterThenEqual(min_value) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
50
|
+
Include lib/definition/types/include.rb /^ class Include < Base$/;" c class:Definition.Types
|
51
|
+
InvalidValueObjectError lib/definition/value_object.rb /^ class InvalidValueObjectError < StandardError; end$/;" c class:Definition
|
52
|
+
JsonApiRequestHandler spec/integration/usecases/jsonapi_spec.rb /^ class JsonApiRequestHandler$/;" c
|
53
|
+
KeyConformError lib/definition/key_conform_error.rb /^ class KeyConformError < ConformError$/;" c class:Definition
|
54
|
+
Keys lib/definition/dsl.rb /^ def Keys(&block) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
55
|
+
Keys lib/definition/types/keys.rb /^ class Keys < Base$/;" c class:Definition.Types
|
56
|
+
Lambda lib/definition/dsl.rb /^ def Lambda(name, &block) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
57
|
+
Lambda lib/definition/types/lambda.rb /^ class Lambda < Base$/;" c class:Definition.Types
|
58
|
+
LessThen lib/definition/dsl/comparators.rb /^ def LessThen(max_value) # rubocop:disable Naming\/MethodName$/;" f class:Definition
|
59
|
+
LessThenEqual lib/definition/dsl/comparators.rb /^ def LessThenEqual(max_value) # rubocop:disable Naming\/MethodName$/;" f
|
60
|
+
MaxSize lib/definition/dsl/comparators.rb /^ def MaxSize(max_size) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl.Comparators
|
61
|
+
MinSize lib/definition/dsl/comparators.rb /^ def MinSize(min_size) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl.Comparators
|
62
|
+
Nil lib/definition/dsl/nil.rb /^ def Nil # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl.Nil
|
63
|
+
Nil lib/definition/dsl/nil.rb /^ module Nil$/;" m class:Definition.Dsl
|
64
|
+
NonEmpty lib/definition/dsl/comparators.rb /^ def NonEmpty # rubocop:disable Naming\/MethodName$/;" f
|
65
|
+
NonEmptyString lib/definition/dsl/comparators.rb /^ def NonEmptyString # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl.Comparators
|
66
|
+
NotConfiguredError lib/definition/value_object.rb /^ class NotConfiguredError < StandardError; end$/;" c class:Definition
|
67
|
+
Or lib/definition/dsl.rb /^ def Or(*definitions) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
68
|
+
Or lib/definition/types/or.rb /^ class Or < Base$/;" c class:Definition.Types
|
69
|
+
Regex lib/definition/dsl/comparators.rb /^ def Regex(regex, name: :regex) # rubocop:disable Naming\/MethodName$/;" f
|
70
|
+
SpecHelpers spec/support/spec_helpers.rb /^module SpecHelpers$/;" m
|
71
|
+
TestArrayValueObject spec/lib/definition/value_object_spec.rb /^ class TestArrayValueObject < described_class$/;" c
|
72
|
+
TestKeysValueObject spec/lib/definition/value_object_spec.rb /^ class TestKeysValueObject < described_class$/;" c
|
73
|
+
TestUnconfiguredValueObject spec/lib/definition/value_object_spec.rb /^ class TestUnconfiguredValueObject < described_class; end$/;" c
|
74
|
+
Type lib/definition/dsl.rb /^ def Type(klass) # rubocop:disable Naming\/MethodName$/;" f class:Definition.Dsl
|
75
|
+
Type lib/definition/types/type.rb /^ class Type < Base$/;" c class:Definition.Types
|
76
|
+
Types lib/definition/types/and.rb /^ module Types$/;" m class:Definition
|
77
|
+
Types lib/definition/types/base.rb /^ module Types$/;" m class:Definition
|
78
|
+
Types lib/definition/types/each.rb /^ module Types$/;" m class:Definition
|
79
|
+
Types lib/definition/types/include.rb /^ module Types$/;" m class:Definition
|
80
|
+
Types lib/definition/types/keys.rb /^ module Types$/;" m class:Definition
|
81
|
+
Types lib/definition/types/lambda.rb /^ module Types$/;" m class:Definition
|
82
|
+
Types lib/definition/types/or.rb /^ module Types$/;" m class:Definition
|
83
|
+
Types lib/definition/types/type.rb /^ module Types$/;" m class:Definition
|
84
|
+
ValueObject lib/definition/value_object.rb /^ class ValueObject < SimpleDelegator$/;" c class:Definition
|
85
|
+
add_extra_key_errors lib/definition/types/keys.rb /^ def add_extra_key_errors$/;" f class:Definition.Types.Keys.Conformer
|
86
|
+
add_missing_key_errors lib/definition/types/keys.rb /^ def add_missing_key_errors$/;" f class:Definition.Types.Keys.Conformer
|
87
|
+
all_keys lib/definition/types/keys.rb /^ def all_keys$/;" f class:Definition.Types.Keys.Conformer
|
88
|
+
assign_parents lib/definition/conform_error.rb /^ def assign_parents$/;" f class:Definition.ConformError.error_path
|
89
|
+
assign_parents lib/definition/key_conform_error.rb /^ def assign_parents$/;" f class:Definition.KeyConformError.error_key_path
|
90
|
+
conform lib/definition/types/and.rb /^ def conform(value)$/;" f class:Definition.Types.And.Conformer
|
91
|
+
conform lib/definition/types/and.rb /^ def conform(value)$/;" f class:Definition.Types.And
|
92
|
+
conform lib/definition/types/base.rb /^ def conform(_value)$/;" f class:Definition.Types.Base
|
93
|
+
conform lib/definition/types/each.rb /^ def conform(value)$/;" f class:Definition.Types.Each.Conformer
|
94
|
+
conform lib/definition/types/each.rb /^ def conform(value)$/;" f class:Definition.Types.Each
|
95
|
+
conform lib/definition/types/include.rb /^ def conform(value)$/;" f class:Definition.Types.Include.Conformer
|
96
|
+
conform lib/definition/types/include.rb /^ def conform(value)$/;" f class:Definition.Types.Include
|
97
|
+
conform lib/definition/types/keys.rb /^ def conform$/;" f class:Definition.Types.Keys.Conformer
|
98
|
+
conform lib/definition/types/keys.rb /^ def conform(value)$/;" f class:Definition.Types.Keys
|
99
|
+
conform lib/definition/types/lambda.rb /^ def conform(value)$/;" f class:Definition.Types.Lambda
|
100
|
+
conform lib/definition/types/or.rb /^ def conform(value)$/;" f class:Definition.Types.Or.Conformer
|
101
|
+
conform lib/definition/types/or.rb /^ def conform(value)$/;" f class:Definition.Types.Or
|
102
|
+
conform lib/definition/types/type.rb /^ def conform(value)$/;" f class:Definition.Types.Type
|
103
|
+
conform lib/definition/value_object.rb /^ def conform(value)$/;" f class:Definition.ValueObject
|
104
|
+
conform_all lib/definition/types/and.rb /^ def conform_all(value)$/;" f class:Definition.Types.And.Conformer
|
105
|
+
conform_all lib/definition/types/each.rb /^ def conform_all(values)$/;" f class:Definition.Types.Each.Conformer
|
106
|
+
conform_all_keys lib/definition/types/keys.rb /^ def conform_all_keys$/;" f class:Definition.Types.Keys.Conformer
|
107
|
+
conform_definitions lib/definition/types/keys.rb /^ def conform_definitions(keys)$/;" f class:Definition.Types.Keys.Conformer
|
108
|
+
conform_with lib/definition/types/lambda.rb /^ def conform_with(value)$/;" f class:Definition.Types.Lambda.Dsl
|
109
|
+
conforming_definition spec/support/spec_helpers.rb /^ def conforming_definition(value)$/;" f class:SpecHelpers
|
110
|
+
define_accessor_methods lib/definition/value_object.rb /^ def define_accessor_methods$/;" f class:Definition.ValueObject
|
111
|
+
definition lib/definition/value_object.rb /^ def definition(definition)$/;" f class:Definition.ValueObject
|
112
|
+
error_key_path lib/definition/key_conform_error.rb /^ def error_key_path$/;" f class:Definition.KeyConformError
|
113
|
+
error_message lib/definition/conform_result.rb /^ def error_message$/;" f class:Definition.ConformResult
|
114
|
+
error_path lib/definition/conform_error.rb /^ def error_path$/;" f class:Definition.ConformError
|
115
|
+
errors lib/definition/types/each.rb /^ def errors(results)$/;" f class:Definition.Types.Each.Conformer
|
116
|
+
errors spec/integration/usecases/jsonapi_spec.rb /^ def self.errors(request_body)$/;" F class:JsonApiRequestHandler
|
117
|
+
explain lib/definition/types/base.rb /^ def explain(value)$/;" f class:Definition.Types.Base
|
118
|
+
failing_definition spec/support/spec_helpers.rb /^ def failing_definition(value, error_message)$/;" f class:SpecHelpers
|
119
|
+
first_successful_conform_or_errors lib/definition/types/or.rb /^ def first_successful_conform_or_errors(value)$/;" f class:Definition.Types.Or.Conformer
|
120
|
+
gather_errors lib/definition/types/include.rb /^ def gather_errors(value)$/;" f class:Definition.Types.Include.Conformer
|
121
|
+
initialize lib/definition/conform_error.rb /^ def initialize(definition, message, sub_errors: [], parent: nil)$/;" f class:Definition.ConformError
|
122
|
+
initialize lib/definition/conform_result.rb /^ def initialize(value, errors: [])$/;" f class:Definition.ConformResult
|
123
|
+
initialize lib/definition/key_conform_error.rb /^ def initialize(definition, message, key:, sub_errors: [], parent: nil)$/;" f class:Definition.KeyConformError
|
124
|
+
initialize lib/definition/types/and.rb /^ def initialize(definition)$/;" f class:Definition.Types.And.Conformer
|
125
|
+
initialize lib/definition/types/and.rb /^ def initialize(name, *args)$/;" f class:Definition.Types.And
|
126
|
+
initialize lib/definition/types/base.rb /^ def initialize(name, descriptions: {})$/;" f class:Definition.Types.Base
|
127
|
+
initialize lib/definition/types/each.rb /^ def initialize(definition)$/;" f class:Definition.Types.Each.Conformer
|
128
|
+
initialize lib/definition/types/each.rb /^ def initialize(name, definition:)$/;" f class:Definition.Types.Each
|
129
|
+
initialize lib/definition/types/include.rb /^ def initialize(definition)$/;" f class:Definition.Types.Include.Conformer
|
130
|
+
initialize lib/definition/types/include.rb /^ def initialize(name, *args)$/;" f class:Definition.Types.Include
|
131
|
+
initialize lib/definition/types/keys.rb /^ def initialize(definition, value)$/;" f class:Definition.Types.Keys.Conformer
|
132
|
+
initialize lib/definition/types/keys.rb /^ def initialize(name, req: {}, opt: {})$/;" f class:Definition.Types.Keys
|
133
|
+
initialize lib/definition/types/lambda.rb /^ def initialize(name, descriptions: {}, &test_lambda)$/;" f class:Definition.Types.Lambda
|
134
|
+
initialize lib/definition/types/or.rb /^ def initialize(definition)$/;" f class:Definition.Types.Or.Conformer
|
135
|
+
initialize lib/definition/types/or.rb /^ def initialize(name, *args)$/;" f class:Definition.Types.Or
|
136
|
+
initialize lib/definition/types/type.rb /^ def initialize(name, klass, &coerce)$/;" f class:Definition.Types.Type
|
137
|
+
initialize lib/definition/value_object.rb /^ def initialize(args = nil, **kwargs)$/;" f class:Definition.ValueObject
|
138
|
+
json_pointer lib/definition/conform_error.rb /^ def json_pointer$/;" f class:Definition.ConformError.error_path
|
139
|
+
keys lib/definition/types/keys.rb /^ def keys$/;" f class:Definition.Types.Keys
|
140
|
+
leaf_errors lib/definition/conform_result.rb /^ def leaf_errors$/;" f class:Definition.ConformResult
|
141
|
+
leafes lib/definition/conform_error.rb /^ def leafes$/;" f class:Definition.ConformError.error_path
|
142
|
+
message lib/definition/conform_error.rb /^ def message$/;" f class:Definition.ConformError
|
143
|
+
non_array_error lib/definition/types/each.rb /^ def non_array_error(value)$/;" f class:Definition.Types.Each.Conformer
|
144
|
+
optional lib/definition/types/keys.rb /^ def optional(key, definition)$/;" f class:Definition.Types.Keys.Dsl
|
145
|
+
optional_definitions lib/definition/types/keys.rb /^ def optional_definitions$/;" f class:Definition.Types.Keys.Conformer
|
146
|
+
optional_keys lib/definition/types/keys.rb /^ def optional_keys$/;" f class:Definition.Types.Keys.Conformer
|
147
|
+
passed? lib/definition/conform_result.rb /^ def passed?$/;" f class:Definition.ConformResult
|
148
|
+
required lib/definition/types/keys.rb /^ def required(key, definition)$/;" f class:Definition.Types.Keys.Dsl
|
149
|
+
required_definitions lib/definition/types/keys.rb /^ def required_definitions$/;" f class:Definition.Types.Keys.Conformer
|
150
|
+
required_keys lib/definition/types/keys.rb /^ def required_keys$/;" f class:Definition.Types.Keys.Conformer
|
151
|
+
translated_error lib/definition/conform_error.rb /^ def translated_error(namespace = "definition", vars: {})$/;" f class:Definition.ConformError.error_path
|
152
|
+
try_conform lib/definition/types/type.rb /^ def try_conform(value)$/;" f class:Definition.Types.Type
|
153
|
+
valid? lib/definition/types/type.rb /^ def valid?(value)$/;" f class:Definition.Types.Type
|
154
|
+
validate lib/definition/types/and.rb /^ def validate(definition)$/;" f class:Definition.Types.And.Dsl
|
155
|
+
validate lib/definition/types/or.rb /^ def validate(definition)$/;" f class:Definition.Types.Or.Dsl
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: definition
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Goltermann
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: i18n
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: approvals
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -229,6 +257,7 @@ files:
|
|
229
257
|
- benchmark/validation_only.rb
|
230
258
|
- bin/console
|
231
259
|
- bin/setup
|
260
|
+
- config/locales/en.yml
|
232
261
|
- definition.gemspec
|
233
262
|
- lib/definition.rb
|
234
263
|
- lib/definition/conform_error.rb
|
@@ -236,6 +265,8 @@ files:
|
|
236
265
|
- lib/definition/dsl.rb
|
237
266
|
- lib/definition/dsl/comparators.rb
|
238
267
|
- lib/definition/dsl/nil.rb
|
268
|
+
- lib/definition/i18n.rb
|
269
|
+
- lib/definition/key_conform_error.rb
|
239
270
|
- lib/definition/types.rb
|
240
271
|
- lib/definition/types/and.rb
|
241
272
|
- lib/definition/types/base.rb
|
@@ -247,6 +278,7 @@ files:
|
|
247
278
|
- lib/definition/types/type.rb
|
248
279
|
- lib/definition/value_object.rb
|
249
280
|
- lib/definition/version.rb
|
281
|
+
- tags
|
250
282
|
homepage: https://github.com/Goltergaul/definition
|
251
283
|
licenses:
|
252
284
|
- MIT
|