schemacop 3.0.12 → 3.0.16
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/CHANGELOG.md +28 -0
- data/README_V3.md +55 -5
- data/VERSION +1 -1
- data/lib/schemacop/v3/hash_node.rb +1 -1
- data/lib/schemacop/v3/node.rb +4 -2
- data/lib/schemacop/v3/string_node.rb +6 -32
- data/lib/schemacop.rb +77 -0
- data/schemacop.gemspec +3 -3
- data/test/unit/schemacop/v3/boolean_node_test.rb +41 -2
- data/test/unit/schemacop/v3/integer_node_test.rb +5 -0
- data/test/unit/schemacop/v3/node_test.rb +8 -0
- data/test/unit/schemacop/v3/number_node_test.rb +5 -0
- data/test/unit/schemacop/v3/string_node_test.rb +97 -27
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3c6c1009f3a4a23a39f58dd1aef99c63136f8d362963d14a7513f08f0d705c0c
|
4
|
+
data.tar.gz: 58a4e7ace82f8f5b1a69ac70ec39dc44a0b4766a167920e3f6de497a7ebe3ee9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7086af3afd13d6cabe140cd550a53b9fed5117b496fb01e67ea4fc9a468d0e5e9a8c5f563fe330fae88a3c4a61fd9c98cbe6317ac1cf6478ab159b66afca9391
|
7
|
+
data.tar.gz: 438129e855a0da9ba74fd7a03c9de3abf3bd206cca4cfe5c70a5ae5ad21d88a927d3cc25738934a3a51f72c32781d48ea1da47c0f7db427a94945792a892641b
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,33 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
|
+
## 3.0.17 (2021-12-06)
|
4
|
+
|
5
|
+
* `#64545`: Fix an issue where `cast_str` in conjunction with `number` notes
|
6
|
+
lead to parsing errors when the given number had a leading zero, e.g. parsing
|
7
|
+
the string `08` lead to an error, as the number was interpreted as an octal
|
8
|
+
string. Numbers are now always being treated as decimal with base 10.
|
9
|
+
|
10
|
+
## 3.0.16 (2021-11-23)
|
11
|
+
|
12
|
+
* Add setting `Schemacop.v3_default_options` which allows to set default node
|
13
|
+
options vor V3 schemas. This is particularly useful for the option `cast_str`
|
14
|
+
to allow string casting globally.
|
15
|
+
|
16
|
+
## 3.0.15 (2021-10-11)
|
17
|
+
|
18
|
+
* Add support for custom string formatters
|
19
|
+
|
20
|
+
## 3.0.14 (2021-10-11)
|
21
|
+
|
22
|
+
* Add string format `integer_list`
|
23
|
+
|
24
|
+
* Improve handling for booleans
|
25
|
+
|
26
|
+
## 3.0.13 (2021-10-04)
|
27
|
+
|
28
|
+
* When using `boolean` with `cast_str: true`, `"0"` is now casted to `false` and
|
29
|
+
`"1"` to `true`. This in addition to already casting `"true", "false"`.
|
30
|
+
|
3
31
|
## 3.0.12 (2021-09-14)
|
4
32
|
|
5
33
|
* Fix compatibility issue with `ruby <= 2.5`
|
data/README_V3.md
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
13. [Reference](#reference)
|
22
22
|
5. [Context](#context)
|
23
23
|
6. [External schemas](#external-schemas)
|
24
|
+
7. [Default options](#default-options)
|
24
25
|
|
25
26
|
## Validation
|
26
27
|
|
@@ -233,8 +234,8 @@ transformed into various types.
|
|
233
234
|
addresses do not have their own ruby type.
|
234
235
|
|
235
236
|
* `boolean`
|
236
|
-
The string must be either `true` or `
|
237
|
-
Ruby's `TrueClass` or `FalseClass`.
|
237
|
+
The string must be either `true`, `false`, `0` or `1`. This value will be
|
238
|
+
casted to Ruby's `TrueClass` or `FalseClass`.
|
238
239
|
|
239
240
|
* `binary`
|
240
241
|
The string is expected to contain binary contents. No casting or additional
|
@@ -246,9 +247,30 @@ transformed into various types.
|
|
246
247
|
* `number`
|
247
248
|
The string must be a number and will be casted to a ruby `Float` object.
|
248
249
|
|
250
|
+
* `integer_list`
|
251
|
+
The string must consist of comma-separated integers casted to a ruby `Array<Integer>` object
|
252
|
+
|
249
253
|
* `symbol`
|
250
254
|
The string can be anything and will be casted to a ruby `Symbol` object.
|
251
255
|
|
256
|
+
#### Custom Formats
|
257
|
+
|
258
|
+
You can also implement your custom formats or override the behavior of the
|
259
|
+
standard formats. This can be done in the initializer configuration (in case of
|
260
|
+
a Rails appliation):
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
# config/initializers/schemacop.rb
|
264
|
+
Schemacop.register_string_formatter(
|
265
|
+
:character_array, # Formatter name
|
266
|
+
pattern: /^[a-zA-Z](,[a-zA-Z])*/, # Regex pattern for validation
|
267
|
+
handler: ->(value) { value.split(',') } # Casting callback
|
268
|
+
)
|
269
|
+
|
270
|
+
# In your schema
|
271
|
+
str! :my_list, format: :character_array
|
272
|
+
```
|
273
|
+
|
252
274
|
#### Examples
|
253
275
|
|
254
276
|
```ruby
|
@@ -318,6 +340,8 @@ integer can be done.
|
|
318
340
|
When set to `true`, this node also accepts strings that can be casted to an integer, e.g.
|
319
341
|
the values `'-5'` or `'42'`. Please note that you can only validate numbers which
|
320
342
|
are in the `Integer` format. Blank strings will be treated equally as `nil`.
|
343
|
+
Strings will be parsed with base 10, so only decimal numbers are allowed.
|
344
|
+
Leading zeroes will be ignored.
|
321
345
|
|
322
346
|
#### Examples
|
323
347
|
|
@@ -399,7 +423,9 @@ With the various available options, validations on the value of the number can b
|
|
399
423
|
When set to `true`, this node also accepts strings that can be casted to a number, e.g.
|
400
424
|
the values `'0.1'` or `'3.1415'`. Please note that you can only validate numbers which
|
401
425
|
are in the `Integer` or `Float` format, i.e. values like `'1.5r'` or `'(4 + 0i)'` will
|
402
|
-
not work. Blank strings will be treated equally as `nil`.
|
426
|
+
not work. Blank strings will be treated equally as `nil`. Strings will be
|
427
|
+
parsed with base 10, so only decimal numbers are allowed. Leading zeroes will
|
428
|
+
be ignored.
|
403
429
|
|
404
430
|
#### Examples
|
405
431
|
|
@@ -501,8 +527,9 @@ The boolean type is used to validate Ruby booleans, i.e. the `TrueClass` and `Fa
|
|
501
527
|
#### Options
|
502
528
|
|
503
529
|
* `cast_str`
|
504
|
-
When set to `true`, this node also accepts strings that can be casted to a
|
505
|
-
the values `'true'` and `'
|
530
|
+
When set to `true`, this node also accepts strings that can be casted to a
|
531
|
+
boolean, namely the values `'true'`, `'false'`, `'1'` and `'0'`. Blank strings
|
532
|
+
will be treated equally as `nil`.
|
506
533
|
|
507
534
|
#### Examples
|
508
535
|
|
@@ -514,6 +541,11 @@ schema.validate!(false) # => false
|
|
514
541
|
schema.validate!(:false) # => Schemacop::Exceptions::ValidationError: /: Invalid type, got type "Symbol", expected "boolean".
|
515
542
|
schema.validate!('false') # => Schemacop::Exceptions::ValidationError: /: Invalid type, got type "String", expected "boolean".
|
516
543
|
schema.validate!(1234) # => Schemacop::Exceptions::ValidationError: /: Invalid type, got type "Integer", expected "boolean".
|
544
|
+
|
545
|
+
schema.validate!('0', cast_str: true) # => false
|
546
|
+
schema.validate!('1', cast_str: true) # => true
|
547
|
+
schema.validate!('false', cast_str: true) # => false
|
548
|
+
schema.validate!('true', cast_str: true) # => true
|
517
549
|
```
|
518
550
|
|
519
551
|
With `cast_str` enabled:
|
@@ -1422,3 +1454,21 @@ Schemacop::V3::GlobalContext.eager_load!
|
|
1422
1454
|
As mentioned before, you can also use the external schemas without having to
|
1423
1455
|
eager-load them, but if you use the schemas multiple times, it might be better
|
1424
1456
|
to eager-load them on start of your application / script.
|
1457
|
+
|
1458
|
+
## Default options
|
1459
|
+
|
1460
|
+
Using the setting `Schemacop.v3_default_options`, you can specify a hash
|
1461
|
+
containing default options that will be used for every schemacop node (options
|
1462
|
+
not supported by a particular node are automatically ignored). Options passed
|
1463
|
+
directly to a node still take precedence. The setting can be set in an
|
1464
|
+
initializer:
|
1465
|
+
|
1466
|
+
```ruby
|
1467
|
+
# config/initializers/schemacop.rb
|
1468
|
+
Schemacop.v3_default_options = { cast_str: true }.freeze
|
1469
|
+
|
1470
|
+
# Example schema: As cast_str is enabled in the default options, strings will
|
1471
|
+
# automatically be casted where supported.
|
1472
|
+
schema = Schemacop::Schema3.new(:integer)
|
1473
|
+
schema.validate!('42') # => 42
|
1474
|
+
```
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.0.
|
1
|
+
3.0.16
|
data/lib/schemacop/v3/node.rb
CHANGED
@@ -30,6 +30,8 @@ module Schemacop
|
|
30
30
|
|
31
31
|
node = klass.new(**options, &block)
|
32
32
|
|
33
|
+
options = Schemacop.v3_default_options.slice(*klass.allowed_options).merge(options)
|
34
|
+
|
33
35
|
if options.delete(:cast_str)
|
34
36
|
format = NodeRegistry.name(klass)
|
35
37
|
one_of_options = {
|
@@ -178,7 +180,7 @@ module Schemacop
|
|
178
180
|
json[:title] = @title if @title
|
179
181
|
json[context.swagger_json? ? :example : :examples] = @examples if @examples
|
180
182
|
json[:description] = @description if @description
|
181
|
-
json[:default] = @default
|
183
|
+
json[:default] = @default unless @default.nil?
|
182
184
|
json[:enum] = @enum.to_a if @enum
|
183
185
|
|
184
186
|
return json.as_json
|
@@ -197,7 +199,7 @@ module Schemacop
|
|
197
199
|
|
198
200
|
# Apply default #
|
199
201
|
if data.nil?
|
200
|
-
if default
|
202
|
+
if !default.nil?
|
201
203
|
data = default
|
202
204
|
else
|
203
205
|
return nil
|
@@ -7,20 +7,6 @@ module Schemacop
|
|
7
7
|
format
|
8
8
|
].freeze
|
9
9
|
|
10
|
-
# rubocop:disable Layout/LineLength
|
11
|
-
FORMAT_PATTERNS = {
|
12
|
-
date: /^([0-9]{4})-?(1[0-2]|0[1-9])-?(3[01]|0[1-9]|[12][0-9])$/,
|
13
|
-
'date-time': /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$/,
|
14
|
-
time: /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$/,
|
15
|
-
email: URI::MailTo::EMAIL_REGEXP,
|
16
|
-
boolean: /^(true|false)$/,
|
17
|
-
binary: nil,
|
18
|
-
symbol: nil,
|
19
|
-
integer: /^-?[0-9]+$/,
|
20
|
-
number: /^-?[0-9]+(\.[0-9]+)?$/
|
21
|
-
}.freeze
|
22
|
-
# rubocop:enable Layout/LineLength
|
23
|
-
|
24
10
|
def self.allowed_options
|
25
11
|
super + ATTRIBUTES + %i[format_options pattern allow_blank]
|
26
12
|
end
|
@@ -70,8 +56,9 @@ module Schemacop
|
|
70
56
|
end
|
71
57
|
|
72
58
|
# Validate format #
|
73
|
-
if options[:format] &&
|
74
|
-
pattern =
|
59
|
+
if options[:format] && Schemacop.string_formatters.include?(options[:format])
|
60
|
+
pattern = Schemacop.string_formatters[options[:format]][:pattern]
|
61
|
+
|
75
62
|
if pattern && !super_data.match?(pattern)
|
76
63
|
result.error "String does not match format #{options[:format].to_s.inspect}."
|
77
64
|
elsif options[:format_options] && Node.resolve_class(options[:format])
|
@@ -90,21 +77,8 @@ module Schemacop
|
|
90
77
|
return nil
|
91
78
|
end
|
92
79
|
|
93
|
-
|
94
|
-
|
95
|
-
return to_cast == 'true'
|
96
|
-
when :date
|
97
|
-
return Date.parse(to_cast)
|
98
|
-
when :'date-time'
|
99
|
-
return DateTime.parse(to_cast)
|
100
|
-
when :time
|
101
|
-
Time.parse(to_cast)
|
102
|
-
when :integer
|
103
|
-
return Integer(to_cast)
|
104
|
-
when :number
|
105
|
-
return Float(to_cast)
|
106
|
-
when :symbol
|
107
|
-
return to_cast.to_sym
|
80
|
+
if (handler = Schemacop.string_formatters.dig(options[:format], :handler))
|
81
|
+
return handler.call(to_cast)
|
108
82
|
else
|
109
83
|
return to_cast
|
110
84
|
end
|
@@ -119,7 +93,7 @@ module Schemacop
|
|
119
93
|
end
|
120
94
|
|
121
95
|
def validate_self
|
122
|
-
if options.include?(:format) && !
|
96
|
+
if options.include?(:format) && !Schemacop.string_formatters.include?(options[:format])
|
123
97
|
fail "Format #{options[:format].to_s.inspect} is not supported."
|
124
98
|
end
|
125
99
|
|
data/lib/schemacop.rb
CHANGED
@@ -13,6 +13,83 @@ module Schemacop
|
|
13
13
|
mattr_accessor :default_schema_version
|
14
14
|
self.default_schema_version = 3
|
15
15
|
|
16
|
+
mattr_accessor :string_formatters
|
17
|
+
self.string_formatters = {}
|
18
|
+
|
19
|
+
mattr_accessor :v3_default_options
|
20
|
+
self.v3_default_options = {}
|
21
|
+
|
22
|
+
def self.register_string_formatter(name, pattern:, handler:)
|
23
|
+
name = name.to_s.dasherize.to_sym
|
24
|
+
|
25
|
+
string_formatters[name] = {
|
26
|
+
pattern: pattern,
|
27
|
+
handler: handler
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
register_string_formatter(
|
32
|
+
:date,
|
33
|
+
pattern: /^([0-9]{4})-?(1[0-2]|0[1-9])-?(3[01]|0[1-9]|[12][0-9])$/,
|
34
|
+
handler: ->(value) { Date.parse(value) }
|
35
|
+
)
|
36
|
+
|
37
|
+
# rubocop: disable Layout/LineLength
|
38
|
+
register_string_formatter(
|
39
|
+
:'date-time',
|
40
|
+
pattern: /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$/,
|
41
|
+
handler: ->(value) { DateTime.parse(value) }
|
42
|
+
)
|
43
|
+
# rubocop: enable Layout/LineLength
|
44
|
+
|
45
|
+
register_string_formatter(
|
46
|
+
:time,
|
47
|
+
pattern: /^(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(\.[0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$/,
|
48
|
+
handler: ->(value) { Time.parse(value) }
|
49
|
+
)
|
50
|
+
|
51
|
+
register_string_formatter(
|
52
|
+
:email,
|
53
|
+
pattern: URI::MailTo::EMAIL_REGEXP,
|
54
|
+
handler: ->(value) { value }
|
55
|
+
)
|
56
|
+
|
57
|
+
register_string_formatter(
|
58
|
+
:boolean,
|
59
|
+
pattern: /^(true|false|0|1)$/,
|
60
|
+
handler: ->(value) { %w[true 1].include?(value) }
|
61
|
+
)
|
62
|
+
|
63
|
+
register_string_formatter(
|
64
|
+
:binary,
|
65
|
+
pattern: nil,
|
66
|
+
handler: ->(value) { value }
|
67
|
+
)
|
68
|
+
|
69
|
+
register_string_formatter(
|
70
|
+
:symbol,
|
71
|
+
pattern: nil,
|
72
|
+
handler: ->(value) { value.to_sym }
|
73
|
+
)
|
74
|
+
|
75
|
+
register_string_formatter(
|
76
|
+
:integer,
|
77
|
+
pattern: /^-?[0-9]+$/,
|
78
|
+
handler: ->(value) { Integer(value, 10) }
|
79
|
+
)
|
80
|
+
|
81
|
+
register_string_formatter(
|
82
|
+
:number,
|
83
|
+
pattern: /^-?[0-9]+(\.[0-9]+)?$/,
|
84
|
+
handler: ->(value) { Float(value) }
|
85
|
+
)
|
86
|
+
|
87
|
+
register_string_formatter(
|
88
|
+
:'integer-list',
|
89
|
+
pattern: /^(-?[0-9]+)(,-?[0-9]+)*$/,
|
90
|
+
handler: ->(value) { value.split(',').map { |i| Integer(i, 10) } }
|
91
|
+
)
|
92
|
+
|
16
93
|
def self.with_context(context)
|
17
94
|
prev_context = Thread.current[CONTEXT_THREAD_KEY]
|
18
95
|
Thread.current[CONTEXT_THREAD_KEY] = context
|
data/schemacop.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: schemacop 3.0.
|
2
|
+
# stub: schemacop 3.0.16 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "schemacop".freeze
|
6
|
-
s.version = "3.0.
|
6
|
+
s.version = "3.0.16"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".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-
|
11
|
+
s.date = "2021-12-06"
|
12
12
|
s.files = [".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.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]
|
@@ -18,6 +18,38 @@ module Schemacop
|
|
18
18
|
assert_json(type: :boolean)
|
19
19
|
end
|
20
20
|
|
21
|
+
def test_required_default
|
22
|
+
schema do
|
23
|
+
boo? :enabled, default: true
|
24
|
+
end
|
25
|
+
|
26
|
+
assert_validation(enabled: true)
|
27
|
+
assert_validation(enabled: false)
|
28
|
+
|
29
|
+
assert_cast({}, { 'enabled' => true })
|
30
|
+
|
31
|
+
schema do
|
32
|
+
boo? :enabled, default: false
|
33
|
+
end
|
34
|
+
|
35
|
+
assert_validation(enabled: true)
|
36
|
+
assert_validation(enabled: false)
|
37
|
+
|
38
|
+
assert_cast({}, { 'enabled' => false })
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_default_bug
|
42
|
+
schema do
|
43
|
+
str! :send_message
|
44
|
+
boo? :always_show_successful, default: true
|
45
|
+
end
|
46
|
+
|
47
|
+
assert_cast(
|
48
|
+
{ 'send_message' => 'foo' },
|
49
|
+
{ 'send_message' => 'foo', 'always_show_successful' => true }
|
50
|
+
)
|
51
|
+
end
|
52
|
+
|
21
53
|
def test_required
|
22
54
|
schema :boolean, required: true
|
23
55
|
|
@@ -146,10 +178,13 @@ module Schemacop
|
|
146
178
|
assert_cast('true', true)
|
147
179
|
assert_cast('false', false)
|
148
180
|
|
181
|
+
assert_cast('1', true)
|
182
|
+
assert_cast('0', false)
|
183
|
+
|
149
184
|
assert_cast(true, true)
|
150
185
|
assert_cast(false, false)
|
151
186
|
|
152
|
-
assert_validation('
|
187
|
+
assert_validation('5') do
|
153
188
|
error '/', 'Matches 0 definitions but should match exactly 1.'
|
154
189
|
end
|
155
190
|
|
@@ -171,7 +206,11 @@ module Schemacop
|
|
171
206
|
assert_cast(true, true)
|
172
207
|
assert_cast(false, false)
|
173
208
|
|
174
|
-
assert_validation('
|
209
|
+
assert_validation('4') do
|
210
|
+
error '/', 'Matches 0 definitions but should match exactly 1.'
|
211
|
+
end
|
212
|
+
|
213
|
+
assert_validation('foo') do
|
175
214
|
error '/', 'Matches 0 definitions but should match exactly 1.'
|
176
215
|
end
|
177
216
|
|
@@ -181,6 +181,14 @@ module Schemacop
|
|
181
181
|
|
182
182
|
assert_equal(@schema.root.children, [])
|
183
183
|
end
|
184
|
+
|
185
|
+
def test_default_options
|
186
|
+
Schemacop.v3_default_options = { cast_str: true }.freeze
|
187
|
+
schema :number
|
188
|
+
assert_cast('1', 1)
|
189
|
+
ensure
|
190
|
+
Schemacop.v3_default_options = {}
|
191
|
+
end
|
184
192
|
end
|
185
193
|
end
|
186
194
|
end
|
@@ -158,6 +158,14 @@ module Schemacop
|
|
158
158
|
assert_cast('2018-11-13T20:20:39+00:00', DateTime.new(2018, 11, 13, 20, 20, 39))
|
159
159
|
end
|
160
160
|
|
161
|
+
def test_format_time
|
162
|
+
schema :string, format: :time
|
163
|
+
assert_json(type: :string, format: :time)
|
164
|
+
assert_cast '20:30:39+00:00', Time.strptime('20:30:39+00:00', '%H:%M:%S%z')
|
165
|
+
|
166
|
+
assert_cast nil, nil
|
167
|
+
end
|
168
|
+
|
161
169
|
def test_format_email
|
162
170
|
schema :string, format: :email
|
163
171
|
|
@@ -183,6 +191,17 @@ module Schemacop
|
|
183
191
|
assert_cast('john.doe@example.com', 'john.doe@example.com')
|
184
192
|
end
|
185
193
|
|
194
|
+
def test_format_boolean
|
195
|
+
schema :string, format: :boolean
|
196
|
+
|
197
|
+
assert_json(type: :string, format: :boolean)
|
198
|
+
|
199
|
+
assert_cast 'true', true
|
200
|
+
assert_cast 'false', false
|
201
|
+
|
202
|
+
assert_cast nil, nil
|
203
|
+
end
|
204
|
+
|
186
205
|
def test_format_symbol
|
187
206
|
schema :string, format: :symbol
|
188
207
|
|
@@ -200,6 +219,84 @@ module Schemacop
|
|
200
219
|
assert_cast('039n23$g- sfk3/', :'039n23$g- sfk3/')
|
201
220
|
end
|
202
221
|
|
222
|
+
def test_format_integer
|
223
|
+
schema :string, format: :integer
|
224
|
+
|
225
|
+
assert_json(type: :string, format: :integer)
|
226
|
+
|
227
|
+
assert_validation '23425'
|
228
|
+
assert_validation '-23425'
|
229
|
+
|
230
|
+
assert_validation 12_312 do
|
231
|
+
error '/', StringNodeTest.invalid_type_error(Integer)
|
232
|
+
end
|
233
|
+
|
234
|
+
assert_validation '24.32' do
|
235
|
+
error '/', 'String does not match format "integer".'
|
236
|
+
end
|
237
|
+
|
238
|
+
assert_cast(nil, nil)
|
239
|
+
assert_cast('2234', 2234)
|
240
|
+
assert_cast('-1', -1)
|
241
|
+
assert_cast('-0', 0)
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_format_integer_list
|
245
|
+
schema :string, format: :integer_list
|
246
|
+
|
247
|
+
assert_json(type: :string, format: :'integer-list')
|
248
|
+
|
249
|
+
assert_validation '1,2,3,4'
|
250
|
+
assert_validation '1,2,-3,-54'
|
251
|
+
assert_validation '2'
|
252
|
+
assert_validation '-2'
|
253
|
+
|
254
|
+
assert_validation 234 do
|
255
|
+
error '/', StringNodeTest.invalid_type_error(Integer)
|
256
|
+
end
|
257
|
+
|
258
|
+
assert_validation 'sd sfdij soidf' do
|
259
|
+
error '/', 'String does not match format "integer-list".'
|
260
|
+
end
|
261
|
+
|
262
|
+
assert_cast nil, nil
|
263
|
+
assert_cast '1,-2,3', [1, -2, 3]
|
264
|
+
assert_cast '1', [1]
|
265
|
+
assert_cast '-1', [-1]
|
266
|
+
assert_cast '08', [8]
|
267
|
+
assert_cast '09', [9]
|
268
|
+
assert_cast '050', [50]
|
269
|
+
assert_cast '01,032', [1, 32]
|
270
|
+
end
|
271
|
+
|
272
|
+
def test_format_custom
|
273
|
+
Schemacop.register_string_formatter(
|
274
|
+
:integer_tuple_list,
|
275
|
+
pattern: /^(-?[0-9]+):(-?[0-9]+)(,(-?[0-9]+):(-?[0-9]+))*$/,
|
276
|
+
handler: proc do |value|
|
277
|
+
value.split(',').map { |t| t.split(':').map(&:to_i) }
|
278
|
+
end
|
279
|
+
)
|
280
|
+
|
281
|
+
schema :string, format: :integer_tuple_list
|
282
|
+
|
283
|
+
assert_json(type: :string, format: :'integer-tuple-list')
|
284
|
+
|
285
|
+
assert_validation '1:5,4:2,-4:4,4:-1,0:0'
|
286
|
+
assert_validation '-1:5'
|
287
|
+
|
288
|
+
assert_validation 234 do
|
289
|
+
error '/', StringNodeTest.invalid_type_error(Integer)
|
290
|
+
end
|
291
|
+
|
292
|
+
assert_validation 'sd sfdij soidf' do
|
293
|
+
error '/', 'String does not match format "integer-tuple-list".'
|
294
|
+
end
|
295
|
+
|
296
|
+
assert_cast nil, nil
|
297
|
+
assert_cast '1:2,3:4,5:-6', [[1, 2], [3, 4], [5, -6]]
|
298
|
+
end
|
299
|
+
|
203
300
|
def test_enum
|
204
301
|
schema :string, enum: ['foo', 'some string', 'some other string', 42]
|
205
302
|
|
@@ -224,33 +321,6 @@ module Schemacop
|
|
224
321
|
end
|
225
322
|
end
|
226
323
|
|
227
|
-
def test_boolean_casting
|
228
|
-
schema :string, format: :boolean
|
229
|
-
|
230
|
-
assert_json(type: :string, format: :boolean)
|
231
|
-
|
232
|
-
assert_cast 'true', true
|
233
|
-
assert_cast 'false', false
|
234
|
-
|
235
|
-
assert_cast nil, nil
|
236
|
-
end
|
237
|
-
|
238
|
-
def test_time_casting
|
239
|
-
schema :string, format: :time
|
240
|
-
assert_json(type: :string, format: :time)
|
241
|
-
assert_cast '20:30:39+00:00', Time.strptime('20:30:39+00:00', '%H:%M:%S%z')
|
242
|
-
|
243
|
-
assert_cast nil, nil
|
244
|
-
end
|
245
|
-
|
246
|
-
def test_date_casting
|
247
|
-
schema :string, format: :date
|
248
|
-
assert_json(type: :string, format: :date)
|
249
|
-
assert_cast '2018-11-13', Date.new(2018, 11, 13)
|
250
|
-
|
251
|
-
assert_cast nil, nil
|
252
|
-
end
|
253
|
-
|
254
324
|
def test_date_time_casting
|
255
325
|
schema :string, format: :date_time
|
256
326
|
assert_json(type: :string, format: :'date-time')
|
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.
|
4
|
+
version: 3.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sitrox
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-12-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -164,8 +164,8 @@ dependencies:
|
|
164
164
|
- - '='
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: 0.21.2
|
167
|
-
description:
|
168
|
-
email:
|
167
|
+
description:
|
168
|
+
email:
|
169
169
|
executables: []
|
170
170
|
extensions: []
|
171
171
|
extra_rdoc_files: []
|
@@ -277,7 +277,7 @@ homepage: https://github.com/sitrox/schemacop
|
|
277
277
|
licenses:
|
278
278
|
- MIT
|
279
279
|
metadata: {}
|
280
|
-
post_install_message:
|
280
|
+
post_install_message:
|
281
281
|
rdoc_options: []
|
282
282
|
require_paths:
|
283
283
|
- lib
|
@@ -292,8 +292,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
292
292
|
- !ruby/object:Gem::Version
|
293
293
|
version: '0'
|
294
294
|
requirements: []
|
295
|
-
rubygems_version: 3.
|
296
|
-
signing_key:
|
295
|
+
rubygems_version: 3.2.22
|
296
|
+
signing_key:
|
297
297
|
specification_version: 4
|
298
298
|
summary: Schemacop validates ruby structures consisting of nested hashes and arrays
|
299
299
|
against simple schema definitions.
|