schemacop 3.0.0.rc0 → 3.0.0.rc5
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/.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
|