schemacop 1.0.2 → 2.0.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/.gitignore +2 -1
- data/.rubocop.yml +59 -1
- data/CHANGELOG.md +10 -0
- data/README.md +389 -199
- data/Rakefile +2 -0
- data/VERSION +1 -1
- data/doc/Schemacop.html +41 -130
- data/doc/Schemacop/ArrayValidator.html +329 -0
- data/doc/Schemacop/BooleanValidator.html +145 -0
- data/doc/Schemacop/Collector.html +535 -0
- data/doc/Schemacop/Exceptions.html +39 -39
- data/doc/Schemacop/Exceptions/InvalidSchemaError.html +124 -0
- data/doc/Schemacop/Exceptions/ValidationError.html +124 -0
- data/doc/Schemacop/FieldNode.html +409 -0
- data/doc/Schemacop/FloatValidator.html +158 -0
- data/doc/Schemacop/HashValidator.html +263 -0
- data/doc/Schemacop/IntegerValidator.html +158 -0
- data/doc/Schemacop/NilValidator.html +145 -0
- data/doc/Schemacop/Node.html +1426 -0
- data/doc/Schemacop/NodeResolver.html +242 -0
- data/doc/Schemacop/NodeSupportingField.html +590 -0
- data/doc/Schemacop/NodeSupportingType.html +614 -0
- data/doc/Schemacop/NodeWithBlock.html +289 -0
- data/doc/Schemacop/NumberValidator.html +232 -0
- data/doc/Schemacop/ObjectValidator.html +288 -0
- data/doc/Schemacop/RootNode.html +171 -0
- data/doc/Schemacop/Schema.html +697 -0
- data/doc/Schemacop/StringValidator.html +295 -0
- data/doc/ScopedEnv.html +351 -0
- data/doc/_index.html +190 -47
- data/doc/class_list.html +24 -31
- data/doc/css/full_list.css +32 -31
- data/doc/css/style.css +244 -91
- data/doc/file.README.html +428 -232
- data/doc/file_list.html +26 -30
- data/doc/frames.html +7 -16
- data/doc/index.html +428 -232
- data/doc/inheritance.graphml +524 -0
- data/doc/inheritance.pdf +825 -0
- data/doc/js/app.js +106 -77
- data/doc/js/full_list.js +170 -135
- data/doc/method_list.html +494 -38
- data/doc/top-level-namespace.html +36 -36
- data/lib/schemacop.rb +22 -7
- data/lib/schemacop/collector.rb +34 -0
- data/lib/schemacop/exceptions.rb +2 -8
- data/lib/schemacop/field_node.rb +26 -0
- data/lib/schemacop/node.rb +127 -0
- data/lib/schemacop/node_resolver.rb +14 -0
- data/lib/schemacop/node_supporting_field.rb +62 -0
- data/lib/schemacop/node_supporting_type.rb +112 -0
- data/lib/schemacop/node_with_block.rb +16 -0
- data/lib/schemacop/root_node.rb +4 -0
- data/lib/schemacop/schema.rb +61 -0
- data/lib/schemacop/scoped_env.rb +18 -0
- data/lib/schemacop/validator/array_validator.rb +30 -0
- data/lib/schemacop/validator/boolean_validator.rb +5 -0
- data/lib/schemacop/validator/float_validator.rb +5 -0
- data/lib/schemacop/validator/hash_validator.rb +18 -0
- data/lib/schemacop/validator/integer_validator.rb +5 -0
- data/lib/schemacop/validator/nil_validator.rb +5 -0
- data/lib/schemacop/validator/number_validator.rb +19 -0
- data/lib/schemacop/validator/object_validator.rb +21 -0
- data/lib/schemacop/validator/string_validator.rb +37 -0
- data/schemacop.gemspec +7 -5
- data/test/custom_check_test.rb +86 -0
- data/test/custom_if_test.rb +95 -0
- data/test/nil_dis_allow_test.rb +41 -0
- data/test/short_forms_test.rb +316 -0
- data/test/test_helper.rb +6 -0
- data/test/types_test.rb +83 -0
- data/test/validator_array_test.rb +97 -0
- data/test/validator_boolean_test.rb +15 -0
- data/test/validator_float_test.rb +57 -0
- data/test/validator_hash_test.rb +71 -0
- data/test/validator_integer_test.rb +46 -0
- data/test/validator_nil_test.rb +13 -0
- data/test/validator_number_test.rb +60 -0
- data/test/validator_object_test.rb +87 -0
- data/test/validator_string_test.rb +76 -0
- metadata +78 -14
- data/doc/Schemacop/Exceptions/Base.html +0 -127
- data/doc/Schemacop/Exceptions/InvalidSchema.html +0 -141
- data/doc/Schemacop/Exceptions/Validation.html +0 -142
- data/doc/Schemacop/MethodValidation.html +0 -120
- data/doc/Schemacop/MethodValidation/ClassMethods.html +0 -196
- data/doc/Schemacop/Validator.html +0 -254
- data/lib/schemacop/validator.rb +0 -145
- data/test/schemacop_validator_test.rb +0 -257
@@ -0,0 +1,112 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class NodeSupportingType < NodeWithBlock
|
3
|
+
block_method :type
|
4
|
+
|
5
|
+
def self.build(options, &block)
|
6
|
+
new(nil, options, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(options = {}, &block)
|
10
|
+
super(options)
|
11
|
+
|
12
|
+
@types = []
|
13
|
+
exec_block(&block)
|
14
|
+
|
15
|
+
if @types.none?
|
16
|
+
fail Exceptions::InvalidSchemaError, 'Block must contain a type definition or not be given at all.' if block_given?
|
17
|
+
type :object
|
18
|
+
end
|
19
|
+
|
20
|
+
# if @types.none?
|
21
|
+
# super(options)
|
22
|
+
# exec_block(&block)
|
23
|
+
# if @types.none?
|
24
|
+
# fail Exceptions::InvalidSchemaError, 'Block must contain a type definition or not be given at all.' if block_given?
|
25
|
+
# end
|
26
|
+
# else
|
27
|
+
# super({})
|
28
|
+
# end
|
29
|
+
end
|
30
|
+
|
31
|
+
def exec_block(&block)
|
32
|
+
super
|
33
|
+
rescue NoMethodError
|
34
|
+
@types = []
|
35
|
+
type :hash, {}, &block
|
36
|
+
end
|
37
|
+
|
38
|
+
# required signature:
|
39
|
+
# First argument must be a type or an array of types
|
40
|
+
# Following arguments may be subtypes
|
41
|
+
# Last argument may be an options hash.
|
42
|
+
# Options and given block are passed to the last specified type.
|
43
|
+
# Not permitted to give subtypes / options / a block if an array of types is given.
|
44
|
+
#
|
45
|
+
# TODO: Probably change this method so that the 'rescue NoMethodError'
|
46
|
+
# happens in here directly and not in the constructor. This way we can
|
47
|
+
# always call 'type', even if we don't have one and the type is auto-guessed
|
48
|
+
# as it formerly was the case in the constructor.
|
49
|
+
def type(*args, &block)
|
50
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
51
|
+
types = [*args.shift]
|
52
|
+
subtypes = args
|
53
|
+
|
54
|
+
unless types.any?
|
55
|
+
fail Exceptions::InvalidSchemaError, 'At least one type must be given.'
|
56
|
+
end
|
57
|
+
|
58
|
+
if subtypes.any? && types.size > 1
|
59
|
+
fail Exceptions::InvalidSchemaError, "First given type can't be an array if subtypes are given."
|
60
|
+
end
|
61
|
+
|
62
|
+
if types.size > 1 && options.any?
|
63
|
+
fail Exceptions::InvalidSchemaError, 'No options can be specified if multiple types are given.'
|
64
|
+
end
|
65
|
+
|
66
|
+
types.each do |type|
|
67
|
+
klass = resolve_type_klass(type)
|
68
|
+
|
69
|
+
if subtypes.any?
|
70
|
+
unless klass <= NodeSupportingType
|
71
|
+
fail "Node #{klass} does not support subtypes."
|
72
|
+
end
|
73
|
+
|
74
|
+
child = klass.new do
|
75
|
+
self.type(*subtypes, options, &block)
|
76
|
+
end
|
77
|
+
|
78
|
+
# child = klass.build(options)
|
79
|
+
#
|
80
|
+
#
|
81
|
+
# child.type(*subtypes, &block)
|
82
|
+
else
|
83
|
+
if klass == ObjectValidator && type.is_a?(Class)
|
84
|
+
options[:classes] = type
|
85
|
+
end
|
86
|
+
|
87
|
+
child = klass.new(options, &block)
|
88
|
+
end
|
89
|
+
|
90
|
+
@types << child
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def validate(data, collector)
|
95
|
+
super
|
96
|
+
|
97
|
+
validate_types(data, collector)
|
98
|
+
end
|
99
|
+
|
100
|
+
protected
|
101
|
+
|
102
|
+
def validate_types(data, collector)
|
103
|
+
unless (match = @types.find { |t| t.type_matches?(data) })
|
104
|
+
allowed_types = @types.map(&:type_label)
|
105
|
+
|
106
|
+
collector.error "Data type not matching: #{data.class}, allowed types: #{allowed_types.join('; ')}"
|
107
|
+
return
|
108
|
+
end
|
109
|
+
match.validate(data, collector)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class NodeWithBlock < Node
|
3
|
+
class_attribute :block_methods
|
4
|
+
self.block_methods = [].freeze
|
5
|
+
|
6
|
+
def self.block_method(name)
|
7
|
+
self.block_methods += [name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def exec_block(&block)
|
11
|
+
return unless block_given?
|
12
|
+
se = ScopedEnv.new(self, self.class.block_methods)
|
13
|
+
se.instance_exec(&block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class Schema
|
3
|
+
# Create a new Schema
|
4
|
+
#
|
5
|
+
# For detailed usage, please refer to README.md in the root of this project.
|
6
|
+
#
|
7
|
+
# @param args [Array] An array of arguments to apply to the root node of the
|
8
|
+
# Schema.
|
9
|
+
# @param block A block with further Schema specification.
|
10
|
+
# @raise [Schemacop::Exceptions::InvalidSchemaError] If the Schema defined
|
11
|
+
# is invalid.
|
12
|
+
def initialize(*args, &block)
|
13
|
+
@root = HashValidator.new do
|
14
|
+
req :root, *args, &block
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Query data validity
|
19
|
+
#
|
20
|
+
# @param data The data to validate.
|
21
|
+
# @return [Boolean] True if the data is valid, false otherwise.
|
22
|
+
def valid?(data)
|
23
|
+
validate(data).valid?
|
24
|
+
end
|
25
|
+
|
26
|
+
# Query data validity
|
27
|
+
#
|
28
|
+
# @param data The data to validate.
|
29
|
+
# @return [Boolean] True if data is invalid, false otherwise.
|
30
|
+
def invalid?(data)
|
31
|
+
!valid?(data)
|
32
|
+
end
|
33
|
+
|
34
|
+
# Validate data for the defined Schema
|
35
|
+
#
|
36
|
+
# @param data The data to validate.
|
37
|
+
# @return [Schemacop::Collector] The object that collected errors
|
38
|
+
# throughout the validation.
|
39
|
+
def validate(data)
|
40
|
+
collector = Collector.new
|
41
|
+
@root.fields[:root].validate({ root: data }, collector)
|
42
|
+
return collector
|
43
|
+
end
|
44
|
+
|
45
|
+
# Validate data for the defined Schema
|
46
|
+
#
|
47
|
+
# @param data The data to validate.
|
48
|
+
# @raise [Schemacop::Exceptions::ValidationError] If the data is invalid,
|
49
|
+
# this exception is thrown.
|
50
|
+
# @return nil
|
51
|
+
def validate!(data)
|
52
|
+
collector = validate(data)
|
53
|
+
|
54
|
+
unless collector.valid?
|
55
|
+
fail Exceptions::ValidationError, collector.exception_message
|
56
|
+
end
|
57
|
+
|
58
|
+
return nil
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ScopedEnv
|
2
|
+
def initialize(delegation_object, methods)
|
3
|
+
@delegation_object = delegation_object
|
4
|
+
@methods = methods
|
5
|
+
end
|
6
|
+
|
7
|
+
def method_missing(symbol, *args, &block)
|
8
|
+
if @methods.include?(symbol)
|
9
|
+
@delegation_object.send(symbol, *args, &block)
|
10
|
+
else
|
11
|
+
super
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def respond_to_missing?(symbol, include_private = false)
|
16
|
+
@methods.include?(symbol) || super
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class ArrayValidator < NodeSupportingType
|
3
|
+
register symbols: :array, klasses: Array
|
4
|
+
|
5
|
+
option :min # Minimal number of elements
|
6
|
+
option :max # Maximal number of elements
|
7
|
+
option :nil # Whether to allow nil values
|
8
|
+
|
9
|
+
def initialize(*args)
|
10
|
+
super
|
11
|
+
type(:nil) if option(:nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate(data, collector)
|
15
|
+
validate_custom_check(data, collector)
|
16
|
+
|
17
|
+
if option?(:min) && data.size < option(:min)
|
18
|
+
collector.error "Array must have more (>=) than #{option(:min)} elements."
|
19
|
+
end
|
20
|
+
if option?(:max) && data.size > option(:max)
|
21
|
+
collector.error "Array must have less (<=) than #{option(:max)} elements."
|
22
|
+
end
|
23
|
+
data.each_with_index do |entry, index|
|
24
|
+
collector.path("[#{index}]") do
|
25
|
+
validate_types(entry, collector)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class HashValidator < NodeSupportingField
|
3
|
+
register symbols: :hash, klasses: Hash
|
4
|
+
|
5
|
+
def validate(data, collector)
|
6
|
+
super
|
7
|
+
|
8
|
+
allowed_fields = @fields.keys
|
9
|
+
obsolete_keys = data.keys - allowed_fields
|
10
|
+
|
11
|
+
collector.error "Obsolete keys: #{obsolete_keys.inspect}." if obsolete_keys.any?
|
12
|
+
|
13
|
+
@fields.values.each do |field|
|
14
|
+
field.validate(data, collector)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class NumberValidator < Node
|
3
|
+
register symbols: :number, klasses: [Integer, Float]
|
4
|
+
|
5
|
+
option :min
|
6
|
+
option :max
|
7
|
+
|
8
|
+
def validate(data, collector)
|
9
|
+
super
|
10
|
+
|
11
|
+
if option?(:min) && data < option(:min)
|
12
|
+
collector.error "Value must be >= #{option(:min)}."
|
13
|
+
end
|
14
|
+
if option?(:max) && data > option(:max)
|
15
|
+
collector.error "Value must be <= #{option(:max)}."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class ObjectValidator < Node
|
3
|
+
register symbols: :object, klasses: Object
|
4
|
+
|
5
|
+
option :classes
|
6
|
+
|
7
|
+
def type_label
|
8
|
+
"#{super} (#{classes.join(', ')})"
|
9
|
+
end
|
10
|
+
|
11
|
+
def type_matches?(data)
|
12
|
+
super && (classes.empty? || classes.include?(data.class)) && !data.nil?
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def classes
|
18
|
+
[*option(:classes)]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class StringValidator < Node
|
3
|
+
register symbols: :string, klasses: String
|
4
|
+
|
5
|
+
option :min
|
6
|
+
option :max
|
7
|
+
|
8
|
+
def initialize(options = {})
|
9
|
+
super(options)
|
10
|
+
|
11
|
+
validate_options!
|
12
|
+
end
|
13
|
+
|
14
|
+
def validate(data, collector)
|
15
|
+
super
|
16
|
+
|
17
|
+
if option?(:min) && data.size < option(:min)
|
18
|
+
collector.error "String must be longer (>=) than #{option(:min)} characters."
|
19
|
+
end
|
20
|
+
if option?(:max) && data.size > option(:max)
|
21
|
+
collector.error "String must be shorter (<=) than #{option(:max)} characters."
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def validate_options!
|
28
|
+
option_schema = Schema.new :integer, min: 0
|
29
|
+
|
30
|
+
if option?(:min) && option_schema.invalid?(option(:min))
|
31
|
+
fail Exceptions::InvalidSchemaError, 'String option :min must be an integer >= 0.'
|
32
|
+
elsif option?(:max) && option_schema.invalid?(option(:max))
|
33
|
+
fail Exceptions::InvalidSchemaError, 'String option :max must be an integer >= 0.'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/schemacop.gemspec
CHANGED
@@ -1,18 +1,20 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: schemacop
|
2
|
+
# stub: schemacop 2.0.0 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "schemacop".freeze
|
6
|
-
s.version = "
|
6
|
+
s.version = "2.0.0"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Sitrox".freeze]
|
11
|
-
s.date = "
|
12
|
-
s.files = [".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "doc/Schemacop.html".freeze, "doc/Schemacop/Exceptions.html".freeze, "doc/Schemacop/Exceptions/
|
11
|
+
s.date = "2017-05-15"
|
12
|
+
s.files = [".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, ".travis.yml".freeze, ".yardopts".freeze, "CHANGELOG.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "doc/Schemacop.html".freeze, "doc/Schemacop/ArrayValidator.html".freeze, "doc/Schemacop/BooleanValidator.html".freeze, "doc/Schemacop/Collector.html".freeze, "doc/Schemacop/Exceptions.html".freeze, "doc/Schemacop/Exceptions/InvalidSchemaError.html".freeze, "doc/Schemacop/Exceptions/ValidationError.html".freeze, "doc/Schemacop/FieldNode.html".freeze, "doc/Schemacop/FloatValidator.html".freeze, "doc/Schemacop/HashValidator.html".freeze, "doc/Schemacop/IntegerValidator.html".freeze, "doc/Schemacop/NilValidator.html".freeze, "doc/Schemacop/Node.html".freeze, "doc/Schemacop/NodeResolver.html".freeze, "doc/Schemacop/NodeSupportingField.html".freeze, "doc/Schemacop/NodeSupportingType.html".freeze, "doc/Schemacop/NodeWithBlock.html".freeze, "doc/Schemacop/NumberValidator.html".freeze, "doc/Schemacop/ObjectValidator.html".freeze, "doc/Schemacop/RootNode.html".freeze, "doc/Schemacop/Schema.html".freeze, "doc/Schemacop/StringValidator.html".freeze, "doc/ScopedEnv.html".freeze, "doc/_index.html".freeze, "doc/class_list.html".freeze, "doc/css/common.css".freeze, "doc/css/full_list.css".freeze, "doc/css/style.css".freeze, "doc/file.README.html".freeze, "doc/file_list.html".freeze, "doc/frames.html".freeze, "doc/index.html".freeze, "doc/inheritance.graphml".freeze, "doc/inheritance.pdf".freeze, "doc/js/app.js".freeze, "doc/js/full_list.js".freeze, "doc/js/jquery.js".freeze, "doc/method_list.html".freeze, "doc/top-level-namespace.html".freeze, "lib/schemacop.rb".freeze, "lib/schemacop/collector.rb".freeze, "lib/schemacop/exceptions.rb".freeze, "lib/schemacop/field_node.rb".freeze, "lib/schemacop/node.rb".freeze, "lib/schemacop/node_resolver.rb".freeze, "lib/schemacop/node_supporting_field.rb".freeze, "lib/schemacop/node_supporting_type.rb".freeze, "lib/schemacop/node_with_block.rb".freeze, "lib/schemacop/root_node.rb".freeze, "lib/schemacop/schema.rb".freeze, "lib/schemacop/scoped_env.rb".freeze, "lib/schemacop/validator/array_validator.rb".freeze, "lib/schemacop/validator/boolean_validator.rb".freeze, "lib/schemacop/validator/float_validator.rb".freeze, "lib/schemacop/validator/hash_validator.rb".freeze, "lib/schemacop/validator/integer_validator.rb".freeze, "lib/schemacop/validator/nil_validator.rb".freeze, "lib/schemacop/validator/number_validator.rb".freeze, "lib/schemacop/validator/object_validator.rb".freeze, "lib/schemacop/validator/string_validator.rb".freeze, "schemacop.gemspec".freeze, "test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/short_forms_test.rb".freeze, "test/test_helper.rb".freeze, "test/types_test.rb".freeze, "test/validator_array_test.rb".freeze, "test/validator_boolean_test.rb".freeze, "test/validator_float_test.rb".freeze, "test/validator_hash_test.rb".freeze, "test/validator_integer_test.rb".freeze, "test/validator_nil_test.rb".freeze, "test/validator_number_test.rb".freeze, "test/validator_object_test.rb".freeze, "test/validator_string_test.rb".freeze]
|
13
|
+
s.homepage = "https://github.com/sitrox/schemacop".freeze
|
14
|
+
s.licenses = ["MIT".freeze]
|
13
15
|
s.rubygems_version = "2.6.6".freeze
|
14
16
|
s.summary = "Schemacop validates ruby structures consisting of nested hashes and arrays against simple schema definitions.".freeze
|
15
|
-
s.test_files = ["test/
|
17
|
+
s.test_files = ["test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/short_forms_test.rb".freeze, "test/test_helper.rb".freeze, "test/types_test.rb".freeze, "test/validator_array_test.rb".freeze, "test/validator_boolean_test.rb".freeze, "test/validator_float_test.rb".freeze, "test/validator_hash_test.rb".freeze, "test/validator_integer_test.rb".freeze, "test/validator_nil_test.rb".freeze, "test/validator_number_test.rb".freeze, "test/validator_object_test.rb".freeze, "test/validator_string_test.rb".freeze]
|
16
18
|
|
17
19
|
if s.respond_to? :specification_version then
|
18
20
|
s.specification_version = 4
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Schemacop
|
4
|
+
class CustomCheckTest < Minitest::Test
|
5
|
+
def test_integer_check_short_form
|
6
|
+
s = Schema.new :integer, check: proc { |i| i.even? }
|
7
|
+
assert_nil s.validate!(2)
|
8
|
+
assert_nil s.validate!(-8)
|
9
|
+
assert_nil s.validate!(0)
|
10
|
+
assert_verr { s.validate!(1) }
|
11
|
+
assert_verr { s.validate!(-7) }
|
12
|
+
assert_verr { s.validate!(2.1) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_integer_check_with_lambda
|
16
|
+
s = Schema.new do
|
17
|
+
type :integer, check: ->(i) { i.even? }
|
18
|
+
end
|
19
|
+
|
20
|
+
assert_nil s.validate!(2)
|
21
|
+
assert_nil s.validate!(-8)
|
22
|
+
assert_nil s.validate!(0)
|
23
|
+
assert_verr { s.validate!(1) }
|
24
|
+
assert_verr { s.validate!(-7) }
|
25
|
+
assert_verr { s.validate!(2.1) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_in_type_dsl
|
29
|
+
s = Schema.new do
|
30
|
+
type :number, check: proc { |x| x == 42 }
|
31
|
+
end
|
32
|
+
assert_nil s.validate!(42)
|
33
|
+
assert_verr { s.validate!(42.1) }
|
34
|
+
assert_verr { s.validate!(0) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_with_array
|
38
|
+
s = Schema.new do
|
39
|
+
type :array, check: proc { |a| a.first == 1 } do
|
40
|
+
type :integer
|
41
|
+
end
|
42
|
+
end
|
43
|
+
assert_nil s.validate!([1, 2, 3])
|
44
|
+
assert_verr { s.validate!([2, 3, 4]) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_with_array_nested
|
48
|
+
s = Schema.new do
|
49
|
+
type :array, check: proc { |a| a.first == 4 } do
|
50
|
+
type :integer, check: proc { |i| i >= 2 }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
assert_nil s.validate!([4, 3, 2])
|
55
|
+
assert_verr { s.validate!([3, 2]) }
|
56
|
+
assert_verr { s.validate!([4, 1]) }
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_with_hash
|
60
|
+
s = Schema.new :hash, check: proc { |h| h.all? { |k, v| k == v } } do
|
61
|
+
opt 1, :integer
|
62
|
+
opt 'two', :string
|
63
|
+
end
|
64
|
+
assert_nil s.validate!(1 => 1, 'two' => 'two')
|
65
|
+
assert_verr { s.validate!(1 => 2, 'two' => 'two') }
|
66
|
+
assert_verr { s.validate!(1 => 1, 'two' => 'one') }
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_mixed_if_check
|
70
|
+
s = Schema.new do
|
71
|
+
req :first_name,
|
72
|
+
:string,
|
73
|
+
if: proc { |str| str.start_with?('Sand') },
|
74
|
+
check: proc { |str| str == 'Sandy' }
|
75
|
+
req :first_name, :string, min: 3
|
76
|
+
end
|
77
|
+
|
78
|
+
assert_nil s.validate!(first_name: 'Bob')
|
79
|
+
assert_nil s.validate!(first_name: 'Sandy')
|
80
|
+
assert_nil s.validate!(first_name: 'Sansibar')
|
81
|
+
|
82
|
+
assert_verr { s.validate!(first_name: 'Sandkasten') }
|
83
|
+
assert_verr { s.validate!(first_name: 'a') }
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|