schemacop 3.0.0.rc3 → 3.0.0.rc4

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 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