schemacop 3.0.0.rc1 → 3.0.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README_V3.md +188 -44
- data/VERSION +1 -1
- data/lib/schemacop/v3/array_node.rb +1 -2
- data/lib/schemacop/v3/hash_node.rb +31 -13
- data/lib/schemacop/v3/node.rb +1 -0
- data/schemacop.gemspec +3 -3
- 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/hash_node_test.rb +78 -20
- data/test/unit/schemacop/v3/one_of_node_test.rb +6 -6
- data/test/unit/schemacop/v3/reference_node_test.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73279c1805de5438933af200c883a7f6a813878d583c92bf7e597580f392df95
|
4
|
+
data.tar.gz: 2ac5ce2925de12c5df8a4f82086d967c68d31cd9f8c598cff0da9231d221f5ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c04434b491dac3c09018969b13293c029347011a58386234ea5dcca6b3aa7ed8ebe3f291b8d819869d79b3c8c80d5a998bbbca0a95d928988367e04efcad4ec2
|
7
|
+
data.tar.gz: 75564dd05800d295f3eb7ebb606f97ea67f2c19512a62193d49651cc77828836cfa95977465692ac85a5738a8407c7a2275a7cbe34db110c8400e70aa5057e95
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,20 @@
|
|
10
10
|
### Changes
|
11
11
|
-->
|
12
12
|
|
13
|
+
## 3.0.0.r2
|
14
|
+
|
15
|
+
* Represent node names as strings internally
|
16
|
+
|
17
|
+
* Update documentation
|
18
|
+
|
19
|
+
## 3.0.0.rc1
|
20
|
+
|
21
|
+
* Add support for ruby `3.0.0`
|
22
|
+
|
23
|
+
* Add `ruby-3.0.0` to travis testing
|
24
|
+
|
25
|
+
* Document all `v3` nodes
|
26
|
+
|
13
27
|
## 3.0.0.rc0
|
14
28
|
|
15
29
|
* Add `Schemacop::Schema3`
|
data/README_V3.md
CHANGED
@@ -1,15 +1,11 @@
|
|
1
1
|
# Schemacop schema V3
|
2
2
|
|
3
|
-
|
3
|
+
## Table of Contents
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
2. [Validation](#validation)
|
10
|
-
3. [Exceptions](#exceptions)
|
11
|
-
4. [Generic Keywords](#generic-keywords)
|
12
|
-
5. [Nodes](#nodes)
|
5
|
+
1. [Validation](#validation)
|
6
|
+
2. [Exceptions](#exceptions)
|
7
|
+
3. [Generic Keywords](#generic-keywords)
|
8
|
+
4. [Nodes](#nodes)
|
13
9
|
1. [String](#string)
|
14
10
|
2. [Integer](#integer)
|
15
11
|
3. [Number](#number)
|
@@ -23,12 +19,8 @@ Use at your own discretion.
|
|
23
19
|
11. [OneOf](#oneOf)
|
24
20
|
12. [IsNot](#isNot)
|
25
21
|
13. [Reference](#reference)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
## Introduction
|
30
|
-
|
31
|
-
TODO: Write short section about using schemacop V3
|
22
|
+
5. [Context](#context)
|
23
|
+
6. [External schemas](#external-schemas)
|
32
24
|
|
33
25
|
## Validation
|
34
26
|
|
@@ -74,19 +66,121 @@ schema.validate!('Foo') # => Schemacop::Exceptions::ValidationError: /:
|
|
74
66
|
|
75
67
|
## Exceptions
|
76
68
|
|
77
|
-
|
69
|
+
Schemacop can raise the following exceptions:
|
78
70
|
|
79
|
-
`Schemacop::Exceptions::ValidationError`
|
80
|
-
|
71
|
+
* `Schemacop::Exceptions::ValidationError`: This exception is raised when the `validate!`
|
72
|
+
method is used, and the data that was passed in is invalid. The exception message contains
|
73
|
+
additional informations why the validation failed.
|
74
|
+
|
75
|
+
Example:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
schema = Schemacop::Schema3.new :hash do
|
79
|
+
int! :foo
|
80
|
+
end
|
81
|
+
|
82
|
+
schema.validate!(foo: 'bar')
|
83
|
+
# => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "integer".
|
84
|
+
```
|
85
|
+
|
86
|
+
* `Schemacop::Exceptions::InvalidSchemaError`: This exception is raised when the schema
|
87
|
+
itself is not valid. The exception message contains additional informations why the
|
88
|
+
validation failed.
|
89
|
+
|
90
|
+
Example:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
Schemacop::Schema3.new :hash do
|
94
|
+
int!
|
95
|
+
end
|
96
|
+
|
97
|
+
# => Schemacop::Exceptions::InvalidSchemaError: Child nodes must have a name.
|
98
|
+
```
|
81
99
|
|
82
100
|
## Generic Keywords
|
83
101
|
|
84
|
-
|
102
|
+
The nodes in Schemacop v3 also support generic keywords, similar to JSON schema:
|
103
|
+
|
104
|
+
* `title`: Short string, should be self-explanatory
|
105
|
+
* `description`: Description of the schema
|
106
|
+
* `examples`: Here, you can provide examples which will be valid for the schema
|
107
|
+
* `enum`: Here, you may enumerate values which will be valid, if the provided
|
108
|
+
value is not in the array, the validation will fail
|
109
|
+
* `default`: You may provide a default value for items that will be set if the
|
110
|
+
value is not given
|
111
|
+
|
112
|
+
|
113
|
+
The three keywords `title`, `description` and `examples` aren't used for validation,
|
114
|
+
but can be used to document the schema. They will be included in the JSON output
|
115
|
+
when you use the `as_json` method:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
schema = Schemacop::Schema3.new :hash do
|
119
|
+
str! :name, title: 'Name', description: 'Holds the name of the user', examples: ['Joe', 'Anna']
|
120
|
+
end
|
121
|
+
|
122
|
+
schema.as_json
|
123
|
+
|
124
|
+
# => {"properties"=>{"name"=>{"type"=>"string", "title"=>"Name", "examples"=>["Joe", "Anna"], "description"=>"Holds the name of the user"}}, "additionalProperties"=>false, "required"=>["name"], "type"=>"object"}
|
125
|
+
```
|
126
|
+
|
127
|
+
The `enum` keyword can be used to only allow a subset of values:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar']
|
131
|
+
|
132
|
+
schema.validate!('foo') # => "foo"
|
133
|
+
schema.validate!('bar') # => "bar"
|
134
|
+
schema.validate!('baz') # => Schemacop::Exceptions::ValidationError: /: Value not included in enum ["foo", "bar"].
|
135
|
+
```
|
136
|
+
|
137
|
+
Please note, that you can also specify values in the enum that are not valid for
|
138
|
+
the schema. This means that the validation will still fail:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar', 42]
|
142
|
+
|
143
|
+
schema.validate!('foo') # => "foo"
|
144
|
+
schema.validate!('bar') # => "bar"
|
145
|
+
schema.validate!(42) # => Schemacop::Exceptions::ValidationError: /: Invalid type, expected "string".
|
146
|
+
```
|
147
|
+
|
148
|
+
The enum will also be provided in the json output:
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar']
|
152
|
+
|
153
|
+
schema.as_json
|
154
|
+
# => {"type"=>"string", "enum"=>["foo", "bar", 42]}
|
155
|
+
```
|
156
|
+
|
157
|
+
And finally, the `default` keyword lets you set a default value to use when no
|
158
|
+
value is provided:
|
159
|
+
|
160
|
+
```ruby
|
161
|
+
schema = Schemacop::Schema3.new :string, default: 'Schemacop'
|
162
|
+
|
163
|
+
schema.validate!('foo') # => "foo"
|
164
|
+
schema.validate!(nil) # => "Schemacop"
|
165
|
+
```
|
166
|
+
|
167
|
+
The default value will also be provided in the json output:
|
85
168
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
169
|
+
```ruby
|
170
|
+
schema = Schemacop::Schema3.new :string, default: 'Schemacop'
|
171
|
+
|
172
|
+
schema.as_json
|
173
|
+
# => {"type"=>"string", "default"=>"Schemacop"}
|
174
|
+
```
|
175
|
+
|
176
|
+
Note that the default value you use is also validated against the schema:
|
177
|
+
|
178
|
+
```ruby
|
179
|
+
schema = Schemacop::Schema3.new :string, default: 42
|
180
|
+
|
181
|
+
schema.validate!('foo') # => "foo"
|
182
|
+
schema.validate!(nil) # => Schemacop::Exceptions::ValidationError: /: Invalid type, expected "string".
|
183
|
+
```
|
90
184
|
|
91
185
|
## Nodes
|
92
186
|
|
@@ -523,11 +617,61 @@ schema = Schemacop::Schema3.new :hash do
|
|
523
617
|
end
|
524
618
|
|
525
619
|
schema.validate!({}) # => Schemacop::Exceptions::ValidationError: /foo: Value must be given.
|
526
|
-
schema.validate!({foo: 'str'}) # => {
|
527
|
-
schema.validate!({foo: 'str', bar: 42}) # => {
|
620
|
+
schema.validate!({foo: 'str'}) # => {"foo"=>"str"}
|
621
|
+
schema.validate!({foo: 'str', bar: 42}) # => {"foo"=>"str", "bar"=>42}
|
528
622
|
schema.validate!({bar: 42}) # => Schemacop::Exceptions::ValidationError: /foo: Value must be given.
|
529
623
|
```
|
530
624
|
|
625
|
+
The name of the properties may either be a string or a symbol, and you can pass
|
626
|
+
in the property either identified by a symbol or a string:
|
627
|
+
|
628
|
+
The following two schemas are equal:
|
629
|
+
|
630
|
+
```ruby
|
631
|
+
schema = Schemacop::Schema3.new :hash do
|
632
|
+
int! :foo
|
633
|
+
end
|
634
|
+
|
635
|
+
schema.validate!(foo: 42) # => {"foo"=>42}
|
636
|
+
schema.validate!('foo' => 42) # => {"foo"=>42}
|
637
|
+
|
638
|
+
schema = Schemacop::Schema3.new :hash do
|
639
|
+
int! 'foo'
|
640
|
+
end
|
641
|
+
|
642
|
+
schema.validate!(foo: 42) # => {"foo"=>42}
|
643
|
+
schema.validate!('foo' => 42) # => {"foo"=>42}
|
644
|
+
```
|
645
|
+
|
646
|
+
The result in both cases will be a
|
647
|
+
[HashWithIndifferentAccess](https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html),
|
648
|
+
which means that you can access the data in the hash with the symbol as well
|
649
|
+
as the string representation:
|
650
|
+
|
651
|
+
```ruby
|
652
|
+
schema = Schemacop::Schema3.new :hash do
|
653
|
+
int! :foo
|
654
|
+
end
|
655
|
+
|
656
|
+
result = schema.validate!(foo: 42)
|
657
|
+
|
658
|
+
result.class # => ActiveSupport::HashWithIndifferentAccess
|
659
|
+
result[:foo] # => 42
|
660
|
+
result['foo'] # 42
|
661
|
+
```
|
662
|
+
|
663
|
+
Please note, that if you specify the value twice in the data you want to validate,
|
664
|
+
once with the key being a symbol and once being a string, Schemacop will raise an
|
665
|
+
error:
|
666
|
+
|
667
|
+
```ruby
|
668
|
+
schema = Schemacop::Schema3.new :hash do
|
669
|
+
int! :foo
|
670
|
+
end
|
671
|
+
|
672
|
+
schema.validate!(foo: 42, 'foo' => 43) # => Schemacop::Exceptions::ValidationError: /: Has 1 ambiguous properties: [:foo].
|
673
|
+
```
|
674
|
+
|
531
675
|
##### Pattern properties
|
532
676
|
|
533
677
|
In addition to symbols, property keys can also be a regular expression. Here,
|
@@ -543,8 +687,8 @@ schema = Schemacop::Schema3.new :hash do
|
|
543
687
|
end
|
544
688
|
|
545
689
|
schema.validate!({}) # => {}
|
546
|
-
schema.validate!({id_foo: 1}) # => {
|
547
|
-
schema.validate!({id_foo: 1, id_bar: 2}) # => {
|
690
|
+
schema.validate!({id_foo: 1}) # => {"id_foo"=>1}
|
691
|
+
schema.validate!({id_foo: 1, id_bar: 2}) # => {"id_foo"=>1, "id_bar"=>2}
|
548
692
|
schema.validate!({foo: 3}) # => Schemacop::Exceptions::ValidationError: /: Obsolete property "foo".
|
549
693
|
```
|
550
694
|
|
@@ -562,7 +706,7 @@ enable all of them by enabling the option `additional_properties`:
|
|
562
706
|
schema = Schemacop::Schema3.new :hash, additional_properties: true
|
563
707
|
|
564
708
|
schema.validate!({}) # => {}
|
565
|
-
schema.validate!({foo: :bar, baz: 42}) # => {
|
709
|
+
schema.validate!({foo: :bar, baz: 42}) # => {"foo"=>:bar, "baz"=>42}
|
566
710
|
```
|
567
711
|
|
568
712
|
Using the DSL method `add` in the hash-node's body however, you can specify
|
@@ -578,8 +722,8 @@ Schemacop::Schema3.new :hash do
|
|
578
722
|
add :string
|
579
723
|
end
|
580
724
|
|
581
|
-
schema.validate!({id: 1}) # => {
|
582
|
-
schema.validate!({id: 1, foo: 'bar'}) # => {
|
725
|
+
schema.validate!({id: 1}) # => {"id"=>1}
|
726
|
+
schema.validate!({id: 1, foo: 'bar'}) # => {"id"=>1, "foo"=>"bar"}
|
583
727
|
schema.validate!({id: 1, foo: 42}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "string".
|
584
728
|
```
|
585
729
|
|
@@ -589,12 +733,12 @@ any additional property **keys** must adhere to:
|
|
589
733
|
```ruby
|
590
734
|
# The following schema allows any number of properties, but all keys must
|
591
735
|
# consist of downcase letters from a-z.
|
592
|
-
schema = Schemacop::Schema3.new :hash, additional_properties:
|
736
|
+
schema = Schemacop::Schema3.new :hash, additional_properties: true, property_names: '^[a-z]+$'
|
593
737
|
|
594
738
|
|
595
739
|
schema.validate!({}) # => {}
|
596
|
-
schema.validate!({foo: 123}) # => {
|
597
|
-
schema.validate!({Foo: 'bar'}) # => Schemacop::Exceptions::ValidationError: /: Property name
|
740
|
+
schema.validate!({foo: 123}) # => {"foo"=>123}
|
741
|
+
schema.validate!({Foo: 'bar'}) # => Schemacop::Exceptions::ValidationError: /: Property name "Foo" does not match "^[a-z]+$".
|
598
742
|
|
599
743
|
# The following schema allows any number of properties, but all keys must
|
600
744
|
# consist of downcase letters from a-z AND the properties must be arrays.
|
@@ -603,7 +747,7 @@ schema = Schemacop::Schema3.new :hash, additional_properties: true, property_nam
|
|
603
747
|
end
|
604
748
|
|
605
749
|
schema.validate!({}) # => {}
|
606
|
-
schema.validate!({foo: [1, 2, 3]}) # => {
|
750
|
+
schema.validate!({foo: [1, 2, 3]}) # => {"foo"=>[1, 2, 3]}
|
607
751
|
schema.validate!({foo: :bar}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "array".
|
608
752
|
schema.validate!({Foo: :bar}) # => Schemacop::Exceptions::ValidationError: /: Property name :Foo does not match "^[a-z]+$". /Foo: Invalid type, expected "array".
|
609
753
|
```
|
@@ -627,7 +771,7 @@ schema = Schemacop::Schema3.new :hash do
|
|
627
771
|
end
|
628
772
|
|
629
773
|
schema.validate!({}) # => Schemacop::Exceptions::ValidationError: /name: Value must be given.
|
630
|
-
schema.validate!({name: 'Joe Doe'}) # => {
|
774
|
+
schema.validate!({name: 'Joe Doe'}) # => {"name"=>"Joe Doe"}
|
631
775
|
schema.validate!({
|
632
776
|
name: 'Joe Doe',
|
633
777
|
billing_address: 'Street 42'
|
@@ -646,7 +790,7 @@ schema.validate!({
|
|
646
790
|
phone_number: '000-000-00-00',
|
647
791
|
credit_card: 'XXXX XXXX XXXX XXXX X'
|
648
792
|
})
|
649
|
-
# => {
|
793
|
+
# => {"name"=>"Joe Doe", "credit_card"=>"XXXX XXXX XXXX XXXX X", "billing_address"=>"Street 42", "phone_number"=>"000-000-00-00"}
|
650
794
|
```
|
651
795
|
|
652
796
|
### Object
|
@@ -654,7 +798,7 @@ schema.validate!({
|
|
654
798
|
Type: `:object`\
|
655
799
|
DSL: `obj`
|
656
800
|
|
657
|
-
The object type represents a ruby `Object`. Please note that the `as_json
|
801
|
+
The object type represents a ruby `Object`. Please note that the `as_json` method
|
658
802
|
on nodes of this type will just return `{}` (an empty JSON object), as there isn't
|
659
803
|
a useful way to represent a ruby object without conflicting with the `Hash` type.
|
660
804
|
If you want to represent an JSON object, you should use the `Hash` node.
|
@@ -884,7 +1028,7 @@ schema.validate!({
|
|
884
1028
|
}
|
885
1029
|
})
|
886
1030
|
|
887
|
-
# => {
|
1031
|
+
# => {"shipping_address"=>{"street"=>"Example Street 42", "zip_code"=>"12345", "location"=>"London", "country"=>"United Kingdom"}, "billing_address"=>{"street"=>"Main St.", "zip_code"=>"54321", "location"=>"Washington DC", "country"=>"USA"}}
|
888
1032
|
```
|
889
1033
|
|
890
1034
|
Note that if you use the reference node with the long type name `reference`,
|
@@ -902,7 +1046,7 @@ schema = Schemacop::Schema3.new :array do
|
|
902
1046
|
end
|
903
1047
|
|
904
1048
|
schema.validate!([]) # => []
|
905
|
-
schema.validate!([{first_name: 'Joe', last_name: 'Doe'}]) # => [{
|
1049
|
+
schema.validate!([{first_name: 'Joe', last_name: 'Doe'}]) # => [{"first_name"=>"Joe", "last_name"=>"Doe"}]
|
906
1050
|
schema.validate!([id: 42, first_name: 'Joe']) # => Schemacop::Exceptions::ValidationError: /[0]/last_name: Value must be given. /[0]: Obsolete property "id".
|
907
1051
|
```
|
908
1052
|
|
@@ -940,7 +1084,7 @@ schema = Schemacop::Schema3.new :reference, path: :Person
|
|
940
1084
|
# of the person.
|
941
1085
|
Schemacop.with_context context do
|
942
1086
|
schema.validate!({first_name: 'Joe', last_name: 'Doe', info: { born_at: '1980-01-01'} })
|
943
|
-
# => {
|
1087
|
+
# => {"first_name"=>"Joe", "last_name"=>"Doe", "info"=>{"born_at"=>Tue, 01 Jan 1980}}
|
944
1088
|
end
|
945
1089
|
|
946
1090
|
# Now we might want another context, where the person is more anonymous, and as
|
@@ -961,7 +1105,7 @@ Schemacop.with_context other_context do
|
|
961
1105
|
# /: Obsolete property "last_name".
|
962
1106
|
# /: Obsolete property "info".
|
963
1107
|
|
964
|
-
schema.validate!({nickname: 'J.'}) # => {
|
1108
|
+
schema.validate!({nickname: 'J.'}) # => {"nickname"=>"J."}
|
965
1109
|
end
|
966
1110
|
```
|
967
1111
|
|
@@ -1032,13 +1176,13 @@ schema = Schemacop::Schema3.new :hash do
|
|
1032
1176
|
end
|
1033
1177
|
|
1034
1178
|
schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe'}})
|
1035
|
-
# => {
|
1179
|
+
# => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe"}}
|
1036
1180
|
|
1037
1181
|
schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe', groups: []}})
|
1038
|
-
# => {
|
1182
|
+
# => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe", "groups"=>[]}}
|
1039
1183
|
|
1040
1184
|
schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe', groups: [{name: 'foo'}, {name: 'bar'}]}})
|
1041
|
-
# => {
|
1185
|
+
# => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe", "groups"=>[{"name"=>"foo"}, {"name"=>"bar"}]}}
|
1042
1186
|
```
|
1043
1187
|
|
1044
1188
|
### Non-Rails applications
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.0.
|
1
|
+
3.0.0.rc2
|
@@ -172,10 +172,9 @@ module Schemacop
|
|
172
172
|
list_item.present?
|
173
173
|
end
|
174
174
|
|
175
|
-
def item_for_data(data
|
175
|
+
def item_for_data(data)
|
176
176
|
item = children.find { |c| item_matches?(c, data) }
|
177
177
|
return item if item
|
178
|
-
return nil unless force
|
179
178
|
|
180
179
|
fail "Could not find specification for item #{data.inspect}."
|
181
180
|
end
|
@@ -91,14 +91,23 @@ module Schemacop
|
|
91
91
|
super_data = super
|
92
92
|
return if super_data.nil?
|
93
93
|
|
94
|
+
original_data_hash = super_data.dup
|
95
|
+
data_hash = super_data.with_indifferent_access
|
96
|
+
|
97
|
+
if original_data_hash.size != data_hash.size
|
98
|
+
ambiguous_properties = original_data_hash.keys - data_hash.keys
|
99
|
+
|
100
|
+
result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}."
|
101
|
+
end
|
102
|
+
|
94
103
|
# Validate min_properties #
|
95
|
-
if options[:min_properties] &&
|
96
|
-
result.error "Has #{
|
104
|
+
if options[:min_properties] && data_hash.size < options[:min_properties]
|
105
|
+
result.error "Has #{data_hash.size} properties but needs at least #{options[:min_properties]}."
|
97
106
|
end
|
98
107
|
|
99
108
|
# Validate max_properties #
|
100
|
-
if options[:max_properties] &&
|
101
|
-
result.error "Has #{
|
109
|
+
if options[:max_properties] && data_hash.size > options[:max_properties]
|
110
|
+
result.error "Has #{data_hash.size} properties but needs at most #{options[:max_properties]}."
|
102
111
|
end
|
103
112
|
|
104
113
|
# Validate specified properties #
|
@@ -106,13 +115,13 @@ module Schemacop
|
|
106
115
|
result.in_path(node.name) do
|
107
116
|
next if node.name.is_a?(Regexp)
|
108
117
|
|
109
|
-
node._validate(
|
118
|
+
node._validate(data_hash[node.name], result: result)
|
110
119
|
end
|
111
120
|
end
|
112
121
|
|
113
122
|
# Validate additional properties #
|
114
123
|
specified_properties = @properties.keys.to_set
|
115
|
-
additional_properties =
|
124
|
+
additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s) }
|
116
125
|
|
117
126
|
property_patterns = {}
|
118
127
|
|
@@ -149,7 +158,7 @@ module Schemacop
|
|
149
158
|
# Validate dependencies #
|
150
159
|
options[:dependencies]&.each do |source, targets|
|
151
160
|
targets.each do |target|
|
152
|
-
if
|
161
|
+
if data_hash[source].present? && data_hash[target].blank?
|
153
162
|
result.error "Missing property #{target.to_s.inspect} because #{source.to_s.inspect} is given."
|
154
163
|
end
|
155
164
|
end
|
@@ -161,10 +170,19 @@ module Schemacop
|
|
161
170
|
end
|
162
171
|
|
163
172
|
def cast(data)
|
164
|
-
result = {}
|
173
|
+
result = {}.with_indifferent_access
|
165
174
|
data ||= default
|
166
175
|
return nil if data.nil?
|
167
176
|
|
177
|
+
original_data_hash = data.dup
|
178
|
+
data_hash = data.with_indifferent_access
|
179
|
+
|
180
|
+
if original_data_hash.size != data_hash.size
|
181
|
+
ambiguous_properties = original_data_hash.keys - data_hash.keys
|
182
|
+
|
183
|
+
result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}."
|
184
|
+
end
|
185
|
+
|
168
186
|
property_patterns = {}
|
169
187
|
|
170
188
|
@properties.each_value do |prop|
|
@@ -173,16 +191,16 @@ module Schemacop
|
|
173
191
|
next
|
174
192
|
end
|
175
193
|
|
176
|
-
result[prop.name] = prop.cast(
|
194
|
+
result[prop.name] = prop.cast(data_hash[prop.name])
|
177
195
|
|
178
|
-
if result[prop.name].nil? && !
|
196
|
+
if result[prop.name].nil? && !data_hash.include?(prop.name)
|
179
197
|
result.delete(prop.name)
|
180
198
|
end
|
181
199
|
end
|
182
200
|
|
183
201
|
# Handle regex properties
|
184
202
|
specified_properties = @properties.keys.to_set
|
185
|
-
additional_properties =
|
203
|
+
additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) }
|
186
204
|
|
187
205
|
if additional_properties.any? && property_patterns.any?
|
188
206
|
additional_properties.each do |name, additional_property|
|
@@ -194,10 +212,10 @@ module Schemacop
|
|
194
212
|
|
195
213
|
# Handle additional properties
|
196
214
|
if options[:additional_properties] == true
|
197
|
-
result =
|
215
|
+
result = data_hash.merge(result)
|
198
216
|
elsif options[:additional_properties].is_a?(Node)
|
199
217
|
specified_properties = @properties.keys.to_set
|
200
|
-
additional_properties =
|
218
|
+
additional_properties = data_hash.reject { |k, _v| specified_properties.include?(k.to_s.to_sym) }
|
201
219
|
if additional_properties.any?
|
202
220
|
additional_properties_result = {}
|
203
221
|
additional_properties.each do |key, value|
|
data/lib/schemacop/v3/node.rb
CHANGED
data/schemacop.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: schemacop 3.0.0.
|
2
|
+
# stub: schemacop 3.0.0.rc2 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.rc2"
|
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-
|
11
|
+
s.date = "2021-01-28"
|
12
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]
|
13
13
|
s.homepage = "https://github.com/sitrox/schemacop".freeze
|
14
14
|
s.licenses = ["MIT".freeze]
|
@@ -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
|
@@ -54,6 +54,14 @@ module Schemacop
|
|
54
54
|
type: :object,
|
55
55
|
additionalProperties: { type: :string }
|
56
56
|
)
|
57
|
+
|
58
|
+
assert_nothing_raised do
|
59
|
+
@schema.validate!({ foo: 'foo' })
|
60
|
+
end
|
61
|
+
|
62
|
+
assert_raises_with_message Exceptions::ValidationError, '/bar: Invalid type, expected "string".' do
|
63
|
+
@schema.validate!({ foo: 'foo', bar: :baz })
|
64
|
+
end
|
57
65
|
end
|
58
66
|
|
59
67
|
def test_property_names
|
@@ -72,8 +80,8 @@ module Schemacop
|
|
72
80
|
propertyNames: '^[a-zA-Z0-9]+$'
|
73
81
|
)
|
74
82
|
|
75
|
-
assert_cast({ foo: 123 }, { foo: 123 })
|
76
|
-
assert_cast({ Foo: 123 }, { Foo: 123 })
|
83
|
+
assert_cast({ foo: 123 }, { foo: 123 }.with_indifferent_access)
|
84
|
+
assert_cast({ Foo: 123 }, { Foo: 123 }.with_indifferent_access)
|
77
85
|
|
78
86
|
# New schema
|
79
87
|
schema :hash, additional_properties: true, property_names: '^[a-z]+$'
|
@@ -82,13 +90,13 @@ module Schemacop
|
|
82
90
|
assert_validation(foo: :bar)
|
83
91
|
assert_validation('foo' => 'bar')
|
84
92
|
assert_validation(Foo: :bar) do
|
85
|
-
error '/', 'Property name
|
93
|
+
error '/', 'Property name "Foo" does not match "^[a-z]+$".'
|
86
94
|
end
|
87
95
|
assert_validation('_foo39sjfdoi 345893(%' => 'bar', 'foo' => 'bar') do
|
88
96
|
error '/', 'Property name "_foo39sjfdoi 345893(%" does not match "^[a-z]+$".'
|
89
97
|
end
|
90
98
|
|
91
|
-
assert_cast({ foo: 123 }, { foo: 123 })
|
99
|
+
assert_cast({ foo: 123 }, { foo: 123 }.with_indifferent_access)
|
92
100
|
end
|
93
101
|
|
94
102
|
def test_required
|
@@ -293,9 +301,9 @@ module Schemacop
|
|
293
301
|
assert_validation({ id_foo: 1, id_bar: 2 })
|
294
302
|
assert_validation({ id_foo: 1, id_bar: 2, value: 4 })
|
295
303
|
|
296
|
-
assert_cast({ id_foo: 1 }, { id_foo: 1 })
|
297
|
-
assert_cast({ id_foo: 1, id_bar: 2 }, { id_foo: 1, id_bar: 2 })
|
298
|
-
assert_cast({ id_foo: 1, id_bar: 2, value: 4 }, { id_foo: 1, id_bar: 2, value: 4 })
|
304
|
+
assert_cast({ id_foo: 1 }, { id_foo: 1 }.with_indifferent_access)
|
305
|
+
assert_cast({ id_foo: 1, id_bar: 2 }, { id_foo: 1, id_bar: 2 }.with_indifferent_access)
|
306
|
+
assert_cast({ id_foo: 1, id_bar: 2, value: 4 }, { id_foo: 1, id_bar: 2, value: 4 }.with_indifferent_access)
|
299
307
|
end
|
300
308
|
|
301
309
|
def test_defaults
|
@@ -311,7 +319,9 @@ module Schemacop
|
|
311
319
|
data = { last_name: 'Doeringer', active: 'true' }
|
312
320
|
data_was = data.dup
|
313
321
|
|
314
|
-
|
322
|
+
expected_data = { first_name: 'John', last_name: 'Doeringer', active: true, address: { street: 'Example 42' } }.with_indifferent_access
|
323
|
+
|
324
|
+
assert_equal(expected_data, @schema.validate(data).data)
|
315
325
|
assert_equal data_was, data
|
316
326
|
|
317
327
|
schema do
|
@@ -526,7 +536,7 @@ module Schemacop
|
|
526
536
|
|
527
537
|
assert_validation(nil)
|
528
538
|
assert_validation(foo: '1')
|
529
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
539
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
530
540
|
|
531
541
|
assert_validation(foo: '1', bar: '2') do
|
532
542
|
error '/', 'Obsolete property "bar".'
|
@@ -552,11 +562,11 @@ module Schemacop
|
|
552
562
|
|
553
563
|
assert_validation(nil)
|
554
564
|
assert_validation(foo: '1')
|
555
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
565
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
556
566
|
|
557
567
|
assert_validation(foo: '1', bar: nil)
|
558
568
|
assert_validation(foo: '1', bar: '2')
|
559
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
569
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
560
570
|
|
561
571
|
assert_json(
|
562
572
|
type: 'object',
|
@@ -589,11 +599,11 @@ module Schemacop
|
|
589
599
|
|
590
600
|
assert_validation(nil)
|
591
601
|
assert_validation(foo: '1')
|
592
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
602
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
593
603
|
|
594
604
|
assert_validation(foo: '1', bar: nil)
|
595
605
|
assert_validation(foo: '1', bar: '2')
|
596
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
606
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
597
607
|
|
598
608
|
assert_json(
|
599
609
|
type: 'object',
|
@@ -616,11 +626,11 @@ module Schemacop
|
|
616
626
|
|
617
627
|
assert_validation(nil)
|
618
628
|
assert_validation(foo: '1')
|
619
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
629
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
620
630
|
|
621
631
|
assert_validation(foo: '1', bar: nil)
|
622
632
|
assert_validation(foo: '1', bar: '2')
|
623
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 })
|
633
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 }.with_indifferent_access)
|
624
634
|
end
|
625
635
|
|
626
636
|
def test_cast_with_additional_any_of
|
@@ -634,7 +644,7 @@ module Schemacop
|
|
634
644
|
|
635
645
|
assert_validation(nil)
|
636
646
|
assert_validation(foo: '1')
|
637
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
647
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
638
648
|
|
639
649
|
assert_validation(foo: '1', bar: nil)
|
640
650
|
assert_validation(foo: '1', bar: '2')
|
@@ -643,7 +653,7 @@ module Schemacop
|
|
643
653
|
error '/qux', 'Does not match any anyOf condition.'
|
644
654
|
end
|
645
655
|
|
646
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' })
|
656
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: '2' }.with_indifferent_access)
|
647
657
|
|
648
658
|
assert_json(
|
649
659
|
type: 'object',
|
@@ -675,7 +685,7 @@ module Schemacop
|
|
675
685
|
|
676
686
|
assert_validation(nil)
|
677
687
|
assert_validation(foo: '1')
|
678
|
-
assert_cast({ foo: '1' }, { foo: 1 })
|
688
|
+
assert_cast({ foo: '1' }, { foo: 1 }.with_indifferent_access)
|
679
689
|
|
680
690
|
assert_validation(foo: '1', bar: nil)
|
681
691
|
assert_validation(foo: '1', bar: '2')
|
@@ -684,8 +694,8 @@ module Schemacop
|
|
684
694
|
error '/qux', 'Does not match any anyOf condition.'
|
685
695
|
end
|
686
696
|
|
687
|
-
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 })
|
688
|
-
assert_cast({ foo: '1', bar: '2', qux: '2020-01-13', asd: 1 }, { foo: 1, bar: 2, qux: Date.new(2020, 1, 13), asd: 1 })
|
697
|
+
assert_cast({ foo: '1', bar: '2' }, { foo: 1, bar: 2 }.with_indifferent_access)
|
698
|
+
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)
|
689
699
|
|
690
700
|
assert_json(
|
691
701
|
type: 'object',
|
@@ -821,6 +831,54 @@ module Schemacop
|
|
821
831
|
end
|
822
832
|
end
|
823
833
|
end
|
834
|
+
|
835
|
+
def test_schema_with_string_keys
|
836
|
+
schema :hash do
|
837
|
+
int! 'foo'
|
838
|
+
end
|
839
|
+
|
840
|
+
assert_validation(nil)
|
841
|
+
assert_validation({ 'foo' => 42 })
|
842
|
+
assert_validation({ foo: 42 })
|
843
|
+
|
844
|
+
assert_cast({ 'foo' => 42 }, { 'foo' => 42 })
|
845
|
+
assert_cast({ foo: 42 }, { foo: 42 }.with_indifferent_access)
|
846
|
+
|
847
|
+
assert_validation({}) do
|
848
|
+
error '/foo', 'Value must be given.'
|
849
|
+
end
|
850
|
+
|
851
|
+
assert_validation({ :foo => 42, 'foo' => 43 }) do
|
852
|
+
error '/', 'Has 1 ambiguous properties: [:foo].'
|
853
|
+
end
|
854
|
+
end
|
855
|
+
|
856
|
+
def test_schema_with_string_keys_in_data
|
857
|
+
schema :hash do
|
858
|
+
int! :foo
|
859
|
+
end
|
860
|
+
|
861
|
+
assert_validation(nil)
|
862
|
+
assert_validation({ 'foo' => 42 })
|
863
|
+
assert_validation({ foo: 42 })
|
864
|
+
|
865
|
+
assert_cast({ 'foo' => 42 }, { 'foo' => 42 })
|
866
|
+
assert_cast({ foo: 42 }, { foo: 42 }.with_indifferent_access)
|
867
|
+
|
868
|
+
assert_validation({}) do
|
869
|
+
error '/foo', 'Value must be given.'
|
870
|
+
end
|
871
|
+
|
872
|
+
assert_validation({ :foo => 42, 'foo' => 43 }) do
|
873
|
+
error '/', 'Has 1 ambiguous properties: [:foo].'
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
877
|
+
# def test_invalid_key_names
|
878
|
+
# schema :hash do
|
879
|
+
# int!
|
880
|
+
# end
|
881
|
+
# end
|
824
882
|
end
|
825
883
|
end
|
826
884
|
end
|
@@ -102,11 +102,11 @@ module Schemacop
|
|
102
102
|
|
103
103
|
assert_cast(
|
104
104
|
{ created_at: '2020-01-01' },
|
105
|
-
created_at: Date.new(2020, 1, 1)
|
105
|
+
{ created_at: Date.new(2020, 1, 1) }.with_indifferent_access
|
106
106
|
)
|
107
107
|
assert_cast(
|
108
108
|
{ created_at: '2020-01-01T17:38:20' },
|
109
|
-
created_at: DateTime.new(2020, 1, 1, 17, 38, 20)
|
109
|
+
{ created_at: DateTime.new(2020, 1, 1, 17, 38, 20) }.with_indifferent_access
|
110
110
|
)
|
111
111
|
end
|
112
112
|
|
@@ -127,12 +127,12 @@ module Schemacop
|
|
127
127
|
|
128
128
|
assert_cast(
|
129
129
|
{ foo: { bar: nil } },
|
130
|
-
foo: { bar: nil }
|
130
|
+
{ foo: { bar: nil } }.with_indifferent_access
|
131
131
|
)
|
132
132
|
|
133
133
|
assert_cast(
|
134
134
|
{ foo: { baz: nil } },
|
135
|
-
foo: { baz: 'Baz' }
|
135
|
+
{ foo: { baz: 'Baz' } }.with_indifferent_access
|
136
136
|
)
|
137
137
|
|
138
138
|
schema do
|
@@ -144,12 +144,12 @@ module Schemacop
|
|
144
144
|
|
145
145
|
assert_cast(
|
146
146
|
{ foo: { bar: '1990-01-13' } },
|
147
|
-
foo: { bar: Date.new(1990, 1, 13) }
|
147
|
+
{ foo: { bar: Date.new(1990, 1, 13) } }.with_indifferent_access
|
148
148
|
)
|
149
149
|
|
150
150
|
assert_cast(
|
151
151
|
{ foo: { bar: '1990-01-13T10:00:00Z' } },
|
152
|
-
foo: { bar: DateTime.new(1990, 1, 13, 10, 0, 0) }
|
152
|
+
{ foo: { bar: DateTime.new(1990, 1, 13, 10, 0, 0) } }.with_indifferent_access
|
153
153
|
)
|
154
154
|
end
|
155
155
|
|
@@ -333,7 +333,7 @@ module Schemacop
|
|
333
333
|
ref? :person, :Person, default: {}
|
334
334
|
end
|
335
335
|
|
336
|
-
assert_cast({}, person: { foo: 'bar' })
|
336
|
+
assert_cast({}, { person: { foo: 'bar' } }.with_indifferent_access)
|
337
337
|
end
|
338
338
|
|
339
339
|
def test_casting
|
@@ -344,7 +344,7 @@ module Schemacop
|
|
344
344
|
ref? :person, :Person, default: {}
|
345
345
|
end
|
346
346
|
|
347
|
-
assert_cast({ person: { born_at: '1990-01-13' } }, person: { born_at: Date.new(1990, 1, 13) })
|
347
|
+
assert_cast({ person: { born_at: '1990-01-13' } }, { person: { born_at: Date.new(1990, 1, 13) } }.with_indifferent_access)
|
348
348
|
end
|
349
349
|
end
|
350
350
|
end
|
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.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sitrox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|