schemacop 3.0.0.rc3 → 3.0.0.rc4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README_V3.md +60 -4
- data/VERSION +1 -1
- data/lib/schemacop/v2/caster.rb +1 -0
- data/lib/schemacop/v3/hash_node.rb +23 -14
- data/lib/schemacop/v3/node.rb +2 -2
- data/lib/schemacop/v3/node_registry.rb +0 -4
- data/lib/schemacop/v3/reference_node.rb +7 -1
- data/lib/schemacop/v3/string_node.rb +15 -7
- data/schemacop.gemspec +4 -4
- data/test/lib/test_helper.rb +17 -2
- data/test/unit/schemacop/v2/casting_test.rb +37 -0
- data/test/unit/schemacop/v2/validator_hash_test.rb +11 -0
- data/test/unit/schemacop/v3/global_context_test.rb +2 -0
- data/test/unit/schemacop/v3/hash_node_test.rb +94 -6
- data/test/unit/schemacop/v3/node_test.rb +14 -0
- data/test/unit/schemacop/v3/reference_node_test.rb +16 -0
- data/test/unit/schemacop/v3/string_node_test.rb +38 -0
- metadata +8 -9
- data/lib/schemacop/v2/root_node.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d4b39e7b5e7391e8c5a8ff8ca7a1b008b19f1b62496e9a48e4180f7e953449d
|
4
|
+
data.tar.gz: 77bcf64925543433aad78dc02fbe610801db6a618cb1c8b154cea1a55c7220cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75030bf09dcbdc5f556e48aac4ac9b200713b3cb59c5a6dfa071bcb642e030638bc3de80a1969378b33c9c77ab5c0ca3f44866c2ce691e827b4067025ca89f0e
|
7
|
+
data.tar.gz: 54de1f2cac717dc6d8b4fcc89bdb679c7d7d528785a2a664bc9940061b1e5015bebd9827677bb581bc838f87ad62e0d54db87d13ce5ba0fa70ca44a37985e539
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,15 @@
|
|
10
10
|
### Changes
|
11
11
|
-->
|
12
12
|
|
13
|
+
## 3.0.0.rc4 (2020-02-02)
|
14
|
+
|
15
|
+
* Fix some minor bugs
|
16
|
+
|
17
|
+
* Improve documentation
|
18
|
+
|
19
|
+
* `used_external_schemas` for the `ReferenceNode` is now applied
|
20
|
+
recursively
|
21
|
+
|
13
22
|
## 3.0.0.rc3 (2020-01-28)
|
14
23
|
|
15
24
|
* Add minor improvements to the documentation
|
data/README_V3.md
CHANGED
@@ -90,7 +90,7 @@ Schemacop can raise the following exceptions:
|
|
90
90
|
Example:
|
91
91
|
|
92
92
|
```ruby
|
93
|
-
Schemacop::Schema3.new do
|
93
|
+
Schemacop::Schema3.new :hash do
|
94
94
|
int!
|
95
95
|
end
|
96
96
|
|
@@ -380,7 +380,7 @@ schema.validate!(1234) # => Schemacop::Exceptions::ValidationError: /: Invali
|
|
380
380
|
### Array
|
381
381
|
|
382
382
|
Type: `:array`\
|
383
|
-
DSL: `
|
383
|
+
DSL: `ary`
|
384
384
|
|
385
385
|
The array type represents a ruby `Array`.
|
386
386
|
It consists of one or multiple values, which can be validated using arbitrary nodes.
|
@@ -587,8 +587,9 @@ It consists of key-value-pairs that can be validated using arbitrary nodes.
|
|
587
587
|
|
588
588
|
* `additional_properties`
|
589
589
|
This option specifies whether additional, unspecified properties are allowed
|
590
|
-
(`true`) or not (`false`). By default, this is `
|
591
|
-
|
590
|
+
(`true`) or not (`false`). By default, this is `false`, i.e. you need to
|
591
|
+
explicitly set it to `true` if you want to allow arbitrary additional properties,
|
592
|
+
or use the `add` DSL method (see below) to specify additional properties.
|
592
593
|
|
593
594
|
* `property_names`
|
594
595
|
This option allows to specify a regexp pattern (as string) which validates the
|
@@ -673,6 +674,61 @@ end
|
|
673
674
|
schema.validate!(foo: 42, 'foo' => 43) # => Schemacop::Exceptions::ValidationError: /: Has 1 ambiguous properties: [:foo].
|
674
675
|
```
|
675
676
|
|
677
|
+
In addition to the normal node options (which vary from type to type, check
|
678
|
+
the respective nodes for details), properties also support the `as` option.
|
679
|
+
|
680
|
+
With this, you can "rename" properties in the output:
|
681
|
+
|
682
|
+
```ruby
|
683
|
+
schema = Schemacop::Schema3.new :hash do
|
684
|
+
int! :foo, as: :bar
|
685
|
+
end
|
686
|
+
|
687
|
+
schema.validate!({foo: 42}) # => {"bar"=>42}
|
688
|
+
```
|
689
|
+
|
690
|
+
Please note that if you specify a node with the same property name multiple
|
691
|
+
times, or use the `as` option to rename a node to the same name of another
|
692
|
+
node, the last specified node will be used:
|
693
|
+
|
694
|
+
```ruby
|
695
|
+
schema = Schemacop::Schema3.new :hash do
|
696
|
+
int? :foo
|
697
|
+
str? :foo
|
698
|
+
end
|
699
|
+
|
700
|
+
schema.validate!({foo: 1}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "string".
|
701
|
+
schema.validate!({foo: 'bar'}) # => {"foo"=>"bar"}
|
702
|
+
```
|
703
|
+
|
704
|
+
As well as:
|
705
|
+
|
706
|
+
```ruby
|
707
|
+
schema = Schemacop::Schema3.new :hash do
|
708
|
+
int? :foo
|
709
|
+
int? :bar, as: :foo
|
710
|
+
end
|
711
|
+
|
712
|
+
schema.validate!({foo: 1}) # => {"foo"=>1}
|
713
|
+
schema.validate!({foo: 1, bar: 2}) # => {"foo"=>2}
|
714
|
+
schema.validate!({bar: 2}) # => {"foo"=>2}
|
715
|
+
```
|
716
|
+
|
717
|
+
If you want to specify a node which may be one of multiple types, use the `one_of`
|
718
|
+
node (see further down for more details):
|
719
|
+
|
720
|
+
```ruby
|
721
|
+
schema = Schemacop::Schema3.new :hash do
|
722
|
+
one_of! :foo do
|
723
|
+
int
|
724
|
+
str
|
725
|
+
end
|
726
|
+
end
|
727
|
+
|
728
|
+
schema.validate!({foo: 1}) # => {"foo"=>1}
|
729
|
+
schema.validate!({foo: 'bar'}) # => {"foo"=>"bar"}
|
730
|
+
```
|
731
|
+
|
676
732
|
##### Pattern properties
|
677
733
|
|
678
734
|
In addition to symbols, property keys can also be a regular expression. Here,
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.0.
|
1
|
+
3.0.0.rc4
|
data/lib/schemacop/v2/caster.rb
CHANGED
@@ -68,7 +68,7 @@ module Schemacop
|
|
68
68
|
|
69
69
|
# In schemacop, by default, additional properties are not allowed,
|
70
70
|
# the users explicitly need to enable additional properties
|
71
|
-
if options[:additional_properties]
|
71
|
+
if options[:additional_properties].is_a?(TrueClass)
|
72
72
|
json[:additionalProperties] = true
|
73
73
|
elsif options[:additional_properties].is_a?(Node)
|
74
74
|
json[:additionalProperties] = options[:additional_properties].as_json
|
@@ -141,7 +141,9 @@ module Schemacop
|
|
141
141
|
result.error "Property name #{name.inspect} does not match #{options[:property_names].inspect}."
|
142
142
|
end
|
143
143
|
|
144
|
-
if options[:additional_properties].
|
144
|
+
if options[:additional_properties].is_a?(TrueClass)
|
145
|
+
next
|
146
|
+
elsif options[:additional_properties].is_a?(FalseClass) || options[:additional_properties].blank?
|
145
147
|
match = property_patterns.keys.find { |p| p.match?(name.to_s) }
|
146
148
|
if match
|
147
149
|
result.in_path(name) do
|
@@ -176,16 +178,10 @@ module Schemacop
|
|
176
178
|
data ||= default
|
177
179
|
return nil if data.nil?
|
178
180
|
|
179
|
-
|
180
|
-
data_hash = data.with_indifferent_access
|
181
|
-
|
182
|
-
if original_data_hash.size != data_hash.size
|
183
|
-
ambiguous_properties = original_data_hash.keys - data_hash.keys
|
184
|
-
|
185
|
-
result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}."
|
186
|
-
end
|
181
|
+
data_hash = data.dup.with_indifferent_access
|
187
182
|
|
188
183
|
property_patterns = {}
|
184
|
+
as_names = []
|
189
185
|
|
190
186
|
@properties.each_value do |prop|
|
191
187
|
if prop.name.is_a?(Regexp)
|
@@ -193,10 +189,18 @@ module Schemacop
|
|
193
189
|
next
|
194
190
|
end
|
195
191
|
|
196
|
-
|
192
|
+
as_names << prop.as&.to_s if prop.as.present?
|
197
193
|
|
198
|
-
|
199
|
-
|
194
|
+
prop_name = prop.as&.to_s || prop.name
|
195
|
+
|
196
|
+
casted_data = prop.cast(data_hash[prop.name])
|
197
|
+
|
198
|
+
if casted_data.present? || data_hash.include?(prop.name)
|
199
|
+
result[prop_name] = casted_data
|
200
|
+
end
|
201
|
+
|
202
|
+
if result[prop_name].nil? && !data_hash.include?(prop.name) && !as_names.include?(prop.name)
|
203
|
+
result.delete(prop_name)
|
200
204
|
end
|
201
205
|
end
|
202
206
|
|
@@ -213,7 +217,7 @@ module Schemacop
|
|
213
217
|
end
|
214
218
|
|
215
219
|
# Handle additional properties
|
216
|
-
if options[:additional_properties]
|
220
|
+
if options[:additional_properties].is_a?(TrueClass)
|
217
221
|
result = data_hash.merge(result)
|
218
222
|
elsif options[:additional_properties].is_a?(Node)
|
219
223
|
specified_properties = @properties.keys.to_set
|
@@ -238,6 +242,11 @@ module Schemacop
|
|
238
242
|
unless @options[:additional_properties].nil? || @options[:additional_properties].is_a?(TrueClass) || @options[:additional_properties].is_a?(FalseClass)
|
239
243
|
fail Schemacop::Exceptions::InvalidSchemaError, 'Option "additional_properties" must be a boolean value'
|
240
244
|
end
|
245
|
+
|
246
|
+
# Default the additional_properties option to false if it's not given
|
247
|
+
if @options[:additional_properties].nil?
|
248
|
+
@options[:additional_properties] = false
|
249
|
+
end
|
241
250
|
end
|
242
251
|
|
243
252
|
def validate_self
|
data/lib/schemacop/v3/node.rb
CHANGED
@@ -72,7 +72,7 @@ module Schemacop
|
|
72
72
|
disallowed_options = options.keys - self.class.allowed_options
|
73
73
|
|
74
74
|
if disallowed_options.any?
|
75
|
-
fail "Options #{disallowed_options.inspect} are not allowed for this node."
|
75
|
+
fail Schemacop::Exceptions::InvalidSchemaError, "Options #{disallowed_options.inspect} are not allowed for this node."
|
76
76
|
end
|
77
77
|
|
78
78
|
# Assign attributes #
|
@@ -95,7 +95,7 @@ module Schemacop
|
|
95
95
|
# Run DSL block #
|
96
96
|
if block_given?
|
97
97
|
unless self.class.supports_children_options
|
98
|
-
fail "Node #{self.class} does not support blocks."
|
98
|
+
fail Schemacop::Exceptions::InvalidSchemaError, "Node #{self.class} does not support blocks."
|
99
99
|
end
|
100
100
|
|
101
101
|
scope = DslScope.new(self)
|
@@ -36,7 +36,13 @@ module Schemacop
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def used_external_schemas
|
39
|
-
|
39
|
+
target_children_schema = target.used_external_schemas
|
40
|
+
|
41
|
+
if schemas.include?(@path)
|
42
|
+
return target_children_schema
|
43
|
+
else
|
44
|
+
return [@path] + target_children_schema
|
45
|
+
end
|
40
46
|
end
|
41
47
|
|
42
48
|
protected
|
@@ -66,21 +66,29 @@ module Schemacop
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def cast(value)
|
69
|
+
if value.present?
|
70
|
+
to_cast = value
|
71
|
+
elsif default.present?
|
72
|
+
to_cast = default
|
73
|
+
else
|
74
|
+
return nil
|
75
|
+
end
|
76
|
+
|
69
77
|
case options[:format]
|
70
78
|
when :boolean
|
71
|
-
return
|
79
|
+
return to_cast == 'true'
|
72
80
|
when :date
|
73
|
-
return Date.parse(
|
81
|
+
return Date.parse(to_cast)
|
74
82
|
when :'date-time'
|
75
|
-
return DateTime.parse(
|
83
|
+
return DateTime.parse(to_cast)
|
76
84
|
when :time
|
77
|
-
Time.parse(
|
85
|
+
Time.parse(to_cast)
|
78
86
|
when :integer
|
79
|
-
return Integer(
|
87
|
+
return Integer(to_cast)
|
80
88
|
when :number
|
81
|
-
return Float(
|
89
|
+
return Float(to_cast)
|
82
90
|
else
|
83
|
-
return
|
91
|
+
return to_cast
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
data/schemacop.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: schemacop 3.0.0.
|
2
|
+
# stub: schemacop 3.0.0.rc4 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "schemacop".freeze
|
6
|
-
s.version = "3.0.0.
|
6
|
+
s.version = "3.0.0.rc4"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Sitrox".freeze]
|
11
|
-
s.date = "2021-
|
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, "README_V2.md".freeze, "README_V3.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "lib/schemacop.rb".freeze, "lib/schemacop/base_schema.rb".freeze, "lib/schemacop/exceptions.rb".freeze, "lib/schemacop/railtie.rb".freeze, "lib/schemacop/schema.rb".freeze, "lib/schemacop/schema2.rb".freeze, "lib/schemacop/schema3.rb".freeze, "lib/schemacop/scoped_env.rb".freeze, "lib/schemacop/v2.rb".freeze, "lib/schemacop/v2/caster.rb".freeze, "lib/schemacop/v2/collector.rb".freeze, "lib/schemacop/v2/dupper.rb".freeze, "lib/schemacop/v2/field_node.rb".freeze, "lib/schemacop/v2/node.rb".freeze, "lib/schemacop/v2/node_resolver.rb".freeze, "lib/schemacop/v2/node_supporting_field.rb".freeze, "lib/schemacop/v2/node_supporting_type.rb".freeze, "lib/schemacop/v2/node_with_block.rb".freeze, "lib/schemacop/v2/
|
11
|
+
s.date = "2021-02-02"
|
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, "README_V2.md".freeze, "README_V3.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "lib/schemacop.rb".freeze, "lib/schemacop/base_schema.rb".freeze, "lib/schemacop/exceptions.rb".freeze, "lib/schemacop/railtie.rb".freeze, "lib/schemacop/schema.rb".freeze, "lib/schemacop/schema2.rb".freeze, "lib/schemacop/schema3.rb".freeze, "lib/schemacop/scoped_env.rb".freeze, "lib/schemacop/v2.rb".freeze, "lib/schemacop/v2/caster.rb".freeze, "lib/schemacop/v2/collector.rb".freeze, "lib/schemacop/v2/dupper.rb".freeze, "lib/schemacop/v2/field_node.rb".freeze, "lib/schemacop/v2/node.rb".freeze, "lib/schemacop/v2/node_resolver.rb".freeze, "lib/schemacop/v2/node_supporting_field.rb".freeze, "lib/schemacop/v2/node_supporting_type.rb".freeze, "lib/schemacop/v2/node_with_block.rb".freeze, "lib/schemacop/v2/validator/array_validator.rb".freeze, "lib/schemacop/v2/validator/boolean_validator.rb".freeze, "lib/schemacop/v2/validator/float_validator.rb".freeze, "lib/schemacop/v2/validator/hash_validator.rb".freeze, "lib/schemacop/v2/validator/integer_validator.rb".freeze, "lib/schemacop/v2/validator/nil_validator.rb".freeze, "lib/schemacop/v2/validator/number_validator.rb".freeze, "lib/schemacop/v2/validator/object_validator.rb".freeze, "lib/schemacop/v2/validator/string_validator.rb".freeze, "lib/schemacop/v2/validator/symbol_validator.rb".freeze, "lib/schemacop/v3.rb".freeze, "lib/schemacop/v3/all_of_node.rb".freeze, "lib/schemacop/v3/any_of_node.rb".freeze, "lib/schemacop/v3/array_node.rb".freeze, "lib/schemacop/v3/boolean_node.rb".freeze, "lib/schemacop/v3/combination_node.rb".freeze, "lib/schemacop/v3/context.rb".freeze, "lib/schemacop/v3/dsl_scope.rb".freeze, "lib/schemacop/v3/global_context.rb".freeze, "lib/schemacop/v3/hash_node.rb".freeze, "lib/schemacop/v3/integer_node.rb".freeze, "lib/schemacop/v3/is_not_node.rb".freeze, "lib/schemacop/v3/node.rb".freeze, "lib/schemacop/v3/node_registry.rb".freeze, "lib/schemacop/v3/number_node.rb".freeze, "lib/schemacop/v3/numeric_node.rb".freeze, "lib/schemacop/v3/object_node.rb".freeze, "lib/schemacop/v3/one_of_node.rb".freeze, "lib/schemacop/v3/reference_node.rb".freeze, "lib/schemacop/v3/result.rb".freeze, "lib/schemacop/v3/string_node.rb".freeze, "lib/schemacop/v3/symbol_node.rb".freeze, "schemacop.gemspec".freeze, "test/lib/test_helper.rb".freeze, "test/schemas/nested/group.rb".freeze, "test/schemas/user.rb".freeze, "test/unit/schemacop/v2/casting_test.rb".freeze, "test/unit/schemacop/v2/collector_test.rb".freeze, "test/unit/schemacop/v2/custom_check_test.rb".freeze, "test/unit/schemacop/v2/custom_if_test.rb".freeze, "test/unit/schemacop/v2/defaults_test.rb".freeze, "test/unit/schemacop/v2/empty_test.rb".freeze, "test/unit/schemacop/v2/nil_dis_allow_test.rb".freeze, "test/unit/schemacop/v2/node_resolver_test.rb".freeze, "test/unit/schemacop/v2/short_forms_test.rb".freeze, "test/unit/schemacop/v2/types_test.rb".freeze, "test/unit/schemacop/v2/validator_array_test.rb".freeze, "test/unit/schemacop/v2/validator_boolean_test.rb".freeze, "test/unit/schemacop/v2/validator_float_test.rb".freeze, "test/unit/schemacop/v2/validator_hash_test.rb".freeze, "test/unit/schemacop/v2/validator_integer_test.rb".freeze, "test/unit/schemacop/v2/validator_nil_test.rb".freeze, "test/unit/schemacop/v2/validator_number_test.rb".freeze, "test/unit/schemacop/v2/validator_object_test.rb".freeze, "test/unit/schemacop/v2/validator_string_test.rb".freeze, "test/unit/schemacop/v2/validator_symbol_test.rb".freeze, "test/unit/schemacop/v3/all_of_node_test.rb".freeze, "test/unit/schemacop/v3/any_of_node_test.rb".freeze, "test/unit/schemacop/v3/array_node_test.rb".freeze, "test/unit/schemacop/v3/boolean_node_test.rb".freeze, "test/unit/schemacop/v3/global_context_test.rb".freeze, "test/unit/schemacop/v3/hash_node_test.rb".freeze, "test/unit/schemacop/v3/integer_node_test.rb".freeze, "test/unit/schemacop/v3/is_not_node_test.rb".freeze, "test/unit/schemacop/v3/node_test.rb".freeze, "test/unit/schemacop/v3/number_node_test.rb".freeze, "test/unit/schemacop/v3/object_node_test.rb".freeze, "test/unit/schemacop/v3/one_of_node_test.rb".freeze, "test/unit/schemacop/v3/reference_node_test.rb".freeze, "test/unit/schemacop/v3/string_node_test.rb".freeze, "test/unit/schemacop/v3/symbol_node_test.rb".freeze]
|
13
13
|
s.homepage = "https://github.com/sitrox/schemacop".freeze
|
14
14
|
s.licenses = ["MIT".freeze]
|
15
15
|
s.rubygems_version = "3.0.3".freeze
|
data/test/lib/test_helper.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
require 'simplecov'
|
2
|
-
SimpleCov.start
|
2
|
+
SimpleCov.start do
|
3
|
+
add_group 'v3', 'lib/schemacop/v3'
|
4
|
+
add_group 'v2', 'lib/schemacop/v2'
|
5
|
+
|
6
|
+
# We don't care about the test coverage for the
|
7
|
+
# tests themselves
|
8
|
+
add_filter 'test'
|
9
|
+
|
10
|
+
# Also enable branch coverage reporting
|
11
|
+
enable_coverage :branch
|
12
|
+
end
|
3
13
|
|
4
14
|
# TODO: Move to more sensible location
|
5
15
|
def assert_verr(&block)
|
@@ -141,7 +151,12 @@ class V3Test < SchemacopTest
|
|
141
151
|
input_data_was = Marshal.load(Marshal.dump(input_data))
|
142
152
|
result = @schema.validate(input_data)
|
143
153
|
assert_empty result.errors
|
144
|
-
|
154
|
+
|
155
|
+
if expected_data.nil?
|
156
|
+
assert_nil result.data, 'Unexpected result data.'
|
157
|
+
else
|
158
|
+
assert_equal expected_data, result.data, 'Unexpected result data.'
|
159
|
+
end
|
145
160
|
|
146
161
|
if input_data.nil?
|
147
162
|
assert_nil input_data_was, 'Expected input_data to stay the same.'
|
@@ -115,6 +115,43 @@ module Schemacop
|
|
115
115
|
assert_equal expected_float, s.validate!(float_field: '')
|
116
116
|
assert_equal expected_float, s.validate!(float_field: ' ')
|
117
117
|
end
|
118
|
+
|
119
|
+
def test_float_to_integer
|
120
|
+
s = Schema.new do
|
121
|
+
req :foo, :integer, cast: [Float]
|
122
|
+
end
|
123
|
+
|
124
|
+
assert_equal({ foo: 42 }, s.validate!(foo: 42.0))
|
125
|
+
assert_equal({ foo: 42 }, s.validate!(foo: Float(42)))
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_integer_to_float
|
129
|
+
s = Schema.new do
|
130
|
+
req :foo, :float, cast: [Integer]
|
131
|
+
end
|
132
|
+
|
133
|
+
assert_equal({ foo: 42.0 }, s.validate!(foo: 42))
|
134
|
+
assert_equal({ foo: 42.0 }, s.validate!(foo: Integer(42)))
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_invalid_cast_option
|
138
|
+
s = Schema.new do
|
139
|
+
req :foo, :integer, cast: true
|
140
|
+
end
|
141
|
+
|
142
|
+
assert_raises Schemacop::Exceptions::InvalidSchemaError do
|
143
|
+
s.validate!({ foo: '42' })
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_impossible_cast
|
148
|
+
s = Schema.new do
|
149
|
+
req :foo, :integer, cast: [String]
|
150
|
+
end
|
151
|
+
|
152
|
+
assert_equal({ foo: 42 }, s.validate!(foo: '42'))
|
153
|
+
assert_verr { s.validate!(foo: 'foo') }
|
154
|
+
end
|
118
155
|
end
|
119
156
|
end
|
120
157
|
end
|
@@ -90,6 +90,17 @@ module Schemacop
|
|
90
90
|
assert_verr { s.validate!(o: true) }
|
91
91
|
assert_verr { s.validate!(r: nil, r_nil: false, o: true) }
|
92
92
|
end
|
93
|
+
|
94
|
+
def test_invalid_hash
|
95
|
+
s = Schema.new do
|
96
|
+
type :hash do
|
97
|
+
req :foo
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
assert_verr { s.validate!({ foo: 42, 'foo' => 42 }) }
|
102
|
+
assert_nothing_raised { s.validate!({ foo: 42 }.with_indifferent_access) }
|
103
|
+
end
|
93
104
|
end
|
94
105
|
end
|
95
106
|
end
|
@@ -25,8 +25,10 @@ module Schemacop
|
|
25
25
|
|
26
26
|
def test_schemas
|
27
27
|
assert_equal({}, GlobalContext.instance.schemas)
|
28
|
+
assert_equal({}, GlobalContext.schemas)
|
28
29
|
GlobalContext.instance.eager_load!
|
29
30
|
assert_equal(%i[nested/group user], GlobalContext.instance.schemas.keys)
|
31
|
+
assert_equal(%i[nested/group user], GlobalContext.schemas.keys)
|
30
32
|
assert_is_a Node, GlobalContext.instance.schemas.values.first
|
31
33
|
end
|
32
34
|
|
@@ -16,7 +16,7 @@ module Schemacop
|
|
16
16
|
assert_json(type: :object, additionalProperties: false)
|
17
17
|
end
|
18
18
|
|
19
|
-
def
|
19
|
+
def test_additional_properties_false_by_default
|
20
20
|
schema
|
21
21
|
assert_validation({})
|
22
22
|
assert_validation(foo: :bar, bar: :baz) do
|
@@ -26,6 +26,17 @@ module Schemacop
|
|
26
26
|
assert_json(type: :object, additionalProperties: false)
|
27
27
|
end
|
28
28
|
|
29
|
+
def test_additional_properties_false
|
30
|
+
schema :hash, additional_properties: false
|
31
|
+
|
32
|
+
assert_validation({})
|
33
|
+
assert_validation(foo: :bar, bar: :baz) do
|
34
|
+
error '/', 'Obsolete property "foo".'
|
35
|
+
error '/', 'Obsolete property "bar".'
|
36
|
+
end
|
37
|
+
assert_json(type: :object, additionalProperties: false)
|
38
|
+
end
|
39
|
+
|
29
40
|
def test_additional_properties_true
|
30
41
|
schema :hash, additional_properties: true
|
31
42
|
assert_validation({})
|
@@ -874,11 +885,88 @@ module Schemacop
|
|
874
885
|
end
|
875
886
|
end
|
876
887
|
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
888
|
+
def test_invalid_options
|
889
|
+
assert_raises_with_message Schemacop::Exceptions::InvalidSchemaError, 'Options [:foo] are not allowed for this node.' do
|
890
|
+
schema :hash, foo: 'bar' do
|
891
|
+
int! :id
|
892
|
+
end
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
def test_casting_optional
|
897
|
+
schema :hash do
|
898
|
+
str? :foo, format: :integer
|
899
|
+
end
|
900
|
+
|
901
|
+
assert_validation(nil)
|
902
|
+
assert_validation({})
|
903
|
+
|
904
|
+
assert_cast(nil, nil)
|
905
|
+
assert_cast({}, {}.with_indifferent_access)
|
906
|
+
end
|
907
|
+
|
908
|
+
def test_as_option
|
909
|
+
schema :hash do
|
910
|
+
int! :foo, as: :bar
|
911
|
+
end
|
912
|
+
|
913
|
+
assert_validation(nil)
|
914
|
+
assert_validation({ foo: 42 })
|
915
|
+
assert_validation({ bar: 13 }) do
|
916
|
+
error '/', 'Obsolete property "bar".'
|
917
|
+
error '/foo', 'Value must be given.'
|
918
|
+
end
|
919
|
+
|
920
|
+
assert_validation({ foo: '13' }) do
|
921
|
+
error '/foo', 'Invalid type, expected "integer".'
|
922
|
+
end
|
923
|
+
|
924
|
+
assert_cast(nil, nil)
|
925
|
+
assert_cast({ foo: 42 }, { bar: 42 }.with_indifferent_access)
|
926
|
+
end
|
927
|
+
|
928
|
+
def test_as_option_overriding
|
929
|
+
schema :hash do
|
930
|
+
int? :foo, as: :bar
|
931
|
+
int? :bar
|
932
|
+
end
|
933
|
+
|
934
|
+
assert_validation(nil)
|
935
|
+
assert_validation({})
|
936
|
+
assert_validation({ foo: 42 })
|
937
|
+
assert_validation({ foo: 42, bar: 13 })
|
938
|
+
|
939
|
+
assert_validation({ foo: '13' }) do
|
940
|
+
error '/foo', 'Invalid type, expected "integer".'
|
941
|
+
end
|
942
|
+
|
943
|
+
# assert_cast(nil, nil)
|
944
|
+
assert_cast({ foo: 42 }, { bar: 42 }.with_indifferent_access)
|
945
|
+
assert_cast({ foo: 42, bar: 13 }, { bar: 13 }.with_indifferent_access)
|
946
|
+
assert_cast({ bar: 13, foo: 42 }, { bar: 13 }.with_indifferent_access)
|
947
|
+
|
948
|
+
# Swap order
|
949
|
+
schema :hash do
|
950
|
+
int? :bar
|
951
|
+
int! :foo, as: :bar
|
952
|
+
end
|
953
|
+
|
954
|
+
assert_validation(nil)
|
955
|
+
assert_validation({ foo: 42 })
|
956
|
+
assert_validation({ foo: 42, bar: 13 })
|
957
|
+
assert_validation({ bar: 13 }) do
|
958
|
+
error '/foo', 'Value must be given.'
|
959
|
+
end
|
960
|
+
|
961
|
+
assert_validation({ foo: '13' }) do
|
962
|
+
error '/foo', 'Invalid type, expected "integer".'
|
963
|
+
end
|
964
|
+
|
965
|
+
assert_cast(nil, nil)
|
966
|
+
assert_cast({ foo: 42 }, { bar: 42 }.with_indifferent_access)
|
967
|
+
assert_cast({ foo: 42, bar: 13 }, { bar: 42 }.with_indifferent_access)
|
968
|
+
assert_cast({ bar: 13, foo: 42 }, { bar: 42 }.with_indifferent_access)
|
969
|
+
end
|
882
970
|
end
|
883
971
|
end
|
884
972
|
end
|
@@ -143,6 +143,20 @@ module Schemacop
|
|
143
143
|
error '/[0]', 'Value must be given.'
|
144
144
|
end
|
145
145
|
end
|
146
|
+
|
147
|
+
def test_not_support_block
|
148
|
+
assert_raises_with_message Schemacop::Exceptions::InvalidSchemaError, 'Node Schemacop::V3::IntegerNode does not support blocks.' do
|
149
|
+
schema :integer do
|
150
|
+
int :foo
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_node_no_children
|
156
|
+
@schema = Schemacop::Schema3.new
|
157
|
+
|
158
|
+
assert_equal(@schema.root.children, [])
|
159
|
+
end
|
146
160
|
end
|
147
161
|
end
|
148
162
|
end
|
@@ -249,6 +249,8 @@ module Schemacop
|
|
249
249
|
ref? :node, :Node
|
250
250
|
end
|
251
251
|
|
252
|
+
assert_equal(@schema.root.used_external_schemas, [])
|
253
|
+
|
252
254
|
assert_validation({})
|
253
255
|
assert_validation(node: { name: '1', children: [{ name: '1' }, { name: '2' }] })
|
254
256
|
assert_validation(
|
@@ -313,6 +315,8 @@ module Schemacop
|
|
313
315
|
ref! :person, :Person
|
314
316
|
end
|
315
317
|
|
318
|
+
assert_equal(@schema.root.used_external_schemas, %i[Person PersonInfo])
|
319
|
+
|
316
320
|
assert_validation(person: { first_name: 'John', last_name: 'Doe' })
|
317
321
|
assert_validation(person: { first_name: 'John', last_name: 'Doe', info: { born_at: '1990-01-13' } })
|
318
322
|
assert_validation(person: { first_name_x: 'John', last_name: 'Doe' }) do
|
@@ -323,6 +327,18 @@ module Schemacop
|
|
323
327
|
error '/person/info/born_at', 'String does not match format "date".'
|
324
328
|
end
|
325
329
|
end
|
330
|
+
|
331
|
+
with_context context do
|
332
|
+
schema do
|
333
|
+
scm :PersonNode do
|
334
|
+
ref! :person, :Person
|
335
|
+
end
|
336
|
+
|
337
|
+
ref! :personNode, :PersonNode
|
338
|
+
end
|
339
|
+
|
340
|
+
assert_equal(@schema.root.used_external_schemas, %i[Person PersonInfo])
|
341
|
+
end
|
326
342
|
end
|
327
343
|
|
328
344
|
def test_defaults
|
@@ -111,6 +111,9 @@ module Schemacop
|
|
111
111
|
assert_validation 'foo 2020-01-29 bar' do
|
112
112
|
error '/', 'String does not match format "date".'
|
113
113
|
end
|
114
|
+
|
115
|
+
assert_cast(nil, nil)
|
116
|
+
assert_cast('2020-01-13', Date.new(2020, 1, 13))
|
114
117
|
end
|
115
118
|
|
116
119
|
def test_format_date_time
|
@@ -132,6 +135,9 @@ module Schemacop
|
|
132
135
|
assert_validation '2018-11-13T20:20:39Y' do
|
133
136
|
error '/', 'String does not match format "date-time".'
|
134
137
|
end
|
138
|
+
|
139
|
+
assert_cast(nil, nil)
|
140
|
+
assert_cast('2018-11-13T20:20:39+00:00', DateTime.new(2018, 11, 13, 20, 20, 39))
|
135
141
|
end
|
136
142
|
|
137
143
|
def test_format_email
|
@@ -154,6 +160,9 @@ module Schemacop
|
|
154
160
|
assert_validation '@john@example.com' do
|
155
161
|
error '/', 'String does not match format "email".'
|
156
162
|
end
|
163
|
+
|
164
|
+
assert_cast(nil, nil)
|
165
|
+
assert_cast('john.doe@example.com', 'john.doe@example.com')
|
157
166
|
end
|
158
167
|
|
159
168
|
def test_enum
|
@@ -187,18 +196,24 @@ module Schemacop
|
|
187
196
|
|
188
197
|
assert_cast 'true', true
|
189
198
|
assert_cast 'false', false
|
199
|
+
|
200
|
+
assert_cast nil, nil
|
190
201
|
end
|
191
202
|
|
192
203
|
def test_time_casting
|
193
204
|
schema :string, format: :time
|
194
205
|
assert_json(type: :string, format: :time)
|
195
206
|
assert_cast '20:30:39+00:00', Time.strptime('20:30:39+00:00', '%H:%M:%S%z')
|
207
|
+
|
208
|
+
assert_cast nil, nil
|
196
209
|
end
|
197
210
|
|
198
211
|
def test_date_casting
|
199
212
|
schema :string, format: :date
|
200
213
|
assert_json(type: :string, format: :date)
|
201
214
|
assert_cast '2018-11-13', Date.new(2018, 11, 13)
|
215
|
+
|
216
|
+
assert_cast nil, nil
|
202
217
|
end
|
203
218
|
|
204
219
|
def test_date_time_casting
|
@@ -207,12 +222,16 @@ module Schemacop
|
|
207
222
|
assert_cast '2018-11-13T20:20:39+00:00', DateTime.new(2018, 11, 13, 20, 20, 39)
|
208
223
|
assert_cast '2018-11-13T20:20:39Z', DateTime.new(2018, 11, 13, 20, 20, 39)
|
209
224
|
assert_cast '2018-11-13T20:20:39+01:00', DateTime.new(2018, 11, 13, 20, 20, 39, '+1')
|
225
|
+
|
226
|
+
assert_cast nil, nil
|
210
227
|
end
|
211
228
|
|
212
229
|
def test_email_casting
|
213
230
|
schema :string, format: :email
|
214
231
|
assert_json(type: :string, format: :email)
|
215
232
|
assert_cast 'support@example.com', 'support@example.com'
|
233
|
+
|
234
|
+
assert_cast nil, nil
|
216
235
|
end
|
217
236
|
|
218
237
|
def test_default
|
@@ -233,6 +252,25 @@ module Schemacop
|
|
233
252
|
assert_cast(nil, 'Hello')
|
234
253
|
end
|
235
254
|
|
255
|
+
def test_default_casting
|
256
|
+
schema :string, format: :integer, default: '42'
|
257
|
+
|
258
|
+
assert_json(
|
259
|
+
type: :string,
|
260
|
+
format: :integer,
|
261
|
+
default: '42'
|
262
|
+
)
|
263
|
+
|
264
|
+
assert_validation(nil)
|
265
|
+
assert_validation('123')
|
266
|
+
assert_validation(5) do
|
267
|
+
error '/', 'Invalid type, expected "string".'
|
268
|
+
end
|
269
|
+
|
270
|
+
assert_cast('123', 123)
|
271
|
+
assert_cast(nil, 42)
|
272
|
+
end
|
273
|
+
|
236
274
|
# Helper function that checks for all the options if the option is
|
237
275
|
# an integer or something else, in which case it needs to raise
|
238
276
|
def validate_self_should_error(value_to_check)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: schemacop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.
|
4
|
+
version: 3.0.0.rc4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sitrox
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-02-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -150,8 +150,8 @@ dependencies:
|
|
150
150
|
- - '='
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: 0.21.2
|
153
|
-
description:
|
154
|
-
email:
|
153
|
+
description:
|
154
|
+
email:
|
155
155
|
executables: []
|
156
156
|
extensions: []
|
157
157
|
extra_rdoc_files: []
|
@@ -188,7 +188,6 @@ files:
|
|
188
188
|
- lib/schemacop/v2/node_supporting_field.rb
|
189
189
|
- lib/schemacop/v2/node_supporting_type.rb
|
190
190
|
- lib/schemacop/v2/node_with_block.rb
|
191
|
-
- lib/schemacop/v2/root_node.rb
|
192
191
|
- lib/schemacop/v2/validator/array_validator.rb
|
193
192
|
- lib/schemacop/v2/validator/boolean_validator.rb
|
194
193
|
- lib/schemacop/v2/validator/float_validator.rb
|
@@ -264,7 +263,7 @@ homepage: https://github.com/sitrox/schemacop
|
|
264
263
|
licenses:
|
265
264
|
- MIT
|
266
265
|
metadata: {}
|
267
|
-
post_install_message:
|
266
|
+
post_install_message:
|
268
267
|
rdoc_options: []
|
269
268
|
require_paths:
|
270
269
|
- lib
|
@@ -279,8 +278,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
279
278
|
- !ruby/object:Gem::Version
|
280
279
|
version: 1.3.1
|
281
280
|
requirements: []
|
282
|
-
rubygems_version: 3.
|
283
|
-
signing_key:
|
281
|
+
rubygems_version: 3.0.3
|
282
|
+
signing_key:
|
284
283
|
specification_version: 4
|
285
284
|
summary: Schemacop validates ruby structures consisting of nested hashes and arrays
|
286
285
|
against simple schema definitions.
|
File without changes
|