schemacop 2.4.7 → 3.0.0.rc0

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.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +25 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +8 -0
  6. data/README.md +41 -708
  7. data/README_V2.md +775 -0
  8. data/README_V3.md +683 -0
  9. data/Rakefile +8 -12
  10. data/VERSION +1 -1
  11. data/lib/schemacop.rb +35 -37
  12. data/lib/schemacop/base_schema.rb +37 -0
  13. data/lib/schemacop/railtie.rb +10 -0
  14. data/lib/schemacop/schema.rb +1 -60
  15. data/lib/schemacop/schema2.rb +22 -0
  16. data/lib/schemacop/schema3.rb +21 -0
  17. data/lib/schemacop/scoped_env.rb +25 -13
  18. data/lib/schemacop/v2.rb +26 -0
  19. data/lib/schemacop/{caster.rb → v2/caster.rb} +16 -2
  20. data/lib/schemacop/{collector.rb → v2/collector.rb} +5 -2
  21. data/lib/schemacop/{dupper.rb → v2/dupper.rb} +1 -1
  22. data/lib/schemacop/{field_node.rb → v2/field_node.rb} +4 -3
  23. data/lib/schemacop/v2/node.rb +142 -0
  24. data/lib/schemacop/{node_resolver.rb → v2/node_resolver.rb} +1 -1
  25. data/lib/schemacop/{node_supporting_field.rb → v2/node_supporting_field.rb} +8 -10
  26. data/lib/schemacop/{node_supporting_type.rb → v2/node_supporting_type.rb} +6 -3
  27. data/lib/schemacop/{node_with_block.rb → v2/node_with_block.rb} +3 -2
  28. data/lib/schemacop/v2/root_node.rb +6 -0
  29. data/lib/schemacop/v2/validator/array_validator.rb +32 -0
  30. data/lib/schemacop/{validator → v2/validator}/boolean_validator.rb +1 -1
  31. data/lib/schemacop/v2/validator/float_validator.rb +7 -0
  32. data/lib/schemacop/v2/validator/hash_validator.rb +37 -0
  33. data/lib/schemacop/v2/validator/integer_validator.rb +7 -0
  34. data/lib/schemacop/{validator → v2/validator}/nil_validator.rb +1 -1
  35. data/lib/schemacop/v2/validator/number_validator.rb +21 -0
  36. data/lib/schemacop/v2/validator/object_validator.rb +29 -0
  37. data/lib/schemacop/v2/validator/string_validator.rb +39 -0
  38. data/lib/schemacop/{validator → v2/validator}/symbol_validator.rb +1 -1
  39. data/lib/schemacop/v3.rb +45 -0
  40. data/lib/schemacop/v3/all_of_node.rb +27 -0
  41. data/lib/schemacop/v3/any_of_node.rb +28 -0
  42. data/lib/schemacop/v3/array_node.rb +219 -0
  43. data/lib/schemacop/v3/boolean_node.rb +16 -0
  44. data/lib/schemacop/v3/combination_node.rb +45 -0
  45. data/lib/schemacop/v3/context.rb +17 -0
  46. data/lib/schemacop/v3/dsl_scope.rb +46 -0
  47. data/lib/schemacop/v3/global_context.rb +114 -0
  48. data/lib/schemacop/v3/hash_node.rb +217 -0
  49. data/lib/schemacop/v3/integer_node.rb +13 -0
  50. data/lib/schemacop/v3/is_not_node.rb +32 -0
  51. data/lib/schemacop/v3/node.rb +214 -0
  52. data/lib/schemacop/v3/node_registry.rb +49 -0
  53. data/lib/schemacop/v3/number_node.rb +18 -0
  54. data/lib/schemacop/v3/numeric_node.rb +76 -0
  55. data/lib/schemacop/v3/object_node.rb +40 -0
  56. data/lib/schemacop/v3/one_of_node.rb +28 -0
  57. data/lib/schemacop/v3/reference_node.rb +49 -0
  58. data/lib/schemacop/v3/result.rb +58 -0
  59. data/lib/schemacop/v3/string_node.rb +124 -0
  60. data/lib/schemacop/v3/symbol_node.rb +13 -0
  61. data/schemacop.gemspec +24 -27
  62. data/test/lib/test_helper.rb +152 -0
  63. data/test/schemas/nested/group.rb +6 -0
  64. data/test/schemas/user.rb +7 -0
  65. data/test/unit/schemacop/v2/casting_test.rb +120 -0
  66. data/test/unit/schemacop/v2/collector_test.rb +47 -0
  67. data/test/unit/schemacop/v2/custom_check_test.rb +95 -0
  68. data/test/unit/schemacop/v2/custom_if_test.rb +97 -0
  69. data/test/unit/schemacop/v2/defaults_test.rb +95 -0
  70. data/test/unit/schemacop/v2/empty_test.rb +16 -0
  71. data/test/unit/schemacop/v2/nil_dis_allow_test.rb +43 -0
  72. data/test/unit/schemacop/v2/node_resolver_test.rb +28 -0
  73. data/test/unit/schemacop/v2/short_forms_test.rb +351 -0
  74. data/test/unit/schemacop/v2/types_test.rb +88 -0
  75. data/test/unit/schemacop/v2/validator_array_test.rb +99 -0
  76. data/test/unit/schemacop/v2/validator_boolean_test.rb +17 -0
  77. data/test/unit/schemacop/v2/validator_float_test.rb +59 -0
  78. data/test/unit/schemacop/v2/validator_hash_test.rb +95 -0
  79. data/test/unit/schemacop/v2/validator_integer_test.rb +48 -0
  80. data/test/unit/schemacop/v2/validator_nil_test.rb +15 -0
  81. data/test/unit/schemacop/v2/validator_number_test.rb +62 -0
  82. data/test/unit/schemacop/v2/validator_object_test.rb +141 -0
  83. data/test/unit/schemacop/v2/validator_string_test.rb +78 -0
  84. data/test/unit/schemacop/v2/validator_symbol_test.rb +18 -0
  85. data/test/unit/schemacop/v3/all_of_node_test.rb +199 -0
  86. data/test/unit/schemacop/v3/any_of_node_test.rb +218 -0
  87. data/test/unit/schemacop/v3/array_node_test.rb +805 -0
  88. data/test/unit/schemacop/v3/boolean_node_test.rb +126 -0
  89. data/test/unit/schemacop/v3/global_context_test.rb +164 -0
  90. data/test/unit/schemacop/v3/hash_node_test.rb +775 -0
  91. data/test/unit/schemacop/v3/integer_node_test.rb +323 -0
  92. data/test/unit/schemacop/v3/is_not_node_test.rb +173 -0
  93. data/test/unit/schemacop/v3/node_test.rb +148 -0
  94. data/test/unit/schemacop/v3/number_node_test.rb +292 -0
  95. data/test/unit/schemacop/v3/object_node_test.rb +170 -0
  96. data/test/unit/schemacop/v3/one_of_node_test.rb +187 -0
  97. data/test/unit/schemacop/v3/reference_node_test.rb +351 -0
  98. data/test/unit/schemacop/v3/string_node_test.rb +334 -0
  99. data/test/unit/schemacop/v3/symbol_node_test.rb +75 -0
  100. metadata +152 -145
  101. data/doc/Schemacop.html +0 -146
  102. data/doc/Schemacop/ArrayValidator.html +0 -329
  103. data/doc/Schemacop/BooleanValidator.html +0 -145
  104. data/doc/Schemacop/Caster.html +0 -379
  105. data/doc/Schemacop/Collector.html +0 -787
  106. data/doc/Schemacop/Dupper.html +0 -214
  107. data/doc/Schemacop/Exceptions.html +0 -115
  108. data/doc/Schemacop/Exceptions/InvalidSchemaError.html +0 -124
  109. data/doc/Schemacop/Exceptions/ValidationError.html +0 -124
  110. data/doc/Schemacop/FieldNode.html +0 -421
  111. data/doc/Schemacop/FloatValidator.html +0 -158
  112. data/doc/Schemacop/HashValidator.html +0 -293
  113. data/doc/Schemacop/IntegerValidator.html +0 -158
  114. data/doc/Schemacop/NilValidator.html +0 -145
  115. data/doc/Schemacop/Node.html +0 -1438
  116. data/doc/Schemacop/NodeResolver.html +0 -258
  117. data/doc/Schemacop/NodeSupportingField.html +0 -590
  118. data/doc/Schemacop/NodeSupportingType.html +0 -612
  119. data/doc/Schemacop/NodeWithBlock.html +0 -289
  120. data/doc/Schemacop/NumberValidator.html +0 -232
  121. data/doc/Schemacop/ObjectValidator.html +0 -298
  122. data/doc/Schemacop/RootNode.html +0 -171
  123. data/doc/Schemacop/Schema.html +0 -699
  124. data/doc/Schemacop/StringValidator.html +0 -295
  125. data/doc/Schemacop/SymbolValidator.html +0 -145
  126. data/doc/ScopedEnv.html +0 -351
  127. data/doc/_index.html +0 -379
  128. data/doc/class_list.html +0 -51
  129. data/doc/css/common.css +0 -1
  130. data/doc/css/full_list.css +0 -58
  131. data/doc/css/style.css +0 -496
  132. data/doc/file.README.html +0 -833
  133. data/doc/file_list.html +0 -56
  134. data/doc/frames.html +0 -17
  135. data/doc/index.html +0 -833
  136. data/doc/inheritance.graphml +0 -524
  137. data/doc/inheritance.pdf +0 -825
  138. data/doc/js/app.js +0 -303
  139. data/doc/js/full_list.js +0 -216
  140. data/doc/js/jquery.js +0 -4
  141. data/doc/method_list.html +0 -587
  142. data/doc/top-level-namespace.html +0 -112
  143. data/lib/schemacop/node.rb +0 -139
  144. data/lib/schemacop/root_node.rb +0 -4
  145. data/lib/schemacop/validator/array_validator.rb +0 -30
  146. data/lib/schemacop/validator/float_validator.rb +0 -5
  147. data/lib/schemacop/validator/hash_validator.rb +0 -35
  148. data/lib/schemacop/validator/integer_validator.rb +0 -5
  149. data/lib/schemacop/validator/number_validator.rb +0 -19
  150. data/lib/schemacop/validator/object_validator.rb +0 -27
  151. data/lib/schemacop/validator/string_validator.rb +0 -37
  152. data/test/casting_test.rb +0 -118
  153. data/test/collector_test.rb +0 -45
  154. data/test/custom_check_test.rb +0 -93
  155. data/test/custom_if_test.rb +0 -95
  156. data/test/defaults_test.rb +0 -93
  157. data/test/empty_test.rb +0 -14
  158. data/test/nil_dis_allow_test.rb +0 -41
  159. data/test/node_resolver_test.rb +0 -26
  160. data/test/short_forms_test.rb +0 -349
  161. data/test/test_helper.rb +0 -13
  162. data/test/types_test.rb +0 -84
  163. data/test/validator_array_test.rb +0 -97
  164. data/test/validator_boolean_test.rb +0 -15
  165. data/test/validator_float_test.rb +0 -57
  166. data/test/validator_hash_test.rb +0 -93
  167. data/test/validator_integer_test.rb +0 -46
  168. data/test/validator_nil_test.rb +0 -13
  169. data/test/validator_number_test.rb +0 -60
  170. data/test/validator_object_test.rb +0 -139
  171. data/test/validator_string_test.rb +0 -76
  172. data/test/validator_symbol_test.rb +0 -16
@@ -1,112 +0,0 @@
1
- <!DOCTYPE html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>
7
- Top Level Namespace
8
-
9
- &mdash; Documentation by YARD 0.9.20
10
-
11
- </title>
12
-
13
- <link rel="stylesheet" href="css/style.css" type="text/css" charset="utf-8" />
14
-
15
- <link rel="stylesheet" href="css/common.css" type="text/css" charset="utf-8" />
16
-
17
- <script type="text/javascript" charset="utf-8">
18
- pathId = "";
19
- relpath = '';
20
- </script>
21
-
22
-
23
- <script type="text/javascript" charset="utf-8" src="js/jquery.js"></script>
24
-
25
- <script type="text/javascript" charset="utf-8" src="js/app.js"></script>
26
-
27
-
28
- </head>
29
- <body>
30
- <div class="nav_wrap">
31
- <iframe id="nav" src="class_list.html?1"></iframe>
32
- <div id="resizer"></div>
33
- </div>
34
-
35
- <div id="main" tabindex="-1">
36
- <div id="header">
37
- <div id="menu">
38
-
39
- <a href="_index.html">Index</a> &raquo;
40
-
41
-
42
- <span class="title">Top Level Namespace</span>
43
-
44
- </div>
45
-
46
- <div id="search">
47
-
48
- <a class="full_list_link" id="class_list_link"
49
- href="class_list.html">
50
-
51
- <svg width="24" height="24">
52
- <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
- <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
- <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
- </svg>
56
- </a>
57
-
58
- </div>
59
- <div class="clear"></div>
60
- </div>
61
-
62
- <div id="content"><h1>Top Level Namespace
63
-
64
-
65
-
66
- </h1>
67
- <div class="box_info">
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
- </div>
80
-
81
- <h2>Defined Under Namespace</h2>
82
- <p class="children">
83
-
84
-
85
- <strong class="modules">Modules:</strong> <span class='object_link'><a href="Schemacop.html" title="Schemacop (module)">Schemacop</a></span>
86
-
87
-
88
-
89
- <strong class="classes">Classes:</strong> <span class='object_link'><a href="ScopedEnv.html" title="ScopedEnv (class)">ScopedEnv</a></span>
90
-
91
-
92
- </p>
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
- </div>
103
-
104
- <div id="footer">
105
- Generated on Thu Jul 2 11:30:34 2020 by
106
- <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
- 0.9.20 (ruby-2.6.2).
108
- </div>
109
-
110
- </div>
111
- </body>
112
- </html>
@@ -1,139 +0,0 @@
1
- module Schemacop
2
- class Node
3
- attr_reader :options
4
-
5
- class_attribute :allowed_options
6
- self.allowed_options = {}.freeze
7
-
8
- class_attribute :symbols
9
- self.symbols = [].freeze
10
-
11
- class_attribute :klasses
12
- self.klasses = [].freeze
13
-
14
- def self.option(key, default: nil)
15
- self.allowed_options = allowed_options.merge(key => default)
16
- end
17
-
18
- option :if
19
- option :check
20
- option :cast
21
- option :default
22
-
23
- def type_label
24
- str = (symbols.first || 'unknown').to_s
25
- str += '*' if option?(:if)
26
- return str
27
- end
28
-
29
- def self.symbol(symbol)
30
- self.symbols += [symbol]
31
- end
32
-
33
- def self.clear_symbols
34
- self.symbols = [].freeze
35
- end
36
-
37
- def self.klass(klass)
38
- self.klasses += [klass]
39
- end
40
-
41
- def self.clear_klasses
42
- self.klasses = [].freeze
43
- end
44
-
45
- def self.register(symbols: [], klasses: [], clear: true, before: nil)
46
- NodeResolver.register(self, before: before)
47
- symbols = [*symbols]
48
- klasses = [*klasses]
49
- if clear
50
- clear_symbols
51
- clear_klasses
52
- end
53
- symbols.each { |s| symbol s }
54
- klasses.each { |k| klass k }
55
- end
56
-
57
- def self.type_matches?(type)
58
- symbol_matches?(type) || class_matches?(type)
59
- end
60
-
61
- def self.symbol_matches?(type)
62
- return false unless type.is_a?(Symbol)
63
- symbols.include?(type)
64
- end
65
-
66
- def self.class_matches?(type)
67
- return false unless type.is_a?(Class)
68
- klasses.each do |klass|
69
- return true if type <= klass
70
- end
71
- return false
72
- end
73
-
74
- def self.build(options, &block)
75
- new(options, &block)
76
- end
77
-
78
- def initialize(options = {})
79
- # Check and save given options
80
- @options = self.class.allowed_options.merge(options)
81
- if (obsolete_opts = @options.keys - self.class.allowed_options.keys).any?
82
- fail Exceptions::InvalidSchemaError,
83
- "Unrecognized option(s) #{obsolete_opts.inspect} for #{self.class.inspect}, allowed options: #{self.class.allowed_options.keys.inspect}."
84
- end
85
-
86
- if option?(:cast) && self.class.klasses.size > 1
87
- fail Exceptions::InvalidSchemaError,
88
- "Casting is only allowed for single-value datatypes, but type #{self.class.inspect} has classes "\
89
- "#{self.class.klasses.map(&:inspect)}."
90
- end
91
- end
92
-
93
- def option(key)
94
- options[key]
95
- end
96
-
97
- def option?(key)
98
- # rubocop:disable Style/DoubleNegation
99
- !!options[key]
100
- # rubocop:enable Style/DoubleNegation
101
- end
102
-
103
- def exec_block
104
- fail Exceptions::InvalidSchemaError, 'Node does not support block.' if block_given?
105
- end
106
-
107
- def resolve_type_klass(type)
108
- klass = NodeResolver.resolve(type)
109
- unless klass
110
- fail Exceptions::InvalidSchemaError, "No validation class found for type #{type.inspect}."
111
- end
112
- return klass
113
- end
114
-
115
- def validate(data, collector)
116
- validate_custom_check(data, collector)
117
- end
118
-
119
- def type_matches?(data)
120
- self.class.type_matches?(data.class) && type_filter_matches?(data)
121
- end
122
-
123
- def type_filter_matches?(data)
124
- !option?(:if) || option(:if).call(data)
125
- end
126
-
127
- protected
128
-
129
- def validate_custom_check(data, collector)
130
- if option?(:check) && (check_result = option(:check).call(data)) != true
131
- if check_result.is_a?(String)
132
- collector.error "Custom :check failed: #{check_result}."
133
- else
134
- collector.error 'Custom :check failed.'
135
- end
136
- end
137
- end
138
- end
139
- end
@@ -1,4 +0,0 @@
1
- module Schemacop
2
- class RootNode < NodeSupportingType
3
- end
4
- end
@@ -1,30 +0,0 @@
1
- module Schemacop
2
- class ArrayValidator < NodeSupportingType
3
- register symbols: :array, klasses: Array
4
-
5
- option :min # Minimal number of elements
6
- option :max # Maximal number of elements
7
- option :nil # Whether to allow nil values
8
-
9
- def initialize(*args)
10
- super
11
- type(:nil) if option(:nil)
12
- end
13
-
14
- def validate(data, collector)
15
- validate_custom_check(data, collector)
16
-
17
- if option?(:min) && data.size < option(:min)
18
- collector.error "Array must have more (>=) than #{option(:min)} elements."
19
- end
20
- if option?(:max) && data.size > option(:max)
21
- collector.error "Array must have less (<=) than #{option(:max)} elements."
22
- end
23
- data.each_with_index do |entry, index|
24
- collector.path("[#{index}]", index, :array) do
25
- validate_types(entry, collector)
26
- end
27
- end
28
- end
29
- end
30
- end
@@ -1,5 +0,0 @@
1
- module Schemacop
2
- class FloatValidator < NumberValidator
3
- register symbols: :float, klasses: Float, before: NumberValidator
4
- end
5
- end
@@ -1,35 +0,0 @@
1
- module Schemacop
2
- class HashValidator < NodeSupportingField
3
- register symbols: :hash, klasses: Hash
4
-
5
- option :allow_obsolete_keys
6
-
7
- def validate(data, collector)
8
- super
9
-
10
- if data.is_a? ActiveSupport::HashWithIndifferentAccess
11
- allowed_fields = @fields.keys.map { |k| k.is_a?(String) ? k.to_sym : k }
12
- data_keys = data.keys.map { |k| k.is_a?(String) ? k.to_sym : k }
13
-
14
- # If the same key is specified in the schema as string and symbol, we
15
- # definitely expect a Ruby hash and not one with indifferent access
16
- if @fields.keys.length != Set.new(allowed_fields).length
17
- fail Exceptions::ValidationError, 'Hash expected, but got ActiveSupport::HashWithIndifferentAccess.'
18
- end
19
- else
20
- allowed_fields = @fields.keys
21
- data_keys = data.keys
22
- end
23
-
24
- obsolete_keys = data_keys - allowed_fields
25
-
26
- unless option?(:allow_obsolete_keys)
27
- collector.error "Obsolete keys: #{obsolete_keys.inspect}." if obsolete_keys.any?
28
- end
29
-
30
- @fields.values.each do |field|
31
- field.validate(data, collector)
32
- end
33
- end
34
- end
35
- end
@@ -1,5 +0,0 @@
1
- module Schemacop
2
- class IntegerValidator < NumberValidator
3
- register symbols: :integer, klasses: Integer, before: NumberValidator
4
- end
5
- end
@@ -1,19 +0,0 @@
1
- module Schemacop
2
- class NumberValidator < Node
3
- register symbols: :number, klasses: [Integer, Float]
4
-
5
- option :min
6
- option :max
7
-
8
- def validate(data, collector)
9
- super
10
-
11
- if option?(:min) && data < option(:min)
12
- collector.error "Value must be >= #{option(:min)}."
13
- end
14
- if option?(:max) && data > option(:max)
15
- collector.error "Value must be <= #{option(:max)}."
16
- end
17
- end
18
- end
19
- end
@@ -1,27 +0,0 @@
1
- module Schemacop
2
- class ObjectValidator < Node
3
- register symbols: :object, klasses: BasicObject
4
-
5
- option :classes
6
- option :strict
7
-
8
- def type_label
9
- "#{super} (#{classes.join(', ')})"
10
- end
11
-
12
- def type_matches?(data)
13
- if option(:strict).is_a?(FalseClass)
14
- sub_or_class = classes.map { |klass| data.class <= klass }.include?(true)
15
- super && (classes.empty? || sub_or_class) && !data.nil?
16
- else
17
- super && (classes.empty? || classes.include?(data.class)) && !data.nil?
18
- end
19
- end
20
-
21
- private
22
-
23
- def classes
24
- [*option(:classes)]
25
- end
26
- end
27
- end
@@ -1,37 +0,0 @@
1
- module Schemacop
2
- class StringValidator < Node
3
- register symbols: :string, klasses: String
4
-
5
- option :min
6
- option :max
7
-
8
- def initialize(options = {})
9
- super(options)
10
-
11
- validate_options!
12
- end
13
-
14
- def validate(data, collector)
15
- super
16
-
17
- if option?(:min) && data.size < option(:min)
18
- collector.error "String must be longer (>=) than #{option(:min)} characters."
19
- end
20
- if option?(:max) && data.size > option(:max)
21
- collector.error "String must be shorter (<=) than #{option(:max)} characters."
22
- end
23
- end
24
-
25
- protected
26
-
27
- def validate_options!
28
- option_schema = Schema.new :integer, min: 0
29
-
30
- if option?(:min) && option_schema.invalid?(option(:min))
31
- fail Exceptions::InvalidSchemaError, 'String option :min must be an integer >= 0.'
32
- elsif option?(:max) && option_schema.invalid?(option(:max))
33
- fail Exceptions::InvalidSchemaError, 'String option :max must be an integer >= 0.'
34
- end
35
- end
36
- end
37
- end
@@ -1,118 +0,0 @@
1
- require 'test_helper'
2
-
3
- module Schemacop
4
- class CastingTest < Minitest::Test
5
- def test_basic
6
- s = Schema.new :integer, cast: [String]
7
-
8
- input = '42'
9
- output = s.validate!(input)
10
-
11
- assert_equal(42, output)
12
- end
13
-
14
- def test_field
15
- s = Schema.new do
16
- req :foo, :integer, cast: [String]
17
- end
18
-
19
- input = { foo: '42' }
20
- output = s.validate!(input)
21
-
22
- assert_equal({ foo: '42' }, input)
23
- assert_equal({ foo: 42 }, output)
24
- end
25
-
26
- def test_first_type_matches
27
- s = Schema.new do
28
- type TrueClass
29
- type :integer, cast: [String]
30
- end
31
-
32
- assert_equal(42, s.validate!('42'))
33
- assert_equal(42, s.validate!(42))
34
- assert_equal(true, s.validate!(true))
35
- end
36
-
37
- def test_with_if
38
- s = Schema.new do
39
- type Float, if: proc { |data| !data.is_a?(String) || data.match(/\d+\.\d+/) }, cast: [String]
40
- type Integer, cast: [String]
41
- end
42
-
43
- assert_equal 42.2, s.validate!('42.2')
44
- assert_equal 42, s.validate!('42')
45
- end
46
-
47
- def test_arrays
48
- s = Schema.new do
49
- req :foo, :array, :integer, cast: [String]
50
- end
51
-
52
- assert_equal(
53
- { foo: [1, 2, 3] },
54
- s.validate!(foo: %w(1 2 3))
55
- )
56
- end
57
-
58
- def test_check_after_cast
59
- s = Schema.new do
60
- type Integer, cast: [String], check: proc { |v| v > 41 }
61
- end
62
-
63
- assert_equal 42, s.validate!('42')
64
- assert_equal 43, s.validate!('43')
65
- assert_equal 42, s.validate!(42)
66
- assert_verr { s.validate!('41') }
67
- assert_verr { s.validate!(42.2) }
68
- end
69
-
70
- def test_multilple_types
71
- e = assert_raises Exceptions::InvalidSchemaError do
72
- Schema.new do
73
- type :number, cast: [String]
74
- end
75
- end
76
-
77
- assert_equal 'Casting is only allowed for single-value datatypes, '\
78
- 'but type Schemacop::NumberValidator has classes ["Integer", "Float"].',
79
- e.message
80
- end
81
-
82
- def test_custom_castings
83
- s = Schema.new do
84
- type :integer, cast: { String => proc { |v| Integer(v) } }
85
- end
86
-
87
- assert_equal 42, s.validate!('42')
88
- end
89
-
90
- def test_decimal_basis_castings
91
- s = Schema.new do
92
- type :integer, cast: [String]
93
- end
94
-
95
- assert_equal 1, s.validate!('01')
96
- assert_equal 8, s.validate!('08')
97
- assert_equal 11, s.validate!('011')
98
- end
99
-
100
- def test_string_to_nil_castings
101
- s = Schema.new do
102
- opt :int_field, :integer, cast: [String]
103
- opt :float_field, :float, cast: [String]
104
- end
105
-
106
- expected_int = { int_field: nil }
107
- expected_float = { float_field: nil }
108
-
109
- assert_equal expected_int, s.validate!(int_field: nil)
110
- assert_equal expected_int, s.validate!(int_field: "")
111
- assert_equal expected_int, s.validate!(int_field: " ")
112
-
113
- assert_equal expected_float, s.validate!(float_field: nil)
114
- assert_equal expected_float, s.validate!(float_field: "")
115
- assert_equal expected_float, s.validate!(float_field: " ")
116
- end
117
- end
118
- end