schemacop 3.0.0.rc3 → 3.0.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b93149de6cee935353aba3381d9e1ee76b51bc4b19763d8634566d375208fcac
4
- data.tar.gz: cb8e1a8b82104f6482d5017d90e3d5c2094d564ac9ef1001d2336bac137886cb
3
+ metadata.gz: 7d4b39e7b5e7391e8c5a8ff8ca7a1b008b19f1b62496e9a48e4180f7e953449d
4
+ data.tar.gz: 77bcf64925543433aad78dc02fbe610801db6a618cb1c8b154cea1a55c7220cf
5
5
  SHA512:
6
- metadata.gz: 0df1ba4b0c314901d015ca969996ffa9df862c79df0a52129bc3b749add7ff2e60ff52a9fb8a874f82b57017fef821c1e8d5d703093e0fd3bade224e8c84d259
7
- data.tar.gz: 1f501b7fdee6cc8347fe1acaf522f268ef5882e595f0c136c68c773b98615b37a05aeeaf1b472c3152546cdd3ae0859dd216eae9850f9f2992c2e970c7111157
6
+ metadata.gz: 75030bf09dcbdc5f556e48aac4ac9b200713b3cb59c5a6dfa071bcb642e030638bc3de80a1969378b33c9c77ab5c0ca3f44866c2ce691e827b4067025ca89f0e
7
+ data.tar.gz: 54de1f2cac717dc6d8b4fcc89bdb679c7d7d528785a2a664bc9940061b1e5015bebd9827677bb581bc838f87ad62e0d54db87d13ce5ba0fa70ca44a37985e539
data/CHANGELOG.md CHANGED
@@ -10,6 +10,15 @@
10
10
  ### Changes
11
11
  -->
12
12
 
13
+ ## 3.0.0.rc4 (2020-02-02)
14
+
15
+ * Fix some minor bugs
16
+
17
+ * Improve documentation
18
+
19
+ * `used_external_schemas` for the `ReferenceNode` is now applied
20
+ recursively
21
+
13
22
  ## 3.0.0.rc3 (2020-01-28)
14
23
 
15
24
  * Add minor improvements to the documentation
data/README_V3.md CHANGED
@@ -90,7 +90,7 @@ Schemacop can raise the following exceptions:
90
90
  Example:
91
91
 
92
92
  ```ruby
93
- Schemacop::Schema3.new do
93
+ Schemacop::Schema3.new :hash do
94
94
  int!
95
95
  end
96
96
 
@@ -380,7 +380,7 @@ schema.validate!(1234) # => Schemacop::Exceptions::ValidationError: /: Invali
380
380
  ### Array
381
381
 
382
382
  Type: `:array`\
383
- DSL: `arr`
383
+ DSL: `ary`
384
384
 
385
385
  The array type represents a ruby `Array`.
386
386
  It consists of one or multiple values, which can be validated using arbitrary nodes.
@@ -587,8 +587,9 @@ It consists of key-value-pairs that can be validated using arbitrary nodes.
587
587
 
588
588
  * `additional_properties`
589
589
  This option specifies whether additional, unspecified properties are allowed
590
- (`true`) or not (`false`). By default, this is `true` if no properties are
591
- specified and `false` if you have specified at least one property.
590
+ (`true`) or not (`false`). By default, this is `false`, i.e. you need to
591
+ explicitly set it to `true` if you want to allow arbitrary additional properties,
592
+ or use the `add` DSL method (see below) to specify additional properties.
592
593
 
593
594
  * `property_names`
594
595
  This option allows to specify a regexp pattern (as string) which validates the
@@ -673,6 +674,61 @@ end
673
674
  schema.validate!(foo: 42, 'foo' => 43) # => Schemacop::Exceptions::ValidationError: /: Has 1 ambiguous properties: [:foo].
674
675
  ```
675
676
 
677
+ In addition to the normal node options (which vary from type to type, check
678
+ the respective nodes for details), properties also support the `as` option.
679
+
680
+ With this, you can "rename" properties in the output:
681
+
682
+ ```ruby
683
+ schema = Schemacop::Schema3.new :hash do
684
+ int! :foo, as: :bar
685
+ end
686
+
687
+ schema.validate!({foo: 42}) # => {"bar"=>42}
688
+ ```
689
+
690
+ Please note that if you specify a node with the same property name multiple
691
+ times, or use the `as` option to rename a node to the same name of another
692
+ node, the last specified node will be used:
693
+
694
+ ```ruby
695
+ schema = Schemacop::Schema3.new :hash do
696
+ int? :foo
697
+ str? :foo
698
+ end
699
+
700
+ schema.validate!({foo: 1}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "string".
701
+ schema.validate!({foo: 'bar'}) # => {"foo"=>"bar"}
702
+ ```
703
+
704
+ As well as:
705
+
706
+ ```ruby
707
+ schema = Schemacop::Schema3.new :hash do
708
+ int? :foo
709
+ int? :bar, as: :foo
710
+ end
711
+
712
+ schema.validate!({foo: 1}) # => {"foo"=>1}
713
+ schema.validate!({foo: 1, bar: 2}) # => {"foo"=>2}
714
+ schema.validate!({bar: 2}) # => {"foo"=>2}
715
+ ```
716
+
717
+ If you want to specify a node which may be one of multiple types, use the `one_of`
718
+ node (see further down for more details):
719
+
720
+ ```ruby
721
+ schema = Schemacop::Schema3.new :hash do
722
+ one_of! :foo do
723
+ int
724
+ str
725
+ end
726
+ end
727
+
728
+ schema.validate!({foo: 1}) # => {"foo"=>1}
729
+ schema.validate!({foo: 'bar'}) # => {"foo"=>"bar"}
730
+ ```
731
+
676
732
  ##### Pattern properties
677
733
 
678
734
  In addition to symbols, property keys can also be a regular expression. Here,
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.0.0.rc3
1
+ 3.0.0.rc4
@@ -18,6 +18,7 @@ module Schemacop::V2
18
18
  @data = data
19
19
  @target_type = target_type
20
20
  @caster = nil
21
+ @value = nil
21
22
 
22
23
  if casts.is_a?(Array)
23
24
  from_types = casts
@@ -68,7 +68,7 @@ module Schemacop
68
68
 
69
69
  # In schemacop, by default, additional properties are not allowed,
70
70
  # the users explicitly need to enable additional properties
71
- if options[:additional_properties] == true
71
+ if options[:additional_properties].is_a?(TrueClass)
72
72
  json[:additionalProperties] = true
73
73
  elsif options[:additional_properties].is_a?(Node)
74
74
  json[:additionalProperties] = options[:additional_properties].as_json
@@ -141,7 +141,9 @@ module Schemacop
141
141
  result.error "Property name #{name.inspect} does not match #{options[:property_names].inspect}."
142
142
  end
143
143
 
144
- if options[:additional_properties].blank?
144
+ if options[:additional_properties].is_a?(TrueClass)
145
+ next
146
+ elsif options[:additional_properties].is_a?(FalseClass) || options[:additional_properties].blank?
145
147
  match = property_patterns.keys.find { |p| p.match?(name.to_s) }
146
148
  if match
147
149
  result.in_path(name) do
@@ -176,16 +178,10 @@ module Schemacop
176
178
  data ||= default
177
179
  return nil if data.nil?
178
180
 
179
- original_data_hash = data.dup
180
- data_hash = data.with_indifferent_access
181
-
182
- if original_data_hash.size != data_hash.size
183
- ambiguous_properties = original_data_hash.keys - data_hash.keys
184
-
185
- result.error "Has #{ambiguous_properties.size} ambiguous properties: #{ambiguous_properties}."
186
- end
181
+ data_hash = data.dup.with_indifferent_access
187
182
 
188
183
  property_patterns = {}
184
+ as_names = []
189
185
 
190
186
  @properties.each_value do |prop|
191
187
  if prop.name.is_a?(Regexp)
@@ -193,10 +189,18 @@ module Schemacop
193
189
  next
194
190
  end
195
191
 
196
- result[prop.as || prop.name] = prop.cast(data_hash[prop.name])
192
+ as_names << prop.as&.to_s if prop.as.present?
197
193
 
198
- if result[prop.as || prop.name].nil? && !data_hash.include?(prop.name)
199
- result.delete(prop.as || prop.name)
194
+ prop_name = prop.as&.to_s || prop.name
195
+
196
+ casted_data = prop.cast(data_hash[prop.name])
197
+
198
+ if casted_data.present? || data_hash.include?(prop.name)
199
+ result[prop_name] = casted_data
200
+ end
201
+
202
+ if result[prop_name].nil? && !data_hash.include?(prop.name) && !as_names.include?(prop.name)
203
+ result.delete(prop_name)
200
204
  end
201
205
  end
202
206
 
@@ -213,7 +217,7 @@ module Schemacop
213
217
  end
214
218
 
215
219
  # Handle additional properties
216
- if options[:additional_properties] == true
220
+ if options[:additional_properties].is_a?(TrueClass)
217
221
  result = data_hash.merge(result)
218
222
  elsif options[:additional_properties].is_a?(Node)
219
223
  specified_properties = @properties.keys.to_set
@@ -238,6 +242,11 @@ module Schemacop
238
242
  unless @options[:additional_properties].nil? || @options[:additional_properties].is_a?(TrueClass) || @options[:additional_properties].is_a?(FalseClass)
239
243
  fail Schemacop::Exceptions::InvalidSchemaError, 'Option "additional_properties" must be a boolean value'
240
244
  end
245
+
246
+ # Default the additional_properties option to false if it's not given
247
+ if @options[:additional_properties].nil?
248
+ @options[:additional_properties] = false
249
+ end
241
250
  end
242
251
 
243
252
  def validate_self
@@ -72,7 +72,7 @@ module Schemacop
72
72
  disallowed_options = options.keys - self.class.allowed_options
73
73
 
74
74
  if disallowed_options.any?
75
- fail "Options #{disallowed_options.inspect} are not allowed for this node."
75
+ fail Schemacop::Exceptions::InvalidSchemaError, "Options #{disallowed_options.inspect} are not allowed for this node."
76
76
  end
77
77
 
78
78
  # Assign attributes #
@@ -95,7 +95,7 @@ module Schemacop
95
95
  # Run DSL block #
96
96
  if block_given?
97
97
  unless self.class.supports_children_options
98
- fail "Node #{self.class} does not support blocks."
98
+ fail Schemacop::Exceptions::InvalidSchemaError, "Node #{self.class} does not support blocks."
99
99
  end
100
100
 
101
101
  scope = DslScope.new(self)
@@ -40,10 +40,6 @@ module Schemacop
40
40
  def self.name(klass)
41
41
  @by_class[klass][:name]
42
42
  end
43
-
44
- def self.short_name(klass)
45
- @by_class[klass][:short_name]
46
- end
47
43
  end
48
44
  end
49
45
  end
@@ -36,7 +36,13 @@ module Schemacop
36
36
  end
37
37
 
38
38
  def used_external_schemas
39
- schemas.include?(@path) ? [] : [@path]
39
+ target_children_schema = target.used_external_schemas
40
+
41
+ if schemas.include?(@path)
42
+ return target_children_schema
43
+ else
44
+ return [@path] + target_children_schema
45
+ end
40
46
  end
41
47
 
42
48
  protected
@@ -66,21 +66,29 @@ module Schemacop
66
66
  end
67
67
 
68
68
  def cast(value)
69
+ if value.present?
70
+ to_cast = value
71
+ elsif default.present?
72
+ to_cast = default
73
+ else
74
+ return nil
75
+ end
76
+
69
77
  case options[:format]
70
78
  when :boolean
71
- return value == 'true'
79
+ return to_cast == 'true'
72
80
  when :date
73
- return Date.parse(value)
81
+ return Date.parse(to_cast)
74
82
  when :'date-time'
75
- return DateTime.parse(value)
83
+ return DateTime.parse(to_cast)
76
84
  when :time
77
- Time.parse(value)
85
+ Time.parse(to_cast)
78
86
  when :integer
79
- return Integer(value)
87
+ return Integer(to_cast)
80
88
  when :number
81
- return Float(value)
89
+ return Float(to_cast)
82
90
  else
83
- return value || default
91
+ return to_cast
84
92
  end
85
93
  end
86
94
 
data/schemacop.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: schemacop 3.0.0.rc3 ruby lib
2
+ # stub: schemacop 3.0.0.rc4 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "schemacop".freeze
6
- s.version = "3.0.0.rc3"
6
+ s.version = "3.0.0.rc4"
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-28"
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-02"
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
@@ -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
@@ -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({})
@@ -874,11 +885,88 @@ module Schemacop
874
885
  end
875
886
  end
876
887
 
877
- # def test_invalid_key_names
878
- # schema :hash do
879
- # int!
880
- # end
881
- # end
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
882
970
  end
883
971
  end
884
972
  end
@@ -143,6 +143,20 @@ module Schemacop
143
143
  error '/[0]', 'Value must be given.'
144
144
  end
145
145
  end
146
+
147
+ def test_not_support_block
148
+ assert_raises_with_message Schemacop::Exceptions::InvalidSchemaError, 'Node Schemacop::V3::IntegerNode does not support blocks.' do
149
+ schema :integer do
150
+ int :foo
151
+ end
152
+ end
153
+ end
154
+
155
+ def test_node_no_children
156
+ @schema = Schemacop::Schema3.new
157
+
158
+ assert_equal(@schema.root.children, [])
159
+ end
146
160
  end
147
161
  end
148
162
  end
@@ -249,6 +249,8 @@ module Schemacop
249
249
  ref? :node, :Node
250
250
  end
251
251
 
252
+ assert_equal(@schema.root.used_external_schemas, [])
253
+
252
254
  assert_validation({})
253
255
  assert_validation(node: { name: '1', children: [{ name: '1' }, { name: '2' }] })
254
256
  assert_validation(
@@ -313,6 +315,8 @@ module Schemacop
313
315
  ref! :person, :Person
314
316
  end
315
317
 
318
+ assert_equal(@schema.root.used_external_schemas, %i[Person PersonInfo])
319
+
316
320
  assert_validation(person: { first_name: 'John', last_name: 'Doe' })
317
321
  assert_validation(person: { first_name: 'John', last_name: 'Doe', info: { born_at: '1990-01-13' } })
318
322
  assert_validation(person: { first_name_x: 'John', last_name: 'Doe' }) do
@@ -323,6 +327,18 @@ module Schemacop
323
327
  error '/person/info/born_at', 'String does not match format "date".'
324
328
  end
325
329
  end
330
+
331
+ with_context context do
332
+ schema do
333
+ scm :PersonNode do
334
+ ref! :person, :Person
335
+ end
336
+
337
+ ref! :personNode, :PersonNode
338
+ end
339
+
340
+ assert_equal(@schema.root.used_external_schemas, %i[Person PersonInfo])
341
+ end
326
342
  end
327
343
 
328
344
  def test_defaults
@@ -111,6 +111,9 @@ module Schemacop
111
111
  assert_validation 'foo 2020-01-29 bar' do
112
112
  error '/', 'String does not match format "date".'
113
113
  end
114
+
115
+ assert_cast(nil, nil)
116
+ assert_cast('2020-01-13', Date.new(2020, 1, 13))
114
117
  end
115
118
 
116
119
  def test_format_date_time
@@ -132,6 +135,9 @@ module Schemacop
132
135
  assert_validation '2018-11-13T20:20:39Y' do
133
136
  error '/', 'String does not match format "date-time".'
134
137
  end
138
+
139
+ assert_cast(nil, nil)
140
+ assert_cast('2018-11-13T20:20:39+00:00', DateTime.new(2018, 11, 13, 20, 20, 39))
135
141
  end
136
142
 
137
143
  def test_format_email
@@ -154,6 +160,9 @@ module Schemacop
154
160
  assert_validation '@john@example.com' do
155
161
  error '/', 'String does not match format "email".'
156
162
  end
163
+
164
+ assert_cast(nil, nil)
165
+ assert_cast('john.doe@example.com', 'john.doe@example.com')
157
166
  end
158
167
 
159
168
  def test_enum
@@ -187,18 +196,24 @@ module Schemacop
187
196
 
188
197
  assert_cast 'true', true
189
198
  assert_cast 'false', false
199
+
200
+ assert_cast nil, nil
190
201
  end
191
202
 
192
203
  def test_time_casting
193
204
  schema :string, format: :time
194
205
  assert_json(type: :string, format: :time)
195
206
  assert_cast '20:30:39+00:00', Time.strptime('20:30:39+00:00', '%H:%M:%S%z')
207
+
208
+ assert_cast nil, nil
196
209
  end
197
210
 
198
211
  def test_date_casting
199
212
  schema :string, format: :date
200
213
  assert_json(type: :string, format: :date)
201
214
  assert_cast '2018-11-13', Date.new(2018, 11, 13)
215
+
216
+ assert_cast nil, nil
202
217
  end
203
218
 
204
219
  def test_date_time_casting
@@ -207,12 +222,16 @@ module Schemacop
207
222
  assert_cast '2018-11-13T20:20:39+00:00', DateTime.new(2018, 11, 13, 20, 20, 39)
208
223
  assert_cast '2018-11-13T20:20:39Z', DateTime.new(2018, 11, 13, 20, 20, 39)
209
224
  assert_cast '2018-11-13T20:20:39+01:00', DateTime.new(2018, 11, 13, 20, 20, 39, '+1')
225
+
226
+ assert_cast nil, nil
210
227
  end
211
228
 
212
229
  def test_email_casting
213
230
  schema :string, format: :email
214
231
  assert_json(type: :string, format: :email)
215
232
  assert_cast 'support@example.com', 'support@example.com'
233
+
234
+ assert_cast nil, nil
216
235
  end
217
236
 
218
237
  def test_default
@@ -233,6 +252,25 @@ module Schemacop
233
252
  assert_cast(nil, 'Hello')
234
253
  end
235
254
 
255
+ def test_default_casting
256
+ schema :string, format: :integer, default: '42'
257
+
258
+ assert_json(
259
+ type: :string,
260
+ format: :integer,
261
+ default: '42'
262
+ )
263
+
264
+ assert_validation(nil)
265
+ assert_validation('123')
266
+ assert_validation(5) do
267
+ error '/', 'Invalid type, expected "string".'
268
+ end
269
+
270
+ assert_cast('123', 123)
271
+ assert_cast(nil, 42)
272
+ end
273
+
236
274
  # Helper function that checks for all the options if the option is
237
275
  # an integer or something else, in which case it needs to raise
238
276
  def validate_self_should_error(value_to_check)
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.rc3
4
+ version: 3.0.0.rc4
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-01-28 00:00:00.000000000 Z
11
+ date: 2021-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -150,8 +150,8 @@ dependencies:
150
150
  - - '='
151
151
  - !ruby/object:Gem::Version
152
152
  version: 0.21.2
153
- description:
154
- email:
153
+ description:
154
+ email:
155
155
  executables: []
156
156
  extensions: []
157
157
  extra_rdoc_files: []
@@ -188,7 +188,6 @@ files:
188
188
  - lib/schemacop/v2/node_supporting_field.rb
189
189
  - lib/schemacop/v2/node_supporting_type.rb
190
190
  - lib/schemacop/v2/node_with_block.rb
191
- - lib/schemacop/v2/root_node.rb
192
191
  - lib/schemacop/v2/validator/array_validator.rb
193
192
  - lib/schemacop/v2/validator/boolean_validator.rb
194
193
  - lib/schemacop/v2/validator/float_validator.rb
@@ -264,7 +263,7 @@ homepage: https://github.com/sitrox/schemacop
264
263
  licenses:
265
264
  - MIT
266
265
  metadata: {}
267
- post_install_message:
266
+ post_install_message:
268
267
  rdoc_options: []
269
268
  require_paths:
270
269
  - lib
@@ -279,8 +278,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
279
278
  - !ruby/object:Gem::Version
280
279
  version: 1.3.1
281
280
  requirements: []
282
- rubygems_version: 3.1.4
283
- signing_key:
281
+ rubygems_version: 3.0.3
282
+ signing_key:
284
283
  specification_version: 4
285
284
  summary: Schemacop validates ruby structures consisting of nested hashes and arrays
286
285
  against simple schema definitions.
File without changes