easy_json_matcher 0.2.2 → 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/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
@@ -2,34 +2,31 @@ module EasyJSONMatcher
|
|
2
2
|
class SchemaLibrary
|
3
3
|
|
4
4
|
SCHEMAS = {}
|
5
|
+
|
5
6
|
private_constant :SCHEMAS
|
7
|
+
|
6
8
|
class << self
|
9
|
+
|
7
10
|
def available_schemas
|
8
|
-
|
11
|
+
SCHEMAS.keys
|
9
12
|
end
|
10
13
|
|
11
14
|
def schema_for(name)
|
12
|
-
|
15
|
+
SCHEMAS[name]
|
13
16
|
end
|
14
17
|
|
15
18
|
def add_schema(name:, schema:)
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def schemas
|
20
|
-
SCHEMAS
|
19
|
+
SCHEMAS[name] = schema
|
21
20
|
end
|
22
21
|
|
23
22
|
def get_schema(name:, opts: {})
|
24
|
-
|
25
|
-
_set_schema_key(schema, opts.delete(:key))
|
23
|
+
schema = _find_and_clone_schema(name) or raise MissingSchemaException.new("No schema with #{name} has been registered")
|
26
24
|
schema
|
27
25
|
end
|
28
26
|
|
29
27
|
def _find_and_clone_schema(name)
|
30
28
|
s = SCHEMAS[name]
|
31
|
-
return s.dup if s
|
32
|
-
nil
|
29
|
+
return s.dup if s or nil
|
33
30
|
end
|
34
31
|
|
35
32
|
def _set_schema_key(schema, key)
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "easy_json_matcher/validation_step"
|
2
|
+
require "easy_json_matcher/unknown_validation_step_error"
|
3
|
+
require "easy_json_matcher/exceptions"
|
4
|
+
|
5
|
+
module EasyJSONMatcher
|
6
|
+
class ValidationChainFactory
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def get_chain(steps:, of: ValidationStep)
|
11
|
+
head = create_head_for(steps: steps, step_type: of)
|
12
|
+
assemble_chain(head: head, steps: steps, step_type: of)
|
13
|
+
head
|
14
|
+
end
|
15
|
+
|
16
|
+
def assemble_chain(head:, steps:, step_type:)
|
17
|
+
steps.inject(head) do |last_link, step|
|
18
|
+
last_link >> get_step_for(validating: step, using: step_type)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def create_head_for(steps:, step_type:)
|
23
|
+
is_required = steps.include?(:required)
|
24
|
+
get_step_for validating: is_required ? :required : :not_required, using: step_type
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_step_for(validating:, using: ValidationStep)
|
28
|
+
if validating.respond_to? :call
|
29
|
+
using.new verify_with: validating
|
30
|
+
elsif verifier = standard_validator(with: validating)
|
31
|
+
using.new verify_with: verifier
|
32
|
+
else
|
33
|
+
begin
|
34
|
+
return SchemaLibrary.get_schema(name: validating)
|
35
|
+
rescue MissingSchemaException => ex
|
36
|
+
#TODO this needs a little finesse: How will the user know if it was a missing schema?
|
37
|
+
raise UnknownValidationStepError.new(type: validating)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def standard_validator(with:)
|
43
|
+
require "easy_json_matcher/validation_rules"
|
44
|
+
VALIDATION_RULES[with]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module EasyJSONMatcher
|
2
|
+
|
3
|
+
VALIDATION_RULES = {
|
4
|
+
object: -> (value, errors) {
|
5
|
+
unless value.is_a? Hash
|
6
|
+
errors << "#{value} is not an Object"
|
7
|
+
return false
|
8
|
+
end
|
9
|
+
},
|
10
|
+
string: -> (value, errors) {
|
11
|
+
unless value.is_a? String
|
12
|
+
errors << "#{value} is not a String"
|
13
|
+
return false
|
14
|
+
end
|
15
|
+
},
|
16
|
+
number: -> (value, errors){
|
17
|
+
error_message = "#{value} is not a Number"
|
18
|
+
begin
|
19
|
+
Kernel::Float(value)
|
20
|
+
rescue ArgumentError, TypeError
|
21
|
+
errors << error_message
|
22
|
+
false
|
23
|
+
end
|
24
|
+
},
|
25
|
+
date: ->(value, errors){
|
26
|
+
require "date"
|
27
|
+
error_message = "#{value} is not a valid SQL date"
|
28
|
+
begin
|
29
|
+
Date.strptime(value,"%Y-%m-%d")
|
30
|
+
rescue ArgumentError, TypeError
|
31
|
+
errors << error_message
|
32
|
+
end
|
33
|
+
},
|
34
|
+
boolean: ->(value, errors){
|
35
|
+
clazz = value.class
|
36
|
+
unless (clazz == TrueClass) || (clazz == FalseClass)
|
37
|
+
errors << "#{value} is not a Boolean"
|
38
|
+
false
|
39
|
+
end
|
40
|
+
},
|
41
|
+
array: ->(value, errors){
|
42
|
+
unless value.is_a? Array
|
43
|
+
errors << "Value was not an array"
|
44
|
+
false
|
45
|
+
end
|
46
|
+
},
|
47
|
+
value: ->(value, errors){
|
48
|
+
# This is a bit of a toughie since value can be any value, including nil
|
49
|
+
},
|
50
|
+
not_required: ->(value, errors){
|
51
|
+
false if value.nil?
|
52
|
+
},
|
53
|
+
required: ->(value, errors){
|
54
|
+
errors << "no value found" and return false if value.nil?
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# The ValidationStep class represents a step in the process of validating a value. Each ValidationStep
|
2
|
+
# instance can be chained to another ValidationStep instance in order to produce a defined process for
|
3
|
+
# running validations within a given Validator. A use case for such a procedure is where a value is
|
4
|
+
# required and of a certain type. In this case the validation for required must precede the check for
|
5
|
+
# the type, and validation must cease if the value is nil.
|
6
|
+
module EasyJSONMatcher
|
7
|
+
class ValidationStep
|
8
|
+
|
9
|
+
attr_reader :next_step, :verifier
|
10
|
+
|
11
|
+
def initialize(verify_with:)
|
12
|
+
@verifier = verify_with
|
13
|
+
end
|
14
|
+
|
15
|
+
def check(value:)
|
16
|
+
errors = []
|
17
|
+
if verifier.call(value, errors) == false || is_tail?
|
18
|
+
errors
|
19
|
+
else
|
20
|
+
errors + next_step.check(value: value)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def >>(step)
|
25
|
+
@next_step = step
|
26
|
+
end
|
27
|
+
|
28
|
+
def concat(chain)
|
29
|
+
is_tail? ? self.>>(chain) : next_step.concat(chain)
|
30
|
+
end
|
31
|
+
|
32
|
+
def is_tail?
|
33
|
+
next_step.nil?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,102 +1,27 @@
|
|
1
|
+
require 'easy_json_matcher/json_coercer'
|
2
|
+
|
1
3
|
module EasyJSONMatcher
|
2
4
|
class Validator
|
3
5
|
|
4
|
-
attr_reader :
|
6
|
+
attr_reader :validation_chain, :coercer
|
5
7
|
attr_accessor :key
|
6
8
|
|
7
|
-
def initialize(
|
8
|
-
@
|
9
|
-
@
|
10
|
-
@custom_validator = options[:custom_validator]
|
11
|
-
@errors = []
|
12
|
-
_post_initialise(options)
|
9
|
+
def initialize(validate_with:, coerce_with: JsonCoercer.new)
|
10
|
+
@validation_chain = validate_with
|
11
|
+
@coercer = coerce_with
|
13
12
|
end
|
14
13
|
|
15
14
|
# Hook. Allows further setup to be carried out by subclasses
|
16
15
|
def _post_initialise(options); end
|
17
16
|
|
18
|
-
def valid?(candidate)
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
_set_content(candidate) #Hook
|
23
|
-
if content.nil?
|
24
|
-
_check_required?
|
25
|
-
else
|
26
|
-
_validate #Hook
|
27
|
-
end
|
28
|
-
_run_custom_validator if custom_validator
|
29
|
-
_no_errors?
|
30
|
-
end
|
31
|
-
|
32
|
-
# Hook. Overriden in Node
|
33
|
-
def reset!
|
34
|
-
errors.clear
|
35
|
-
end
|
36
|
-
|
37
|
-
# Hook
|
38
|
-
# Protected method that Validators use to implement their validation logic.
|
39
|
-
# Called by #valid?
|
40
|
-
def _validate
|
41
|
-
raise NotImplementedError.new "Validators must override _validate"
|
42
|
-
end
|
43
|
-
|
44
|
-
# Hook
|
45
|
-
# Protected method that Validators use to set their content from the candidate.
|
46
|
-
def _set_content(candidate)
|
47
|
-
@content = key ? candidate[key] : candidate
|
48
|
-
end
|
49
|
-
|
50
|
-
# Hook.
|
51
|
-
# This method returns the errors that this validator has found in the candidate.
|
52
|
-
def get_errors
|
53
|
-
error_message = {}
|
54
|
-
# Should the method just add errors even if there has been no error? Would
|
55
|
-
# avoid undefined method [] for nil:NilClass if you look for a key where
|
56
|
-
# there is no error but it would also make the output harder to read...
|
57
|
-
error_message[key.to_sym] = errors
|
58
|
-
error_message
|
59
|
-
end
|
60
|
-
|
61
|
-
# This method makees sure that the candidate behaves like a Hash, and not a
|
62
|
-
# value or an array.
|
63
|
-
def _check_content_type(candidate)
|
64
|
-
# TODO perhaps this should raise an error instead of returning false?
|
65
|
-
# if the value that has arrived at this point doesn't behave like a Hash then it
|
66
|
-
# is in the wrong place.
|
67
|
-
begin
|
68
|
-
candidate[key]
|
69
|
-
rescue TypeError
|
70
|
-
return false
|
71
|
-
end
|
72
|
-
true
|
73
|
-
end
|
74
|
-
|
75
|
-
def _check_required?
|
76
|
-
if required
|
77
|
-
errors << "Value was not present"
|
78
|
-
return true
|
79
|
-
else
|
80
|
-
return false
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def _create_validator(type:, opts: {})
|
85
|
-
ValidatorFactory.get_instance(type: type, opts: opts)
|
86
|
-
end
|
87
|
-
|
88
|
-
def _custom_validator?
|
89
|
-
custom_validator
|
90
|
-
end
|
91
|
-
|
92
|
-
def _run_custom_validator
|
93
|
-
if error_message = custom_validator.call(content)
|
94
|
-
errors << error_message
|
95
|
-
end
|
17
|
+
def valid?(candidate:)
|
18
|
+
errors = validate(candidate: candidate)
|
19
|
+
errors.empty?
|
96
20
|
end
|
97
21
|
|
98
|
-
def
|
99
|
-
|
22
|
+
def validate(candidate:)
|
23
|
+
candidate = coercer.coerce(json: candidate)
|
24
|
+
validation_chain.check(value: candidate)
|
100
25
|
end
|
101
26
|
end
|
102
27
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'easy_json_matcher'
|
2
|
+
|
3
|
+
module EasyJSONMatcher
|
4
|
+
class ValidatorSet
|
5
|
+
|
6
|
+
attr_accessor :validators, :strict
|
7
|
+
|
8
|
+
def initialize(validators:, strict: false)
|
9
|
+
@validators = validators
|
10
|
+
@strict = strict
|
11
|
+
end
|
12
|
+
|
13
|
+
def check(value:, errors:[])
|
14
|
+
error_hash = validators.each_with_object({}) do |k_v, errors_found|
|
15
|
+
key = k_v[0]
|
16
|
+
val = value[key]
|
17
|
+
validator = k_v[1]
|
18
|
+
results = validator.check(value: val)
|
19
|
+
errors_found[key] = results unless results.empty?
|
20
|
+
end
|
21
|
+
validate_strict_keyset(keys: validators.keys, candidates: value.keys, errors: error_hash) if strict
|
22
|
+
errors << error_hash unless error_hash.empty?
|
23
|
+
errors
|
24
|
+
end
|
25
|
+
|
26
|
+
def validate_strict_keyset(keys:, errors:, candidates:)
|
27
|
+
rogue_keys = candidates - keys
|
28
|
+
errors[:unexpected_keys] = "Unexpected keys: #{rogue_keys}" unless rogue_keys.empty?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/easy_json_matcher.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "easy_json_matcher/node"
|
2
|
+
require "easy_json_matcher/schema_generator"
|
3
|
+
require "easy_json_matcher/validator_set"
|
4
|
+
|
3
5
|
module EasyJSONMatcher
|
4
6
|
|
7
|
+
TYPES = [:number, :object, :value, :string, :boolean, :date, :array]
|
8
|
+
|
5
9
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "easy_json_matcher/array_content_validator"
|
3
|
+
|
4
|
+
module EasyJSONMatcher
|
5
|
+
describe ArrayContentValidator do
|
6
|
+
|
7
|
+
it "should check all the elements in an array" do
|
8
|
+
mock_values = (1..5).map do |n|
|
9
|
+
mock_val = Minitest::Mock.new
|
10
|
+
mock_val.expect(:hello, "hi")
|
11
|
+
end
|
12
|
+
subject = ArrayContentValidator.new( verify_with: ValidationStep.new(verify_with: ->(value, errors) { value.hello }))
|
13
|
+
subject.check value: mock_values
|
14
|
+
mock_values.each(&:verify)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,25 +1,25 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
3
|
+
module EasyJSONMatcher
|
4
4
|
|
5
|
-
|
6
|
-
test_schema = EasyJSONMatcher::SchemaGenerator.new do |s|
|
7
|
-
string_validator = ->(candidate) { "String did not say 'hi'" unless candidate == 'hi' }
|
8
|
-
s.has_string key: :a_string, opts: { custom_validator: string_validator }
|
9
|
-
end.generate_schema
|
5
|
+
describe "Custom Validations" do
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
subject {
|
8
|
+
SchemaGenerator.new { |sc|
|
9
|
+
sc.has_attribute key: :val,
|
10
|
+
opts: [
|
11
|
+
:required,
|
12
|
+
->(value, errors) { errors << "value was false" unless value === true }
|
13
|
+
]
|
14
|
+
}.generate_schema
|
15
|
+
}
|
14
16
|
|
15
|
-
|
17
|
+
it "should pass where val => true" do
|
18
|
+
subject.validate( candidate: { val: true }.to_json ).must_be :empty?
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
test_schema.reset!
|
22
|
-
|
23
|
-
assert(test_schema.valid?(should_validate), test_schema.get_errors)
|
21
|
+
it "should show an error where val => false" do
|
22
|
+
subject.validate( candidate: { val: false }.to_json ).wont_be :empty?
|
23
|
+
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,48 +1,43 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
implicitly_required_error = test_schema.get_errors[:implicitly_required][0]
|
43
|
-
nested_implicitly_required_error = test_schema.get_errors[:also_implicitly_required][:nested_implicitly_required][0]
|
44
|
-
error_message = /Value was not present/
|
45
|
-
assert_match(error_message, implicitly_required_error)
|
46
|
-
assert(nested_implicitly_required_error.nil?)
|
3
|
+
module EasyJSONMatcher
|
4
|
+
|
5
|
+
describe "Global Validation Options" do
|
6
|
+
|
7
|
+
|
8
|
+
subject {
|
9
|
+
SchemaGenerator.new(global_opts: [ :required ]) { |schema|
|
10
|
+
schema.has_boolean key: :implicitly_required
|
11
|
+
schema.contains_node key: :also_implicitly_required do |n|
|
12
|
+
n.has_boolean key: :nested_implicitly_required
|
13
|
+
n.has_boolean key: :not_required, opts: [:not_required]
|
14
|
+
end
|
15
|
+
}.generate_schema
|
16
|
+
}
|
17
|
+
|
18
|
+
let(:invalid_candidate){
|
19
|
+
{
|
20
|
+
also_implicitly_required: {
|
21
|
+
nested_implicitly_required: true
|
22
|
+
}
|
23
|
+
}.to_json
|
24
|
+
}
|
25
|
+
|
26
|
+
let(:valid_candidate){
|
27
|
+
{
|
28
|
+
implicitly_required: true,
|
29
|
+
also_implicitly_required: {
|
30
|
+
nested_implicitly_required: true
|
31
|
+
}
|
32
|
+
}.to_json
|
33
|
+
}
|
34
|
+
|
35
|
+
it "should only apply required to all implicitly required keys" do
|
36
|
+
subject.valid?(candidate: valid_candidate).must_be :===, true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should apply required to all implicitly required keys" do
|
40
|
+
subject.valid?(candidate: invalid_candidate).must_be :===, false
|
41
|
+
end
|
47
42
|
end
|
48
43
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
require "easy_json_matcher/json_coercer"
|
3
|
+
require "easy_json_matcher/coercion_error"
|
4
|
+
|
5
|
+
module EasyJSONMatcher
|
6
|
+
describe JsonCoercer do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@subject = JsonCoercer.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#coerce" do
|
13
|
+
|
14
|
+
it "should coerce a valid JSON string to a Hash" do
|
15
|
+
valid_json = { a: 1, b: 2, c: 3}.to_json
|
16
|
+
@subject.coerce(json: valid_json).must_be_instance_of Hash
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should raise a JSONFormatError if json: is an invalid JSON string" do
|
20
|
+
invalid_json = "123"
|
21
|
+
-> { @subject.coerce(json: invalid_json) }.must_raise CoercionError
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,68 +1,69 @@
|
|
1
|
-
require
|
1
|
+
require "test_helper"
|
2
|
+
require "easy_json_matcher/exceptions"
|
2
3
|
|
3
|
-
|
4
|
+
module EasyJSONMatcher
|
5
|
+
class ManagingSchemasTest < ActiveSupport::TestCase
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
test "As a user I want to be able to register a Schema so I can reuse it later" do
|
13
|
-
assert(EasyJSONMatcher::SchemaLibrary.available_schemas.include?(:test), ":test not found in available_nodes")
|
14
|
-
end
|
7
|
+
setup do
|
8
|
+
@name = :test
|
9
|
+
SchemaGenerator.new { |schema|
|
10
|
+
schema.has_attribute(key: :name, opts: [ :string, :required ])
|
11
|
+
}.register(as: @name)
|
12
|
+
end
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
}.to_json
|
14
|
+
test "As a user I want to be able to register a Schema so I can reuse it later" do
|
15
|
+
assert(SchemaLibrary.available_schemas.include?(:test), ":test not found in available_nodes")
|
16
|
+
end
|
20
17
|
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
test "As as user I want to reuse a saved schema" do
|
19
|
+
candidate = {
|
20
|
+
name: "Green Mandarin"
|
21
|
+
}.to_json
|
22
|
+
schema = Validator.new validate_with: SchemaLibrary.get_schema(name: @name)
|
23
|
+
assert(schema.valid?(candidate: candidate), "test_schema did not validate correctly")
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
26
|
+
test "SchemaLibrary should thrown a MissingSchemaException if an unregistered schema is requested" do
|
27
|
+
assert_raises(MissingSchemaException) do
|
28
|
+
SchemaLibrary.get_schema(name: "#{@name.to_s}-wibble")
|
29
|
+
end
|
28
30
|
end
|
29
|
-
end
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
32
|
+
test "As a user I want to reuse a schema within another schema" do
|
33
|
+
test_schema = SchemaGenerator.new { |s|
|
34
|
+
s.has_boolean key: :is_present, opts: [ :required ]
|
35
|
+
s.has_schema key: @name, name: @name
|
36
|
+
}.generate_schema
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
38
|
+
invalid_json = {
|
39
|
+
is_present: true,
|
40
|
+
}
|
40
41
|
|
41
|
-
|
42
|
+
# assert_not(test_schema.valid?(invalid_json), "#{invalid_json} should not have been valid as it does not include the saved schema")
|
42
43
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
44
|
+
valid_json = invalid_json.dup
|
45
|
+
valid_json.store(@name, {name: "Achilles Tang"})
|
46
|
+
valid_json = valid_json.to_json
|
47
|
+
assert(test_schema.valid?(candidate: valid_json), "Stored schema did not validate correctly")
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
50
|
+
test "It can validate JSON Schema payloads" do
|
51
|
+
SchemaGenerator.new { |country|
|
52
|
+
country.has_attribute key: :id, opts: [:number, :required]
|
53
|
+
country.contains_node(key: :attributes) do |atts|
|
54
|
+
atts.has_attribute key: :alpha_2, opts: [ :string, :required ]
|
55
|
+
atts.has_attribute key: :alpha_3, opts: [ :string, :required ]
|
56
|
+
atts.has_attribute key: :name, opts: [ :string, :required ]
|
57
|
+
end
|
58
|
+
}.register(as: :country)
|
58
59
|
|
59
|
-
|
60
|
-
|
61
|
-
|
60
|
+
country_payload = SchemaGenerator.new {|country_payload|
|
61
|
+
country_payload.has_schema(key: :data, name: :country)
|
62
|
+
}.register(as: :country_payload)
|
62
63
|
|
63
|
-
|
64
|
+
valid_json = "{\"data\":{\"id\":\"4376\",\"type\":\"countries\",\"attributes\":{\"alpha_2\":\"GB\",\"alpha_3\":\"GBR\",\"name\":\"United Kingdom of Great Britain and Northern Ireland\"}}}"
|
64
65
|
|
65
|
-
|
66
|
-
|
66
|
+
assert country_payload.valid?(candidate: valid_json)
|
67
|
+
end
|
67
68
|
end
|
68
69
|
end
|