easy_json_matcher 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/easy_json_matcher/array_content_validator.rb +22 -0
- data/lib/easy_json_matcher/array_generator.rb +41 -0
- data/lib/easy_json_matcher/array_validator.rb +11 -76
- data/lib/easy_json_matcher/attribute_generator.rb +37 -0
- data/lib/easy_json_matcher/attribute_type_methods.rb +29 -0
- data/lib/easy_json_matcher/coercion_error.rb +10 -0
- data/lib/easy_json_matcher/content_wrapper.rb +2 -4
- data/lib/easy_json_matcher/{validation_error.rb → easy_json_matcher_error.rb} +2 -1
- data/lib/easy_json_matcher/json_coercer.rb +34 -0
- data/lib/easy_json_matcher/node.rb +10 -114
- data/lib/easy_json_matcher/node_generator.rb +58 -0
- data/lib/easy_json_matcher/schema_generator.rb +47 -71
- data/lib/easy_json_matcher/schema_library.rb +8 -11
- data/lib/easy_json_matcher/unknown_validation_step_error.rb +10 -0
- data/lib/easy_json_matcher/validation_chain_factory.rb +48 -0
- data/lib/easy_json_matcher/validation_rules.rb +59 -0
- data/lib/easy_json_matcher/validation_step.rb +36 -0
- data/lib/easy_json_matcher/validator.rb +12 -87
- data/lib/easy_json_matcher/validator_set.rb +31 -0
- data/lib/easy_json_matcher/version.rb +1 -1
- data/lib/easy_json_matcher.rb +6 -2
- data/lib/easy_json_matcher.rb~ +5 -0
- data/test/array_content_validator_test.rb +17 -0
- data/test/custom_validations_test.rb +17 -17
- data/test/global_validation_options_test.rb +39 -44
- data/test/json_coercer_test.rb +25 -0
- data/test/managing_schemas_test.rb +53 -52
- data/test/node_test.rb +28 -0
- data/test/primitives_boolean_test.rb +27 -0
- data/test/primitives_date_test.rb +28 -0
- data/test/primitives_number_test.rb +27 -0
- data/test/primitives_object_test.rb +27 -0
- data/test/primitives_string_test.rb +27 -0
- data/test/primtives_value_test.rb +23 -0
- data/test/required_validation_test.rb +7 -7
- data/test/schema_generator_test.rb +23 -0
- data/test/strict_mode_test.rb +25 -54
- data/test/test_helper.rb +8 -6
- data/test/validating_arrays_test.rb +40 -132
- data/test/validation_chain_factory_test.rb +45 -0
- data/test/validation_chain_test_helper.rb +13 -0
- data/test/validation_step_array_test.rb +27 -0
- data/test/validation_step_boolean_test.rb +19 -0
- data/test/validation_step_date_test.rb +20 -0
- data/test/validation_step_not_required_test.rb +35 -0
- data/test/validation_step_number_test.rb +23 -0
- data/test/validation_step_object_test.rb +20 -0
- data/test/validation_step_required_test.rb +19 -0
- data/test/validation_step_string_test.rb +20 -0
- data/test/validation_step_test.rb +55 -0
- data/test/validation_step_value_test.rb +15 -0
- data/test/validator_set_test.rb +49 -0
- data/test/validator_test.rb +44 -0
- metadata +64 -26
- data/lib/easy_json_matcher/boolean_validator.rb +0 -14
- data/lib/easy_json_matcher/date_validator.rb +0 -44
- data/lib/easy_json_matcher/node.rb~ +0 -121
- data/lib/easy_json_matcher/number_validator.rb +0 -22
- data/lib/easy_json_matcher/object_validator.rb +0 -12
- data/lib/easy_json_matcher/schema_generator.rb~ +0 -104
- data/lib/easy_json_matcher/string_validator.rb +0 -16
- data/lib/easy_json_matcher/validator.rb~ +0 -99
- data/lib/easy_json_matcher/validator_factory.rb +0 -76
- data/lib/easy_json_matcher/value_validator.rb +0 -10
- data/lib/easy_json_matcher/version.rb~ +0 -3
- data/test/custom_validations_test.rb~ +0 -25
- data/test/easy_json_matcher_test.rb +0 -262
- data/test/easy_json_matcher_test.rb~ +0 -262
- data/test/error_messages_test.rb +0 -148
- data/test/reset_test.rb +0 -32
- data/test/reset_test.rb~ +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55ae99f6f7c4b6ccee8c50a57555d58a5a4bd2b2
|
4
|
+
data.tar.gz: 713dc82d9dce7912117f6a59b419c3cfeff92441
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 012365ce1754864733914fcfcf7dd341d168168977e341014fd8804a7426a3c7e9bf005708e1c6f8e50d1c96a39dc82e048e303a0b30bfe98d445e0d718a270b
|
7
|
+
data.tar.gz: 51ecd2c9ca6f601ab1894da188fb1feecce8fb32a2d4ecd55c0001b2399b8c97a37a2a9c9cd3642630c732b283f8af8087faefa237f352ab65c90173dcae4a9c
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module EasyJSONMatcher
|
2
|
+
class ArrayContentValidator
|
3
|
+
|
4
|
+
attr_reader :next_step, :verifier
|
5
|
+
|
6
|
+
def initialize(verify_with:)
|
7
|
+
@verifier = verify_with
|
8
|
+
end
|
9
|
+
|
10
|
+
def check(value:)
|
11
|
+
errors = []
|
12
|
+
value.each do |val|
|
13
|
+
errors += verifier.check(value: val)
|
14
|
+
end
|
15
|
+
errors
|
16
|
+
end
|
17
|
+
|
18
|
+
def >> (step)
|
19
|
+
@next_step = step
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module EasyJSONMatcher
|
2
|
+
class ArrayGenerator
|
3
|
+
|
4
|
+
WHITELIST = [:required, :not_required]
|
5
|
+
|
6
|
+
attr_reader :opts, :content_opts, :target_class
|
7
|
+
|
8
|
+
def initialize(local_opts:, global_opts:, target_class: ArrayValidator)
|
9
|
+
@target_class = target_class
|
10
|
+
@opts = extract_opts(locals: local_opts, globals: global_opts)
|
11
|
+
@content_opts = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_array
|
15
|
+
target_class.new(opts: opts, verify_content_as: content_opts)
|
16
|
+
end
|
17
|
+
|
18
|
+
def elements_should(be:)
|
19
|
+
@content_opts = be
|
20
|
+
end
|
21
|
+
|
22
|
+
def extract_opts(locals:, globals:)
|
23
|
+
(globals.select(&array_options_filter) + locals).map(&override_local_values(locals: locals))
|
24
|
+
end
|
25
|
+
|
26
|
+
def array_options_filter
|
27
|
+
->(opt) { WHITELIST.include?(opt) }
|
28
|
+
end
|
29
|
+
|
30
|
+
def override_local_values(locals:)
|
31
|
+
conflicts = { required: :not_required }
|
32
|
+
->(opt) {
|
33
|
+
if conflicts.keys.include? opt
|
34
|
+
locals.include?(conflicts[opt]) ? conflicts[opt] : opt
|
35
|
+
else
|
36
|
+
opt
|
37
|
+
end
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -1,84 +1,19 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
class ArrayValidator < Validator
|
4
|
-
attr_reader :validators, :validator_results
|
5
|
-
######################### Methods for requiring values by type #################
|
6
|
-
|
7
|
-
def should_only_contain_strings(opts: {})
|
8
|
-
should_only_contain type: :string, opts: opts
|
9
|
-
end
|
10
|
-
|
11
|
-
def should_only_contain_objects(opts: {})
|
12
|
-
should_only_contain type: :object, opts: opts
|
13
|
-
end
|
14
|
-
|
15
|
-
def should_only_contain_values(opts: {})
|
16
|
-
should_only_contain type: :value, opts: opts
|
17
|
-
end
|
18
|
-
|
19
|
-
def should_only_contain_numbers(opts: {})
|
20
|
-
should_only_contain type: :number, opts: opts
|
21
|
-
end
|
22
|
-
|
23
|
-
def should_only_contain_booleans(opts: {})
|
24
|
-
should_only_contain type: :boolean, opts: opts
|
25
|
-
end
|
26
|
-
|
27
|
-
def should_only_contain_dates(opts: {})
|
28
|
-
should_only_contain type: :date, opts: opts
|
29
|
-
end
|
30
|
-
|
31
|
-
def should_only_contain_schema(name:, opts: {})
|
32
|
-
should_only_contain type: :schema, opts: opts.merge({name: name})
|
33
|
-
end
|
1
|
+
require "easy_json_matcher/validator"
|
2
|
+
require "easy_json_matcher/array_content_validator"
|
34
3
|
|
35
|
-
|
36
|
-
|
37
|
-
_add_validator(_create_validator(type: type, opts: opts))
|
38
|
-
end
|
39
|
-
|
40
|
-
######################## Private methods #######################################
|
41
|
-
|
42
|
-
def _validate
|
43
|
-
errors << "#{content} is not an Array" unless _content_is_array?
|
44
|
-
_validate_content
|
45
|
-
end
|
46
|
-
|
47
|
-
def _content_is_array?
|
48
|
-
content.is_a? Array
|
49
|
-
end
|
50
|
-
|
51
|
-
def _validate_content
|
52
|
-
validators.each do |val|
|
53
|
-
_accumulate_errors val
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def _clear_validators
|
58
|
-
validators.clear
|
59
|
-
end
|
60
|
-
|
61
|
-
def _add_validator(validator)
|
62
|
-
validators << validator
|
63
|
-
end
|
64
|
-
|
65
|
-
def validators
|
66
|
-
@validators ||= []
|
67
|
-
end
|
4
|
+
module EasyJSONMatcher
|
5
|
+
class ArrayValidator
|
68
6
|
|
69
|
-
|
70
|
-
content.each do |candidate|
|
71
|
-
_run_validator(validator, candidate)
|
72
|
-
end
|
73
|
-
errors << validator.errors unless validator._no_errors?
|
74
|
-
end
|
7
|
+
attr_reader :verifier
|
75
8
|
|
76
|
-
def
|
77
|
-
|
9
|
+
def initialize(opts: [], verify_content_as:, container: ArrayContentValidator, factory: ValidationChainFactory)
|
10
|
+
chain = factory.get_chain(steps: verify_content_as)
|
11
|
+
@verifier = factory.get_chain(steps: opts + [:array])
|
12
|
+
@verifier.concat(container.new(verify_with: chain))
|
78
13
|
end
|
79
14
|
|
80
|
-
def
|
81
|
-
|
15
|
+
def check(value:, errors: [])
|
16
|
+
verifier.check(value: value)
|
82
17
|
end
|
83
18
|
end
|
84
19
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module EasyJSONMatcher
|
2
|
+
class AttributeGenerator
|
3
|
+
|
4
|
+
attr_reader :opts, :factory
|
5
|
+
|
6
|
+
def initialize(attribute_factory: ValidationChainFactory, local_opts:, global_opts:)
|
7
|
+
@factory = attribute_factory
|
8
|
+
@opts = extract_opts(locals: local_opts, globals: global_opts)
|
9
|
+
end
|
10
|
+
|
11
|
+
def generate_attribute
|
12
|
+
factory.get_chain(steps: opts)
|
13
|
+
end
|
14
|
+
|
15
|
+
def extract_opts(locals:, globals:)
|
16
|
+
(globals.reject(&non_attribute_options_filter) + locals).map(&override_local_values(locals: locals))
|
17
|
+
end
|
18
|
+
|
19
|
+
#TODO this method should whitelist the options, and the options should be in a constant
|
20
|
+
# Remember to change extract_ops so that it uses globals.select afterwards
|
21
|
+
def non_attribute_options_filter
|
22
|
+
non_attribute_options = [:strict]
|
23
|
+
->(opt) { non_attribute_options.include? opt }
|
24
|
+
end
|
25
|
+
|
26
|
+
def override_local_values(locals:)
|
27
|
+
conflicts = { required: :not_required }
|
28
|
+
->(opt) {
|
29
|
+
if conflicts.keys.include? opt
|
30
|
+
locals.include?(conflicts[opt]) ? conflicts[opt] : opt
|
31
|
+
else
|
32
|
+
opt
|
33
|
+
end
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module AttributeTypeMethods
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
def has_boolean(key:, opts: [])
|
6
|
+
has_attribute(key: key, opts: opts + [:boolean])
|
7
|
+
end
|
8
|
+
|
9
|
+
def has_number(key: , opts: [])
|
10
|
+
has_attribute(key: key, opts: opts + [:number] )
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_date(key:, opts: [])
|
14
|
+
has_attribute(key: key, opts: opts + [:date])
|
15
|
+
end
|
16
|
+
|
17
|
+
def has_object(key:, opts: [])
|
18
|
+
has_attribute(key: key, opts: opts + [:object])
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_value(key:, opts: [])
|
22
|
+
has_attribute(key: key, opts: opts + [:value])
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_string(key:, opts: [])
|
26
|
+
has_attribute(key: key, opts: opts + [:string])
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -1,14 +1,12 @@
|
|
1
1
|
module EasyJSONMatcher
|
2
2
|
module ContentWrapper
|
3
3
|
|
4
|
+
attr_reader :content
|
5
|
+
|
4
6
|
def [](key)
|
5
7
|
content[key.to_s]
|
6
8
|
end
|
7
9
|
|
8
|
-
def method_missing(method, *args, &block)
|
9
|
-
content.send(method, *args, &block)
|
10
|
-
end
|
11
|
-
|
12
10
|
def keys
|
13
11
|
content.keys.map(&:to_sym)
|
14
12
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "json"
|
2
|
+
require "easy_json_matcher/coercion_error"
|
3
|
+
|
4
|
+
module EasyJSONMatcher
|
5
|
+
class JsonCoercer
|
6
|
+
|
7
|
+
def coerce(json:)
|
8
|
+
begin
|
9
|
+
coerced = JSON.parse(json)
|
10
|
+
symbolize_keys(hash: coerced)
|
11
|
+
rescue JSON::ParserError, TypeError
|
12
|
+
raise CoercionError.new invalid_string: json
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def symbolize_keys(hash:)
|
17
|
+
hash.keys.each do |key|
|
18
|
+
value = hash.delete(key)
|
19
|
+
convert_value(value)
|
20
|
+
hash[key.to_sym] = value
|
21
|
+
end
|
22
|
+
hash
|
23
|
+
end
|
24
|
+
|
25
|
+
def convert_value(value)
|
26
|
+
case value
|
27
|
+
when Hash
|
28
|
+
symbolize_keys(hash: value) if value.is_a? Hash
|
29
|
+
when Array
|
30
|
+
value.select {|val| val.is_a? Hash}.each {|h| symbolize_keys(hash: h) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -1,122 +1,18 @@
|
|
1
|
-
require
|
2
|
-
require 'json'
|
3
|
-
require 'easy_json_matcher/content_wrapper'
|
4
|
-
module EasyJSONMatcher
|
5
|
-
class Node < Validator
|
6
|
-
include ContentWrapper
|
7
|
-
|
8
|
-
attr_reader :validators, :validity, :strict
|
9
|
-
|
10
|
-
def initialize(opts: {})
|
11
|
-
super(options: opts)
|
12
|
-
@validators = []
|
13
|
-
@validity = true
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_validator(validator)
|
17
|
-
validators << validator
|
18
|
-
end
|
1
|
+
require "easy_json_matcher/validation_step"
|
19
2
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def _validate
|
25
|
-
_validate_strict_keyset
|
26
|
-
validators.each do |val|
|
27
|
-
@validity = false unless _use_validator val
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def reset!
|
32
|
-
@validity = true
|
33
|
-
errors.clear
|
34
|
-
validators.each(&:reset!)
|
35
|
-
end
|
36
|
-
|
37
|
-
def _validate_strict_keyset
|
38
|
-
_validate_keyset if strict
|
39
|
-
end
|
40
|
-
|
41
|
-
def _validate_keyset
|
42
|
-
unexpected_keys = keys - _expected_keys
|
43
|
-
errors << "#{unexpected_keys} found in addition to expected keys" unless unexpected_keys.empty?
|
44
|
-
end
|
45
|
-
|
46
|
-
def _expected_keys
|
47
|
-
validators.each_with_object([]) do |validator, keyset|
|
48
|
-
keyset << validator.key
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def _use_validator(validator)
|
53
|
-
validator.valid? self
|
54
|
-
end
|
55
|
-
|
56
|
-
def _get_content_for(key)
|
57
|
-
content[key]
|
58
|
-
end
|
59
|
-
|
60
|
-
def _get_validator_for(key)
|
61
|
-
validators[key]
|
62
|
-
end
|
63
|
-
|
64
|
-
def _set_content(candidate)
|
65
|
-
@content = _is_root? ? _prep_root_content(candidate) : candidate[key]
|
66
|
-
end
|
67
|
-
|
68
|
-
def _is_root?
|
69
|
-
key.nil?
|
70
|
-
end
|
71
|
-
|
72
|
-
def get_errors
|
73
|
-
child_errors = _collect_child_errors
|
74
|
-
_wrap_errors(child_errors)
|
75
|
-
end
|
76
|
-
|
77
|
-
def _collect_child_errors
|
78
|
-
validators.each_with_object({}) do |val, container|
|
79
|
-
container.merge!(val.get_errors)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
def _wrap_errors(child_errors)
|
84
|
-
_add_local_errors_to child_errors
|
85
|
-
unless _is_root?
|
86
|
-
_wrap_child_errors(child_errors)
|
87
|
-
else
|
88
|
-
_root_errors(child_errors)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def _add_local_errors_to(child_errors)
|
93
|
-
child_errors.merge!({node_errors_: errors}) unless errors.empty?
|
94
|
-
end
|
95
|
-
|
96
|
-
def _wrap_child_errors(child_errors)
|
97
|
-
errors_wrapper = {}
|
98
|
-
errors_wrapper[key] = child_errors
|
99
|
-
errors_wrapper
|
100
|
-
end
|
101
|
-
|
102
|
-
def _root_errors(child_errors)
|
103
|
-
errors.length > 0 ? {root: errors} : child_errors
|
104
|
-
end
|
3
|
+
module EasyJSONMatcher
|
4
|
+
class Node
|
105
5
|
|
106
|
-
|
107
|
-
candidate.is_a?(String) ? _parse_and_verify_json(candidate) : candidate
|
108
|
-
end
|
6
|
+
attr_reader :node_validator, :validators
|
109
7
|
|
110
|
-
def
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
errors << '#{json} is not a valid JSON String'
|
115
|
-
end
|
8
|
+
def initialize(opts: [], strict: false, validators:, content_handler: ValidatorSet, factory: ValidationChainFactory)
|
9
|
+
@node_validator = factory.get_chain(steps: opts + [:object])
|
10
|
+
@validators = content_handler.new(validators: validators, strict: strict)
|
11
|
+
@node_validator.concat(@validators)
|
116
12
|
end
|
117
13
|
|
118
|
-
def
|
119
|
-
|
14
|
+
def check(value:)
|
15
|
+
node_validator.check(value: value)
|
120
16
|
end
|
121
17
|
end
|
122
18
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require "easy_json_matcher/validation_chain_factory"
|
2
|
+
require "easy_json_matcher/node"
|
3
|
+
require "easy_json_matcher/schema_library"
|
4
|
+
require "easy_json_matcher/attribute_type_methods"
|
5
|
+
require "easy_json_matcher/attribute_generator"
|
6
|
+
require "easy_json_matcher/array_generator"
|
7
|
+
|
8
|
+
module EasyJSONMatcher
|
9
|
+
class NodeGenerator
|
10
|
+
include AttributeTypeMethods
|
11
|
+
|
12
|
+
attr_reader :validators, :attribute_opts, :node_opts, :array_opts, :global_opts
|
13
|
+
|
14
|
+
def initialize(opts: [], global_opts: [])
|
15
|
+
@validators = {}
|
16
|
+
@node_opts = extract_opts(local: opts, global: global_opts)
|
17
|
+
@global_opts = global_opts
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_node
|
21
|
+
strict = node_opts.delete(:strict)
|
22
|
+
Node.new(opts: node_opts, strict: strict, validators: validators)
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_attribute(key:, opts:)
|
26
|
+
validator = AttributeGenerator.new(local_opts: opts, global_opts: global_opts)
|
27
|
+
validators[key] = validator.generate_attribute
|
28
|
+
end
|
29
|
+
|
30
|
+
def contains_node(key:, opts: [])
|
31
|
+
generator = self.class.new(opts: opts, global_opts: global_opts)
|
32
|
+
yield generator if block_given?
|
33
|
+
validators[key] = generator.generate_node
|
34
|
+
end
|
35
|
+
|
36
|
+
def contains_array(key:, opts: [])
|
37
|
+
validator = ArrayGenerator.new(local_opts: opts, global_opts: global_opts)
|
38
|
+
yield validator if block_given?
|
39
|
+
validators[key] = validator.generate_array
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_schema(key:, name:)
|
43
|
+
schema = SchemaLibrary.get_schema(name: name)
|
44
|
+
validators[key] = schema
|
45
|
+
end
|
46
|
+
|
47
|
+
def extract_opts(local:, global:)
|
48
|
+
conflicts = { required: :not_required }
|
49
|
+
opts = global.map do |opt|
|
50
|
+
if conflicts.keys.include? opt
|
51
|
+
local.include?(conflicts[opt]) ? conflicts[opt] : opt
|
52
|
+
else
|
53
|
+
opt
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,104 +1,80 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require "easy_json_matcher/validation_chain_factory"
|
2
|
+
require "easy_json_matcher/node"
|
3
|
+
require "easy_json_matcher/schema_library"
|
4
|
+
require "easy_json_matcher/validator"
|
5
|
+
require "easy_json_matcher/attribute_type_methods"
|
6
|
+
require "easy_json_matcher/node_generator"
|
7
|
+
|
5
8
|
module EasyJSONMatcher
|
6
9
|
class SchemaGenerator
|
10
|
+
include AttributeTypeMethods
|
7
11
|
|
8
|
-
attr_reader :node, :
|
12
|
+
attr_reader :node, :glob_opts, :att_glob_opts
|
9
13
|
|
10
|
-
def initialize(opts:
|
11
|
-
@name = opts.delete(:key)
|
12
|
-
@options = opts
|
14
|
+
def initialize(opts: [], global_opts: [])
|
13
15
|
@glob_opts = global_opts
|
14
|
-
|
16
|
+
@att_glob_opts = glob_opts.dup
|
17
|
+
@att_glob_opts.delete(:strict)
|
18
|
+
@node = node_generator(opts: opts, globals: global_opts)
|
19
|
+
yield node if block_given?
|
15
20
|
end
|
16
21
|
|
17
|
-
def
|
18
|
-
|
22
|
+
def create_node(opts:)
|
23
|
+
Node.new(opts: opts)
|
19
24
|
end
|
20
25
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
node.add_validator generator.generate_schema
|
26
|
+
def has_attribute(key:, opts:)
|
27
|
+
opts = override_globals(local_opts: opts)
|
28
|
+
opts = opts - [:strict]
|
29
|
+
validator = ValidationChainFactory.get_chain(steps: opts)
|
30
|
+
node.add_validator key: key, validator: validator
|
27
31
|
end
|
28
32
|
|
29
|
-
|
30
|
-
|
33
|
+
# TODO pretty hacky but can be cleaned later
|
34
|
+
def override_globals(local_opts:)
|
35
|
+
if local_opts.include?(:not_required) && glob_opts.include?(:required)
|
36
|
+
(local_opts + (glob_opts - [:required]))
|
37
|
+
else
|
38
|
+
local_opts + glob_opts
|
39
|
+
end
|
31
40
|
end
|
32
41
|
|
33
|
-
|
34
|
-
has_attribute(key: key, opts: opts.merge({type: :number}))
|
35
|
-
end
|
36
|
-
|
37
|
-
def has_date(key:, opts: {})
|
38
|
-
has_attribute(key: key, opts: opts.merge({type: :date}))
|
39
|
-
end
|
40
|
-
|
41
|
-
def has_object(key:, opts: {})
|
42
|
-
has_attribute(key: key, opts: opts.merge({type: :object}))
|
43
|
-
end
|
44
|
-
|
45
|
-
def has_value(key:, opts: {})
|
46
|
-
has_attribute(key: key, opts: opts.merge({type: :value}))
|
47
|
-
end
|
42
|
+
################ Methods for adding specific attribute types ##############
|
48
43
|
|
49
|
-
def
|
50
|
-
|
44
|
+
def contains_node(key:, opts: [])
|
45
|
+
generator = node_generator(opts: opts)
|
46
|
+
yield generator if block_given?
|
47
|
+
node.add_validator key: key, validator: generator.node
|
51
48
|
end
|
52
49
|
|
53
|
-
def contains_array(key:, opts:
|
54
|
-
|
55
|
-
array_validator = _create_validator(key, opts)
|
50
|
+
def contains_array(key:, opts: [], with_content:)
|
51
|
+
array_validator = ArrayValidator.new opts: opts, verify_content_as: with_content
|
56
52
|
yield array_validator if block_given?
|
57
|
-
node.add_validator array_validator
|
53
|
+
node.add_validator key: key, validator: array_validator
|
58
54
|
end
|
59
55
|
|
60
|
-
def has_schema(key:,
|
61
|
-
|
56
|
+
def has_schema(key:, name:)
|
57
|
+
schema = SchemaLibrary.get_schema(name: name)
|
58
|
+
node.add_validator key: key, validator: schema
|
62
59
|
end
|
63
60
|
|
64
61
|
################ Methods for generating the schema #########################
|
65
62
|
|
63
|
+
def generate_node
|
64
|
+
node.generate_node
|
65
|
+
end
|
66
|
+
|
66
67
|
def generate_schema
|
67
|
-
|
68
|
+
Validator.new validate_with: generate_node
|
68
69
|
end
|
69
70
|
|
70
71
|
def register(as:)
|
71
|
-
SchemaLibrary.add_schema(name: as, schema:
|
72
|
+
SchemaLibrary.add_schema(name: as, schema: generate_node)
|
72
73
|
generate_schema
|
73
74
|
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
def _prep_schema_opts(schema_name, opts)
|
78
|
-
opts[:type] = :schema
|
79
|
-
opts[:name] = schema_name
|
80
|
-
opts
|
81
|
-
end
|
82
|
-
|
83
|
-
def _set_validator_key(validator, key)
|
84
|
-
validator.key = key
|
85
|
-
end
|
86
|
-
|
87
|
-
def _validator_opts(key, opts)
|
88
|
-
opts[:key] = key
|
89
|
-
glob_opts.merge(opts)
|
90
|
-
end
|
91
|
-
|
92
|
-
def _create_validator(key, opts)
|
93
|
-
ValidatorFactory.get_instance type: opts[:type], opts: _validator_opts(key, opts)
|
94
|
-
end
|
95
|
-
|
96
|
-
def _node_generator(opts = {})
|
97
|
-
self.class.new opts: opts, global_opts: glob_opts
|
98
|
-
end
|
99
|
-
|
100
|
-
def node
|
101
|
-
@node ||= Node.new(opts: _validator_opts(name, options))
|
76
|
+
def node_generator(opts:, globals:)
|
77
|
+
NodeGenerator.new(opts: opts, global_opts: globals)
|
102
78
|
end
|
103
79
|
end
|
104
80
|
end
|