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.
data/schemacop.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: schemacop 3.0.0.rc0 ruby lib
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.rc0"
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-01-14"
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/root_node.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]
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"])
@@ -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
- assert_equal expected_data, result.data, 'Unexpected result data.'
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
@@ -142,8 +142,7 @@ module Schemacop
142
142
 
143
143
  assert_cast(
144
144
  { foo: '42', bar: '2020-01-15' },
145
- foo: 42,
146
- bar: Date.new(2020, 1, 15)
145
+ { foo: 42, bar: Date.new(2020, 1, 15) }.with_indifferent_access
147
146
  )
148
147
  end
149
148
 
@@ -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 test_additional_properties_false
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
- assert_equal({ first_name: 'John', last_name: 'Doeringer', active: true, address: { street: 'Example 42' } }, @schema.validate(data).data)
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