schemacop 3.0.0.rc0 → 3.0.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.releaser_config +0 -1
- data/.travis.yml +1 -0
- data/CHANGELOG.md +34 -1
- data/README.md +13 -3
- data/README_V3.md +717 -147
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/lib/schemacop.rb +1 -0
- data/lib/schemacop/schema2.rb +2 -2
- data/lib/schemacop/scoped_env.rb +1 -1
- data/lib/schemacop/v2.rb +0 -1
- data/lib/schemacop/v2/caster.rb +1 -0
- data/lib/schemacop/v2/node_supporting_field.rb +25 -11
- data/lib/schemacop/v2/node_supporting_type.rb +2 -2
- data/lib/schemacop/v3/array_node.rb +1 -2
- data/lib/schemacop/v3/hash_node.rb +77 -27
- data/lib/schemacop/v3/node.rb +11 -6
- 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 +7 -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/all_of_node_test.rb +1 -2
- data/test/unit/schemacop/v3/any_of_node_test.rb +6 -6
- data/test/unit/schemacop/v3/array_node_test.rb +13 -3
- data/test/unit/schemacop/v3/global_context_test.rb +2 -0
- data/test/unit/schemacop/v3/hash_node_test.rb +211 -14
- data/test/unit/schemacop/v3/node_test.rb +14 -0
- data/test/unit/schemacop/v3/one_of_node_test.rb +6 -6
- data/test/unit/schemacop/v3/reference_node_test.rb +76 -60
- data/test/unit/schemacop/v3/string_node_test.rb +38 -0
- metadata +16 -3
- data/lib/schemacop/v2/root_node.rb +0 -6
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.rc5 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.rc5"
|
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-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, "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
|
@@ -21,6 +21,7 @@ Gem::Specification.new do |s|
|
|
21
21
|
|
22
22
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
23
23
|
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
24
|
+
s.add_runtime_dependency(%q<ruby2_keywords>.freeze, ["= 0.0.4"])
|
24
25
|
s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
|
25
26
|
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
26
27
|
s.add_development_dependency(%q<minitest>.freeze, [">= 0"])
|
@@ -32,6 +33,7 @@ Gem::Specification.new do |s|
|
|
32
33
|
s.add_development_dependency(%q<simplecov>.freeze, ["= 0.21.2"])
|
33
34
|
else
|
34
35
|
s.add_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
36
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, ["= 0.0.4"])
|
35
37
|
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
36
38
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
37
39
|
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
@@ -44,6 +46,7 @@ Gem::Specification.new do |s|
|
|
44
46
|
end
|
45
47
|
else
|
46
48
|
s.add_dependency(%q<activesupport>.freeze, [">= 4.0"])
|
49
|
+
s.add_dependency(%q<ruby2_keywords>.freeze, ["= 0.0.4"])
|
47
50
|
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
48
51
|
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
49
52
|
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
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
|
@@ -133,11 +133,11 @@ module Schemacop
|
|
133
133
|
|
134
134
|
assert_cast(
|
135
135
|
{ created_at: '2020-01-01' },
|
136
|
-
created_at: Date.new(2020, 1, 1)
|
136
|
+
{ created_at: Date.new(2020, 1, 1) }.with_indifferent_access
|
137
137
|
)
|
138
138
|
assert_cast(
|
139
139
|
{ created_at: '2020-01-01T17:38:20' },
|
140
|
-
created_at: DateTime.new(2020, 1, 1, 17, 38, 20)
|
140
|
+
{ created_at: DateTime.new(2020, 1, 1, 17, 38, 20) }.with_indifferent_access
|
141
141
|
)
|
142
142
|
end
|
143
143
|
|
@@ -158,12 +158,12 @@ module Schemacop
|
|
158
158
|
|
159
159
|
assert_cast(
|
160
160
|
{ foo: { bar: nil } },
|
161
|
-
foo: { bar: nil }
|
161
|
+
{ foo: { bar: nil } }.with_indifferent_access
|
162
162
|
)
|
163
163
|
|
164
164
|
assert_cast(
|
165
165
|
{ foo: { baz: nil } },
|
166
|
-
foo: { baz: 'Baz' }
|
166
|
+
{ foo: { baz: 'Baz' } }.with_indifferent_access
|
167
167
|
)
|
168
168
|
|
169
169
|
schema do
|
@@ -175,12 +175,12 @@ module Schemacop
|
|
175
175
|
|
176
176
|
assert_cast(
|
177
177
|
{ foo: { bar: '1990-01-13' } },
|
178
|
-
foo: { bar: Date.new(1990, 1, 13) }
|
178
|
+
{ foo: { bar: Date.new(1990, 1, 13) } }.with_indifferent_access
|
179
179
|
)
|
180
180
|
|
181
181
|
assert_cast(
|
182
182
|
{ foo: { bar: '1990-01-13T10:00:00Z' } },
|
183
|
-
foo: { bar: DateTime.new(1990, 1, 13, 10, 0, 0) }
|
183
|
+
{ foo: { bar: DateTime.new(1990, 1, 13, 10, 0, 0) } }.with_indifferent_access
|
184
184
|
)
|
185
185
|
end
|
186
186
|
|
@@ -446,8 +446,8 @@ module Schemacop
|
|
446
446
|
end
|
447
447
|
|
448
448
|
assert_cast(['foo', 42], ['foo', 42])
|
449
|
-
assert_cast(['foo', 42, { foo: '1990-01-01' }], ['foo', 42, { foo: Date.new(1990, 1, 1) }])
|
450
|
-
assert_cast(['foo', 42, { foo: '1990-01-01', bar: :baz }], ['foo', 42, { foo: Date.new(1990, 1, 1), bar: :baz }])
|
449
|
+
assert_cast(['foo', 42, { foo: '1990-01-01' }], ['foo', 42, { foo: Date.new(1990, 1, 1) }.with_indifferent_access])
|
450
|
+
assert_cast(['foo', 42, { foo: '1990-01-01', bar: :baz }], ['foo', 42, { foo: Date.new(1990, 1, 1), bar: :baz }.with_indifferent_access])
|
451
451
|
end
|
452
452
|
|
453
453
|
def test_multiple_add_in_schema
|
@@ -537,7 +537,7 @@ module Schemacop
|
|
537
537
|
additionalItems: false
|
538
538
|
)
|
539
539
|
|
540
|
-
assert_cast [{}], [{ name: 'John' }]
|
540
|
+
assert_cast [{}], [{ name: 'John' }.with_indifferent_access]
|
541
541
|
end
|
542
542
|
|
543
543
|
def test_enum_schema
|
@@ -800,6 +800,16 @@ module Schemacop
|
|
800
800
|
|
801
801
|
assert_cast(%w[foo 1990-01-01], ['foo', Date.new(1990, 1, 1)])
|
802
802
|
end
|
803
|
+
|
804
|
+
def test_contains_multiple_should_fail
|
805
|
+
assert_raises_with_message Exceptions::InvalidSchemaError, 'You can only use "cont" once.' do
|
806
|
+
schema :array do
|
807
|
+
list :string
|
808
|
+
cont :string
|
809
|
+
cont :integer
|
810
|
+
end
|
811
|
+
end
|
812
|
+
end
|
803
813
|
end
|
804
814
|
end
|
805
815
|
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({})
|
@@ -54,6 +65,14 @@ module Schemacop
|
|
54
65
|
type: :object,
|
55
66
|
additionalProperties: { type: :string }
|
56
67
|
)
|
68
|
+
|
69
|
+
assert_nothing_raised do
|
70
|
+
@schema.validate!({ foo: 'foo' })
|
71
|
+
end
|
72
|
+
|
73
|
+
assert_raises_with_message Exceptions::ValidationError, '/bar: Invalid type, expected "string".' do
|
74
|
+
@schema.validate!({ foo: 'foo', bar: :baz })
|
75
|
+
end
|
57
76
|
end
|
58
77
|
|
59
78
|
def test_property_names
|
@@ -61,6 +80,7 @@ module Schemacop
|
|
61
80
|
assert_validation({})
|
62
81
|
assert_validation(foo: :bar)
|
63
82
|
assert_validation('foo' => 'bar')
|
83
|
+
assert_validation(Foo: :bar)
|
64
84
|
assert_validation('_foo39sjfdoi 345893(%' => 'bar', 'foo' => 'bar') do
|
65
85
|
error '/', 'Property name "_foo39sjfdoi 345893(%" does not match "^[a-zA-Z0-9]+$".'
|
66
86
|
end
|
@@ -70,6 +90,24 @@ module Schemacop
|
|
70
90
|
additionalProperties: true,
|
71
91
|
propertyNames: '^[a-zA-Z0-9]+$'
|
72
92
|
)
|
93
|
+
|
94
|
+
assert_cast({ foo: 123 }, { foo: 123 }.with_indifferent_access)
|
95
|
+
assert_cast({ Foo: 123 }, { Foo: 123 }.with_indifferent_access)
|
96
|
+
|
97
|
+
# New schema
|
98
|
+
schema :hash, additional_properties: true, property_names: '^[a-z]+$'
|
99
|
+
|
100
|
+
assert_validation({})
|
101
|
+
assert_validation(foo: :bar)
|
102
|
+
assert_validation('foo' => 'bar')
|
103
|
+
assert_validation(Foo: :bar) do
|
104
|
+
error '/', 'Property name "Foo" does not match "^[a-z]+$".'
|
105
|
+
end
|
106
|
+
assert_validation('_foo39sjfdoi 345893(%' => 'bar', 'foo' => 'bar') do
|
107
|
+
error '/', 'Property name "_foo39sjfdoi 345893(%" does not match "^[a-z]+$".'
|
108
|
+
end
|
109
|
+
|
110
|
+
assert_cast({ foo: 123 }, { foo: 123 }.with_indifferent_access)
|
73
111
|
end
|
74
112
|
|
75
113
|
def test_required
|
@@ -254,6 +292,31 @@ module Schemacop
|
|
254
292
|
)
|
255
293
|
end
|
256
294
|
|
295
|
+
def test_pattern_properties_casting
|
296
|
+
schema do
|
297
|
+
int?(/^id_.*$/)
|
298
|
+
int?(/^val.*$/)
|
299
|
+
end
|
300
|
+
|
301
|
+
assert_json({
|
302
|
+
type: :object,
|
303
|
+
patternProperties: {
|
304
|
+
'^id_.*$': { type: :integer },
|
305
|
+
'^val.*$': { type: :integer }
|
306
|
+
},
|
307
|
+
additionalProperties: false
|
308
|
+
})
|
309
|
+
|
310
|
+
assert_validation({})
|
311
|
+
assert_validation({ id_foo: 1 })
|
312
|
+
assert_validation({ id_foo: 1, id_bar: 2 })
|
313
|
+
assert_validation({ id_foo: 1, id_bar: 2, value: 4 })
|
314
|
+
|
315
|
+
assert_cast({ id_foo: 1 }, { id_foo: 1 }.with_indifferent_access)
|
316
|
+
assert_cast({ id_foo: 1, id_bar: 2 }, { id_foo: 1, id_bar: 2 }.with_indifferent_access)
|
317
|
+
assert_cast({ id_foo: 1, id_bar: 2, value: 4 }, { id_foo: 1, id_bar: 2, value: 4 }.with_indifferent_access)
|
318
|
+
end
|
319
|
+
|
257
320
|
def test_defaults
|
258
321
|
schema do
|
259
322
|
str? :first_name, default: 'John'
|
@@ -267,7 +330,9 @@ module Schemacop
|
|
267
330
|
data = { last_name: 'Doeringer', active: 'true' }
|
268
331
|
data_was = data.dup
|
269
332
|
|
270
|
-
|
333
|
+
expected_data = { first_name: 'John', last_name: 'Doeringer', active: true, address: { street: 'Example 42' } }.with_indifferent_access
|
334
|
+
|
335
|
+
assert_equal(expected_data, @schema.validate(data).data)
|
271
336
|
assert_equal data_was, data
|
272
337
|
|
273
338
|
schema do
|
@@ -425,6 +490,13 @@ module Schemacop
|
|
425
490
|
validate_self_should_error((4 + 6i))
|
426
491
|
validate_self_should_error('13')
|
427
492
|
validate_self_should_error('Lorem ipsum')
|
493
|
+
|
494
|
+
# rubocop:disable Lint/BooleanSymbol
|
495
|
+
assert_raises_with_message Exceptions::InvalidSchemaError,
|
496
|
+
'Option "additional_properties" must be a boolean value' do
|
497
|
+
schema :hash, additional_properties: :true
|
498
|
+
end
|
499
|
+
# rubocop:enable Lint/BooleanSymbol
|
428
500
|
end
|
429
501
|
|
430
502
|
def test_doc_example
|
@@ -475,7 +547,7 @@ module Schemacop
|
|
475
547
|
|
476
548
|
assert_validation(nil)
|
477
549
|
assert_validation(foo: '1')
|
478
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
550
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
479
551
|
|
480
552
|
assert_validation(foo: '1', bar: '2') do
|
481
553
|
error '/', 'Obsolete property "bar".'
|
@@ -501,11 +573,11 @@ module Schemacop
|
|
501
573
|
|
502
574
|
assert_validation(nil)
|
503
575
|
assert_validation(foo: '1')
|
504
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
576
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
505
577
|
|
506
578
|
assert_validation(foo: '1', bar: nil)
|
507
579
|
assert_validation(foo: '1', bar: '2')
|
508
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
580
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
509
581
|
|
510
582
|
assert_json(
|
511
583
|
type: 'object',
|
@@ -538,11 +610,11 @@ module Schemacop
|
|
538
610
|
|
539
611
|
assert_validation(nil)
|
540
612
|
assert_validation(foo: '1')
|
541
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
613
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
542
614
|
|
543
615
|
assert_validation(foo: '1', bar: nil)
|
544
616
|
assert_validation(foo: '1', bar: '2')
|
545
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
617
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
546
618
|
|
547
619
|
assert_json(
|
548
620
|
type: 'object',
|
@@ -565,11 +637,11 @@ module Schemacop
|
|
565
637
|
|
566
638
|
assert_validation(nil)
|
567
639
|
assert_validation(foo: '1')
|
568
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
640
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
569
641
|
|
570
642
|
assert_validation(foo: '1', bar: nil)
|
571
643
|
assert_validation(foo: '1', bar: '2')
|
572
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 })
|
644
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 }.with_indifferent_access)
|
573
645
|
end
|
574
646
|
|
575
647
|
def test_cast_with_additional_any_of
|
@@ -583,7 +655,7 @@ module Schemacop
|
|
583
655
|
|
584
656
|
assert_validation(nil)
|
585
657
|
assert_validation(foo: '1')
|
586
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
658
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
587
659
|
|
588
660
|
assert_validation(foo: '1', bar: nil)
|
589
661
|
assert_validation(foo: '1', bar: '2')
|
@@ -592,7 +664,7 @@ module Schemacop
|
|
592
664
|
error '/qux', 'Does not match any anyOf condition.'
|
593
665
|
end
|
594
666
|
|
595
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
667
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
596
668
|
|
597
669
|
assert_json(
|
598
670
|
type: 'object',
|
@@ -624,7 +696,7 @@ module Schemacop
|
|
624
696
|
|
625
697
|
assert_validation(nil)
|
626
698
|
assert_validation(foo: '1')
|
627
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
699
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
628
700
|
|
629
701
|
assert_validation(foo: '1', bar: nil)
|
630
702
|
assert_validation(foo: '1', bar: '2')
|
@@ -633,8 +705,8 @@ module Schemacop
|
|
633
705
|
error '/qux', 'Does not match any anyOf condition.'
|
634
706
|
end
|
635
707
|
|
636
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 })
|
637
|
-
assert_cast({ foo: '1', bar: '2', qux: '2020-01-13', asd: 1 }, { foo: 1, bar: 2, qux: Date.new(2020, 1, 13), asd: 1 })
|
708
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 }.with_indifferent_access)
|
709
|
+
assert_cast({ foo: '1', bar: '2', qux: '2020-01-13', asd: 1 }, { foo: 1, bar: 2, qux: Date.new(2020, 1, 13), asd: 1 }.with_indifferent_access)
|
638
710
|
|
639
711
|
assert_json(
|
640
712
|
type: 'object',
|
@@ -770,6 +842,131 @@ module Schemacop
|
|
770
842
|
end
|
771
843
|
end
|
772
844
|
end
|
845
|
+
|
846
|
+
def test_schema_with_string_keys
|
847
|
+
schema :hash do
|
848
|
+
int! 'foo'
|
849
|
+
end
|
850
|
+
|
851
|
+
assert_validation(nil)
|
852
|
+
assert_validation({ 'foo' => 42 })
|
853
|
+
assert_validation({ foo: 42 })
|
854
|
+
|
855
|
+
assert_cast({ 'foo' => 42 }, { 'foo' => 42 })
|
856
|
+
assert_cast({ foo: 42 }, { foo: 42 }.with_indifferent_access)
|
857
|
+
|
858
|
+
assert_validation({}) do
|
859
|
+
error '/foo', 'Value must be given.'
|
860
|
+
end
|
861
|
+
|
862
|
+
assert_validation({ :foo => 42, 'foo' => 43 }) do
|
863
|
+
error '/', 'Has 1 ambiguous properties: [:foo].'
|
864
|
+
end
|
865
|
+
end
|
866
|
+
|
867
|
+
def test_schema_with_string_keys_in_data
|
868
|
+
schema :hash do
|
869
|
+
int! :foo
|
870
|
+
end
|
871
|
+
|
872
|
+
assert_validation(nil)
|
873
|
+
assert_validation({ 'foo' => 42 })
|
874
|
+
assert_validation({ foo: 42 })
|
875
|
+
|
876
|
+
assert_cast({ 'foo' => 42 }, { 'foo' => 42 })
|
877
|
+
assert_cast({ foo: 42 }, { foo: 42 }.with_indifferent_access)
|
878
|
+
|
879
|
+
assert_validation({}) do
|
880
|
+
error '/foo', 'Value must be given.'
|
881
|
+
end
|
882
|
+
|
883
|
+
assert_validation({ :foo => 42, 'foo' => 43 }) do
|
884
|
+
error '/', 'Has 1 ambiguous properties: [:foo].'
|
885
|
+
end
|
886
|
+
end
|
887
|
+
|
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
|
773
970
|
end
|
774
971
|
end
|
775
972
|
end
|