schemacop 2.3.0 → 2.4.2
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 +5 -5
- data/CHANGELOG.md +41 -0
- data/LICENSE +1 -1
- data/README.md +204 -14
- data/RUBY_VERSION +1 -1
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/doc/Schemacop.html +32 -5
- data/doc/Schemacop/ArrayValidator.html +4 -4
- data/doc/Schemacop/BooleanValidator.html +4 -4
- data/doc/Schemacop/Caster.html +379 -0
- data/doc/Schemacop/Collector.html +180 -104
- data/doc/Schemacop/Exceptions.html +3 -3
- data/doc/Schemacop/Exceptions/InvalidSchemaError.html +3 -3
- data/doc/Schemacop/Exceptions/ValidationError.html +3 -3
- data/doc/Schemacop/FieldNode.html +19 -7
- data/doc/Schemacop/FloatValidator.html +4 -4
- data/doc/Schemacop/HashValidator.html +4 -4
- data/doc/Schemacop/IntegerValidator.html +4 -4
- data/doc/Schemacop/NilValidator.html +4 -4
- data/doc/Schemacop/Node.html +97 -85
- data/doc/Schemacop/NodeResolver.html +28 -12
- data/doc/Schemacop/NodeSupportingField.html +4 -4
- data/doc/Schemacop/NodeSupportingType.html +5 -7
- data/doc/Schemacop/NodeWithBlock.html +4 -4
- data/doc/Schemacop/NumberValidator.html +4 -4
- data/doc/Schemacop/ObjectValidator.html +3 -3
- data/doc/Schemacop/RootNode.html +4 -4
- data/doc/Schemacop/Schema.html +5 -5
- data/doc/Schemacop/StringValidator.html +3 -3
- data/doc/Schemacop/SymbolValidator.html +4 -4
- data/doc/ScopedEnv.html +3 -3
- data/doc/_index.html +11 -4
- data/doc/class_list.html +1 -1
- data/doc/css/style.css +10 -6
- data/doc/file.README.html +198 -16
- data/doc/frames.html +1 -1
- data/doc/index.html +198 -16
- data/doc/js/app.js +55 -0
- data/doc/method_list.html +81 -49
- data/doc/top-level-namespace.html +3 -3
- data/lib/schemacop.rb +14 -0
- data/lib/schemacop/caster.rb +38 -0
- data/lib/schemacop/collector.rb +34 -6
- data/lib/schemacop/field_node.rb +24 -3
- data/lib/schemacop/node.rb +16 -4
- data/lib/schemacop/node_resolver.rb +10 -2
- data/lib/schemacop/node_supporting_type.rb +19 -1
- data/lib/schemacop/schema.rb +2 -2
- data/lib/schemacop/validator/array_validator.rb +1 -1
- data/lib/schemacop/validator/float_validator.rb +1 -1
- data/lib/schemacop/validator/integer_validator.rb +1 -1
- data/lib/schemacop/validator/object_validator.rb +1 -1
- data/schemacop.gemspec +15 -9
- data/test/casting_test.rb +90 -0
- data/test/custom_check_test.rb +20 -13
- data/test/custom_if_test.rb +12 -12
- data/test/defaults_test.rb +71 -0
- data/test/nil_dis_allow_test.rb +6 -6
- data/test/node_resolver_test.rb +26 -0
- data/test/short_forms_test.rb +84 -66
- data/test/test_helper.rb +7 -0
- data/test/types_test.rb +5 -5
- data/test/validator_array_test.rb +16 -16
- data/test/validator_boolean_test.rb +2 -2
- data/test/validator_float_test.rb +15 -15
- data/test/validator_hash_test.rb +5 -5
- data/test/validator_integer_test.rb +9 -9
- data/test/validator_nil_test.rb +1 -1
- data/test/validator_number_test.rb +19 -19
- data/test/validator_object_test.rb +52 -18
- data/test/validator_string_test.rb +12 -12
- data/test/validator_symbol_test.rb +2 -2
- metadata +43 -14
@@ -0,0 +1,38 @@
|
|
1
|
+
module Schemacop
|
2
|
+
class Caster
|
3
|
+
def initialize(casts, data, target_type)
|
4
|
+
@casts = casts
|
5
|
+
@data = data
|
6
|
+
@target_type = target_type
|
7
|
+
@caster = nil
|
8
|
+
|
9
|
+
if casts.is_a?(Array)
|
10
|
+
from_types = casts
|
11
|
+
elsif casts.is_a?(Hash)
|
12
|
+
from_types = casts.keys
|
13
|
+
else
|
14
|
+
fail Exceptions::InvalidSchemaError, 'Option `cast` must be either an array or a hash.'
|
15
|
+
end
|
16
|
+
|
17
|
+
return unless from_types.include?(data.class)
|
18
|
+
|
19
|
+
if (casts.is_a?(Array) && casts.include?(data.class)) || casts[data.class] == :default
|
20
|
+
@caster = DEFAULT_CASTERS[data.class][target_type]
|
21
|
+
else
|
22
|
+
@caster = casts[data.class]
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def castable?
|
27
|
+
!@caster.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def cast
|
31
|
+
fail 'Not castable.' unless castable?
|
32
|
+
return @caster.call(@data)
|
33
|
+
rescue => e
|
34
|
+
fail Exceptions::InvalidSchemaError,
|
35
|
+
"Could not cast value #{@value.inspect} to #{@target_type}: #{e.message}."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/schemacop/collector.rb
CHANGED
@@ -1,12 +1,18 @@
|
|
1
1
|
module Schemacop
|
2
2
|
class Collector
|
3
|
-
attr_reader :current_path
|
4
3
|
attr_reader :exceptions
|
5
4
|
|
6
|
-
def initialize
|
5
|
+
def initialize(data)
|
7
6
|
@exceptions = []
|
8
7
|
@current_path = []
|
9
8
|
@ignore_next_segment = false
|
9
|
+
@current_datappoint_path = [data]
|
10
|
+
@current_index = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def data
|
14
|
+
return nil unless valid?
|
15
|
+
@current_datappoint_path.first
|
10
16
|
end
|
11
17
|
|
12
18
|
def valid?
|
@@ -14,20 +20,42 @@ module Schemacop
|
|
14
20
|
end
|
15
21
|
|
16
22
|
# Construct the current path
|
17
|
-
def path(segment)
|
23
|
+
def path(segment, index, type)
|
18
24
|
ignore_this_segment = false
|
25
|
+
|
26
|
+
previous_index = @current_index
|
27
|
+
|
19
28
|
if @ignore_next_segment
|
20
29
|
ignore_this_segment = true
|
21
30
|
@ignore_next_segment = false
|
31
|
+
else
|
32
|
+
unless @current_datappoint_path.last
|
33
|
+
if type == :hash
|
34
|
+
@current_datappoint_path[-1] = {}
|
35
|
+
else
|
36
|
+
@current_datappoint_path[-1] = []
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@current_path << segment unless ignore_this_segment
|
40
|
+
@current_datappoint_path << @current_datappoint_path.last[index]
|
41
|
+
@current_index = index
|
22
42
|
end
|
23
43
|
|
24
|
-
@current_path << segment unless ignore_this_segment
|
25
|
-
|
26
44
|
yield
|
27
45
|
ensure
|
46
|
+
@current_index = previous_index
|
47
|
+
@current_datappoint_path.pop unless ignore_this_segment
|
28
48
|
@current_path.pop unless ignore_this_segment
|
29
49
|
end
|
30
50
|
|
51
|
+
def override_value(value)
|
52
|
+
if @current_datappoint_path.size > 1
|
53
|
+
@current_datappoint_path[-2][@current_index] = value
|
54
|
+
else
|
55
|
+
@current_datappoint_path[0] = value
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
31
59
|
def exception_message
|
32
60
|
return "Schemacop validation failed:\n" + @exceptions.map do |e|
|
33
61
|
"- #{e[:path].join('')}: #{e[:message]}"
|
@@ -36,7 +64,7 @@ module Schemacop
|
|
36
64
|
|
37
65
|
def error(error_msg)
|
38
66
|
@exceptions << {
|
39
|
-
path: current_path.dup,
|
67
|
+
path: @current_path.dup,
|
40
68
|
message: error_msg
|
41
69
|
}
|
42
70
|
end
|
data/lib/schemacop/field_node.rb
CHANGED
@@ -16,11 +16,32 @@ module Schemacop
|
|
16
16
|
def validate(data, collector)
|
17
17
|
unless data.key?(name)
|
18
18
|
collector.error "Missing key #{name.inspect}." if @required
|
19
|
-
return
|
20
19
|
end
|
21
|
-
|
22
|
-
|
20
|
+
|
21
|
+
collector.path "/#{name}", name, :hash do
|
22
|
+
value, default_applied = apply_default!(data[name], collector)
|
23
|
+
|
24
|
+
unless data.key?(name) || default_applied
|
25
|
+
next
|
26
|
+
end
|
27
|
+
|
28
|
+
super(value, collector)
|
23
29
|
end
|
24
30
|
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def apply_default!(data, collector)
|
35
|
+
return data, false unless data.nil?
|
36
|
+
|
37
|
+
@types.each do |type|
|
38
|
+
next unless type.option?(:default)
|
39
|
+
default = type.option(:default)
|
40
|
+
collector.override_value(default)
|
41
|
+
return default, true
|
42
|
+
end
|
43
|
+
|
44
|
+
return nil, false
|
45
|
+
end
|
25
46
|
end
|
26
47
|
end
|
data/lib/schemacop/node.rb
CHANGED
@@ -17,6 +17,8 @@ module Schemacop
|
|
17
17
|
|
18
18
|
option :if
|
19
19
|
option :check
|
20
|
+
option :cast
|
21
|
+
option :default
|
20
22
|
|
21
23
|
def type_label
|
22
24
|
str = (symbols.first || 'unknown').to_s
|
@@ -40,8 +42,8 @@ module Schemacop
|
|
40
42
|
self.klasses = [].freeze
|
41
43
|
end
|
42
44
|
|
43
|
-
def self.register(symbols: [], klasses: [], clear: true)
|
44
|
-
NodeResolver.register(self)
|
45
|
+
def self.register(symbols: [], klasses: [], clear: true, before: nil)
|
46
|
+
NodeResolver.register(self, before: before)
|
45
47
|
symbols = [*symbols]
|
46
48
|
klasses = [*klasses]
|
47
49
|
if clear
|
@@ -80,6 +82,12 @@ module Schemacop
|
|
80
82
|
fail Exceptions::InvalidSchemaError,
|
81
83
|
"Unrecognized option(s) #{obsolete_opts.inspect} for #{self.class.inspect}, allowed options: #{self.class.allowed_options.keys.inspect}."
|
82
84
|
end
|
85
|
+
|
86
|
+
if option?(:cast) && self.class.klasses.size > 1
|
87
|
+
fail Exceptions::InvalidSchemaError,
|
88
|
+
"Casting is only allowed for single-value datatypes, but type #{self.class.inspect} has classes "\
|
89
|
+
"#{self.class.klasses.map(&:inspect)}."
|
90
|
+
end
|
83
91
|
end
|
84
92
|
|
85
93
|
def option(key)
|
@@ -119,8 +127,12 @@ module Schemacop
|
|
119
127
|
protected
|
120
128
|
|
121
129
|
def validate_custom_check(data, collector)
|
122
|
-
if option?(:check) &&
|
123
|
-
|
130
|
+
if option?(:check) && (check_result = option(:check).call(data)) != true
|
131
|
+
if check_result.is_a?(String)
|
132
|
+
collector.error "Custom :check failed: #{check_result}."
|
133
|
+
else
|
134
|
+
collector.error 'Custom :check failed.'
|
135
|
+
end
|
124
136
|
end
|
125
137
|
end
|
126
138
|
end
|
@@ -3,8 +3,16 @@ module Schemacop
|
|
3
3
|
class_attribute :node_classes
|
4
4
|
self.node_classes = [].freeze
|
5
5
|
|
6
|
-
def self.register(node_class)
|
7
|
-
|
6
|
+
def self.register(node_class, before: nil)
|
7
|
+
if before
|
8
|
+
unless (index = node_classes.find_index(before))
|
9
|
+
fail "Cannot insert before class #{before} which has not been registered yet."
|
10
|
+
end
|
11
|
+
|
12
|
+
node_classes.insert(index, node_class)
|
13
|
+
else
|
14
|
+
self.node_classes += [node_class]
|
15
|
+
end
|
8
16
|
end
|
9
17
|
|
10
18
|
def self.resolve(type)
|
@@ -93,13 +93,31 @@ module Schemacop
|
|
93
93
|
|
94
94
|
def validate(data, collector)
|
95
95
|
super
|
96
|
-
|
97
96
|
validate_types(data, collector)
|
98
97
|
end
|
99
98
|
|
100
99
|
protected
|
101
100
|
|
101
|
+
def cast!(data, collector)
|
102
|
+
@types.each do |type|
|
103
|
+
next unless type.option?(:cast) && !type.type_matches?(data) && type.type_filter_matches?(data)
|
104
|
+
caster = Caster.new(type.option(:cast), data, type.class.klasses.first)
|
105
|
+
|
106
|
+
next unless caster.castable?
|
107
|
+
begin
|
108
|
+
data = caster.cast
|
109
|
+
collector.override_value(data)
|
110
|
+
return data
|
111
|
+
rescue Exceptions::InvalidSchemaError => e
|
112
|
+
collector.error e.message
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
return data
|
117
|
+
end
|
118
|
+
|
102
119
|
def validate_types(data, collector)
|
120
|
+
data = cast!(data, collector)
|
103
121
|
unless (match = @types.find { |t| t.type_matches?(data) })
|
104
122
|
allowed_types = @types.map(&:type_label)
|
105
123
|
|
data/lib/schemacop/schema.rb
CHANGED
@@ -37,7 +37,7 @@ module Schemacop
|
|
37
37
|
# @return [Schemacop::Collector] The object that collected errors
|
38
38
|
# throughout the validation.
|
39
39
|
def validate(data)
|
40
|
-
collector = Collector.new
|
40
|
+
collector = Collector.new(data.deep_dup)
|
41
41
|
@root.fields[:root].validate({ root: data }, collector.ignore_next_segment)
|
42
42
|
return collector
|
43
43
|
end
|
@@ -55,7 +55,7 @@ module Schemacop
|
|
55
55
|
fail Exceptions::ValidationError, collector.exception_message
|
56
56
|
end
|
57
57
|
|
58
|
-
return
|
58
|
+
return collector.data
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -21,7 +21,7 @@ module Schemacop
|
|
21
21
|
collector.error "Array must have less (<=) than #{option(:max)} elements."
|
22
22
|
end
|
23
23
|
data.each_with_index do |entry, index|
|
24
|
-
collector.path("[#{index}]") do
|
24
|
+
collector.path("[#{index}]", index, :array) do
|
25
25
|
validate_types(entry, collector)
|
26
26
|
end
|
27
27
|
end
|
data/schemacop.gemspec
CHANGED
@@ -1,54 +1,60 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: schemacop 2.
|
2
|
+
# stub: schemacop 2.4.2 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "schemacop".freeze
|
6
|
-
s.version = "2.
|
6
|
+
s.version = "2.4.2"
|
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/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/Schemacop/SymbolValidator.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, "lib/schemacop/validator/symbol_validator.rb".freeze, "schemacop.gemspec".freeze, "test/collector_test.rb".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, "test/validator_symbol_test.rb".freeze]
|
11
|
+
s.date = "2019-11-05"
|
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/Caster.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/Schemacop/SymbolValidator.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/caster.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, "lib/schemacop/validator/symbol_validator.rb".freeze, "schemacop.gemspec".freeze, "test/casting_test.rb".freeze, "test/collector_test.rb".freeze, "test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/defaults_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/node_resolver_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, "test/validator_symbol_test.rb".freeze]
|
13
13
|
s.homepage = "https://github.com/sitrox/schemacop".freeze
|
14
14
|
s.licenses = ["MIT".freeze]
|
15
|
-
s.rubygems_version = "
|
15
|
+
s.rubygems_version = "3.0.3".freeze
|
16
16
|
s.summary = "Schemacop validates ruby structures consisting of nested hashes and arrays against simple schema definitions.".freeze
|
17
|
-
s.test_files = ["test/collector_test.rb".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, "test/validator_symbol_test.rb".freeze]
|
17
|
+
s.test_files = ["test/casting_test.rb".freeze, "test/collector_test.rb".freeze, "test/custom_check_test.rb".freeze, "test/custom_if_test.rb".freeze, "test/defaults_test.rb".freeze, "test/nil_dis_allow_test.rb".freeze, "test/node_resolver_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, "test/validator_symbol_test.rb".freeze]
|
18
18
|
|
19
19
|
if s.respond_to? :specification_version then
|
20
20
|
s.specification_version = 4
|
21
21
|
|
22
22
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
23
|
+
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
23
24
|
s.add_development_dependency(%q<bundler>.freeze, ["~> 1.3"])
|
24
25
|
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
25
26
|
s.add_development_dependency(%q<ci_reporter>.freeze, ["~> 2.0"])
|
26
27
|
s.add_development_dependency(%q<ci_reporter_minitest>.freeze, [">= 0"])
|
27
28
|
s.add_development_dependency(%q<haml>.freeze, [">= 0"])
|
29
|
+
s.add_development_dependency(%q<colorize>.freeze, [">= 0"])
|
28
30
|
s.add_development_dependency(%q<yard>.freeze, [">= 0"])
|
29
31
|
s.add_development_dependency(%q<rubocop>.freeze, ["= 0.35.1"])
|
30
32
|
s.add_development_dependency(%q<redcarpet>.freeze, [">= 0"])
|
31
|
-
s.
|
33
|
+
s.add_development_dependency(%q<pry>.freeze, [">= 0"])
|
32
34
|
else
|
35
|
+
s.add_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
33
36
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.3"])
|
34
37
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
35
38
|
s.add_dependency(%q<ci_reporter>.freeze, ["~> 2.0"])
|
36
39
|
s.add_dependency(%q<ci_reporter_minitest>.freeze, [">= 0"])
|
37
40
|
s.add_dependency(%q<haml>.freeze, [">= 0"])
|
41
|
+
s.add_dependency(%q<colorize>.freeze, [">= 0"])
|
38
42
|
s.add_dependency(%q<yard>.freeze, [">= 0"])
|
39
43
|
s.add_dependency(%q<rubocop>.freeze, ["= 0.35.1"])
|
40
44
|
s.add_dependency(%q<redcarpet>.freeze, [">= 0"])
|
41
|
-
s.add_dependency(%q<
|
45
|
+
s.add_dependency(%q<pry>.freeze, [">= 0"])
|
42
46
|
end
|
43
47
|
else
|
48
|
+
s.add_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
44
49
|
s.add_dependency(%q<bundler>.freeze, ["~> 1.3"])
|
45
50
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
46
51
|
s.add_dependency(%q<ci_reporter>.freeze, ["~> 2.0"])
|
47
52
|
s.add_dependency(%q<ci_reporter_minitest>.freeze, [">= 0"])
|
48
53
|
s.add_dependency(%q<haml>.freeze, [">= 0"])
|
54
|
+
s.add_dependency(%q<colorize>.freeze, [">= 0"])
|
49
55
|
s.add_dependency(%q<yard>.freeze, [">= 0"])
|
50
56
|
s.add_dependency(%q<rubocop>.freeze, ["= 0.35.1"])
|
51
57
|
s.add_dependency(%q<redcarpet>.freeze, [">= 0"])
|
52
|
-
s.add_dependency(%q<
|
58
|
+
s.add_dependency(%q<pry>.freeze, [">= 0"])
|
53
59
|
end
|
54
60
|
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Schemacop
|
4
|
+
class CastingTest < Minitest::Test
|
5
|
+
def test_basic
|
6
|
+
s = Schema.new :integer, cast: [String]
|
7
|
+
|
8
|
+
input = '42'
|
9
|
+
output = s.validate!(input)
|
10
|
+
|
11
|
+
assert_equal(42, output)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_field
|
15
|
+
s = Schema.new do
|
16
|
+
req :foo, :integer, cast: [String]
|
17
|
+
end
|
18
|
+
|
19
|
+
input = { foo: '42' }
|
20
|
+
output = s.validate!(input)
|
21
|
+
|
22
|
+
assert_equal({ foo: '42' }, input)
|
23
|
+
assert_equal({ foo: 42 }, output)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_first_type_matches
|
27
|
+
s = Schema.new do
|
28
|
+
type TrueClass
|
29
|
+
type :integer, cast: [String]
|
30
|
+
end
|
31
|
+
|
32
|
+
assert_equal(42, s.validate!('42'))
|
33
|
+
assert_equal(42, s.validate!(42))
|
34
|
+
assert_equal(true, s.validate!(true))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_with_if
|
38
|
+
s = Schema.new do
|
39
|
+
type Float, if: proc { |data| !data.is_a?(String) || data.match(/\d+\.\d+/) }, cast: [String]
|
40
|
+
type Integer, cast: [String]
|
41
|
+
end
|
42
|
+
|
43
|
+
assert_equal 42.2, s.validate!('42.2')
|
44
|
+
assert_equal 42, s.validate!('42')
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_arrays
|
48
|
+
s = Schema.new do
|
49
|
+
req :foo, :array, :integer, cast: [String]
|
50
|
+
end
|
51
|
+
|
52
|
+
assert_equal(
|
53
|
+
{ foo: [1, 2, 3] },
|
54
|
+
s.validate!(foo: %w(1 2 3))
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_check_after_cast
|
59
|
+
s = Schema.new do
|
60
|
+
type Integer, cast: [String], check: proc { |v| v > 41 }
|
61
|
+
end
|
62
|
+
|
63
|
+
assert_equal 42, s.validate!('42')
|
64
|
+
assert_equal 43, s.validate!('43')
|
65
|
+
assert_equal 42, s.validate!(42)
|
66
|
+
assert_verr { s.validate!('41') }
|
67
|
+
assert_verr { s.validate!(42.2) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_multilple_types
|
71
|
+
e = assert_raises Exceptions::InvalidSchemaError do
|
72
|
+
Schema.new do
|
73
|
+
type :number, cast: [String]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
assert_equal 'Casting is only allowed for single-value datatypes, '\
|
78
|
+
'but type Schemacop::NumberValidator has classes ["Integer", "Float"].',
|
79
|
+
e.message
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_custom_castings
|
83
|
+
s = Schema.new do
|
84
|
+
type :integer, cast: { String => proc { |v| Integer(v) } }
|
85
|
+
end
|
86
|
+
|
87
|
+
assert_equal 42, s.validate!('42')
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|