schemacop 2.3.0 → 2.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +41 -0
  3. data/LICENSE +1 -1
  4. data/README.md +204 -14
  5. data/RUBY_VERSION +1 -1
  6. data/Rakefile +6 -5
  7. data/VERSION +1 -1
  8. data/doc/Schemacop.html +32 -5
  9. data/doc/Schemacop/ArrayValidator.html +4 -4
  10. data/doc/Schemacop/BooleanValidator.html +4 -4
  11. data/doc/Schemacop/Caster.html +379 -0
  12. data/doc/Schemacop/Collector.html +180 -104
  13. data/doc/Schemacop/Exceptions.html +3 -3
  14. data/doc/Schemacop/Exceptions/InvalidSchemaError.html +3 -3
  15. data/doc/Schemacop/Exceptions/ValidationError.html +3 -3
  16. data/doc/Schemacop/FieldNode.html +19 -7
  17. data/doc/Schemacop/FloatValidator.html +4 -4
  18. data/doc/Schemacop/HashValidator.html +4 -4
  19. data/doc/Schemacop/IntegerValidator.html +4 -4
  20. data/doc/Schemacop/NilValidator.html +4 -4
  21. data/doc/Schemacop/Node.html +97 -85
  22. data/doc/Schemacop/NodeResolver.html +28 -12
  23. data/doc/Schemacop/NodeSupportingField.html +4 -4
  24. data/doc/Schemacop/NodeSupportingType.html +5 -7
  25. data/doc/Schemacop/NodeWithBlock.html +4 -4
  26. data/doc/Schemacop/NumberValidator.html +4 -4
  27. data/doc/Schemacop/ObjectValidator.html +3 -3
  28. data/doc/Schemacop/RootNode.html +4 -4
  29. data/doc/Schemacop/Schema.html +5 -5
  30. data/doc/Schemacop/StringValidator.html +3 -3
  31. data/doc/Schemacop/SymbolValidator.html +4 -4
  32. data/doc/ScopedEnv.html +3 -3
  33. data/doc/_index.html +11 -4
  34. data/doc/class_list.html +1 -1
  35. data/doc/css/style.css +10 -6
  36. data/doc/file.README.html +198 -16
  37. data/doc/frames.html +1 -1
  38. data/doc/index.html +198 -16
  39. data/doc/js/app.js +55 -0
  40. data/doc/method_list.html +81 -49
  41. data/doc/top-level-namespace.html +3 -3
  42. data/lib/schemacop.rb +14 -0
  43. data/lib/schemacop/caster.rb +38 -0
  44. data/lib/schemacop/collector.rb +34 -6
  45. data/lib/schemacop/field_node.rb +24 -3
  46. data/lib/schemacop/node.rb +16 -4
  47. data/lib/schemacop/node_resolver.rb +10 -2
  48. data/lib/schemacop/node_supporting_type.rb +19 -1
  49. data/lib/schemacop/schema.rb +2 -2
  50. data/lib/schemacop/validator/array_validator.rb +1 -1
  51. data/lib/schemacop/validator/float_validator.rb +1 -1
  52. data/lib/schemacop/validator/integer_validator.rb +1 -1
  53. data/lib/schemacop/validator/object_validator.rb +1 -1
  54. data/schemacop.gemspec +15 -9
  55. data/test/casting_test.rb +90 -0
  56. data/test/custom_check_test.rb +20 -13
  57. data/test/custom_if_test.rb +12 -12
  58. data/test/defaults_test.rb +71 -0
  59. data/test/nil_dis_allow_test.rb +6 -6
  60. data/test/node_resolver_test.rb +26 -0
  61. data/test/short_forms_test.rb +84 -66
  62. data/test/test_helper.rb +7 -0
  63. data/test/types_test.rb +5 -5
  64. data/test/validator_array_test.rb +16 -16
  65. data/test/validator_boolean_test.rb +2 -2
  66. data/test/validator_float_test.rb +15 -15
  67. data/test/validator_hash_test.rb +5 -5
  68. data/test/validator_integer_test.rb +9 -9
  69. data/test/validator_nil_test.rb +1 -1
  70. data/test/validator_number_test.rb +19 -19
  71. data/test/validator_object_test.rb +52 -18
  72. data/test/validator_string_test.rb +12 -12
  73. data/test/validator_symbol_test.rb +2 -2
  74. metadata +43 -14
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  File: README
8
8
 
9
- &mdash; Documentation by YARD 0.9.9
9
+ &mdash; Documentation by YARD 0.9.20
10
10
 
11
11
  </title>
12
12
 
@@ -161,7 +161,7 @@ this:</p>
161
161
  <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
162
162
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span>
163
163
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:hash</span> <span class='kw'>do</span>
164
- <span class='id identifier rubyid_req'>req</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>name</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
164
+ <span class='id identifier rubyid_req'>req</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>present</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
165
165
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:boolean</span>
166
166
  <span class='kw'>end</span>
167
167
  <span class='kw'>end</span>
@@ -177,12 +177,38 @@ FalseClass).</p>
177
177
  <h3><code>validate</code> vs <code>validate!</code> vs <code>valid?</code></h3>
178
178
 
179
179
  <p>The method <code>validate</code> will return a <code>Collector</code> object that contains all
180
- validation errors (if any), whereas <code>validate!</code> will accumulate all violations
181
- and finally throw an exception describing them.</p>
180
+ validation errors (if any) as well as a deep copy of your data with applied
181
+ defaults and castings, whereas <code>validate!</code> will accumulate all violations
182
+ and finally throw an exception describing them or, if the validation was
183
+ successful, a deep-copy of your supplied data with defaults and castings
184
+ applied.</p>
182
185
 
183
186
  <p>For simply querying the validity of some data, use the methods <code>valid?</code> or
184
187
  <code>invalid?</code>.</p>
185
188
 
189
+ <p>Examples:</p>
190
+
191
+ <pre class="code ruby"><code class="ruby"><span class='comment'># validate! returns your modified data or throws a validation error
192
+ </span><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
193
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
194
+ <span class='kw'>end</span>
195
+ <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span> <span class='comment'># =&gt; { foo: 42 }
196
+ </span>
197
+ <span class='comment'># validate returns a collector
198
+ </span><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
199
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
200
+ <span class='kw'>end</span>
201
+
202
+ <span class='id identifier rubyid_collector'>collector</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate'>validate</span><span class='lparen'>(</span><span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
203
+ <span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span> <span class='comment'># true
204
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; { foo: 42 }
205
+ </span>
206
+ <span class='id identifier rubyid_collector'>collector</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate'>validate</span><span class='lparen'>(</span><span class='lbrace'>{</span> <span class='label'>foo:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>invalid</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
207
+ <span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span> <span class='comment'># false
208
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; nil
209
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_exceptions'>exceptions</span> <span class='comment'># =&gt; Validation error
210
+ </span></code></pre>
211
+
186
212
  <h2>Schemacop&#39;s DSL</h2>
187
213
 
188
214
  <p>In this section, we will ignore <a href="#short-forms">short forms</a> and explicitly
@@ -235,7 +261,7 @@ proc returns false.&quot;</p>
235
261
 
236
262
  <p>The corresponding schema would look as follows:</p>
237
263
 
238
- <pre class="code ruby"><code class="ruby"><span class='const'>Schma</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
264
+ <pre class="code ruby"><code class="ruby"><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
239
265
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>if:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_data'>data</span><span class='op'>|</span> <span class='id identifier rubyid_data'>data</span><span class='period'>.</span><span class='id identifier rubyid_odd?'>odd?</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>max:</span> <span class='int'>15</span>
240
266
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span>
241
267
  <span class='kw'>end</span>
@@ -256,8 +282,8 @@ the type checking, meaning that it only gets executed if the data has the right
256
282
  type and the proc in <code>if</code> (if any) has returned true.</p>
257
283
 
258
284
  <p>The proc passed to the <code>check</code> option is given the data being analyzed. It is to
259
- return true if the data passes the custom check. If it returns false, Schemacop
260
- considers the data to be invalid.</p>
285
+ return true if the data passes the custom check. If it returns false or an error
286
+ message as a string, Schemacop considers the data to be invalid.</p>
261
287
 
262
288
  <p>The following example illustrates the use of the option <code>check</code>: Consider a
263
289
  scenario in which you want the following rule set:</p>
@@ -278,6 +304,15 @@ scenario in which you want the following rule set:</p>
278
304
  <p>The above Type Line has type <code>:string</code> and two options (<code>min</code> and <code>check</code>). The
279
305
  option <code>min</code> is supported by the <code>:string</code> validator (covered later).</p>
280
306
 
307
+ <p>You can also specify a custom error message by returning a string:</p>
308
+
309
+ <pre class="code ruby"><code class="ruby"><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
310
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>check:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span><span class='period'>.</span><span class='id identifier rubyid_even?'>even?</span> <span class='op'>?</span> <span class='kw'>true</span> <span class='op'>:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Custom error</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span>
311
+ <span class='kw'>end</span>
312
+ </code></pre>
313
+
314
+ <p>This will include <code>Custom error</code> in the validation error message.</p>
315
+
281
316
  <h3>Field Line</h3>
282
317
 
283
318
  <p>Inside a Type Line of type <code>:hash</code>, you may specify an arbitrary number of field
@@ -531,6 +566,10 @@ write Field Lines in the schema instantiation:</p>
531
566
  <span class='kw'>end</span>
532
567
  </code></pre>
533
568
 
569
+ <p>Note that this does not allow you to specify any options for the hash itself.
570
+ You still need to specify <code>:hash</code> as a type if you want to pass any options to
571
+ the hash (i.e. a <code>default</code>).</p>
572
+
534
573
  <h3>Shortform for subtypes</h3>
535
574
 
536
575
  <p>In case of nested arrays, you can group all Type Lines to a single one.</p>
@@ -586,6 +625,145 @@ of type Array with children of type Array with children of type Hash in which at
586
625
  least one of the Symbol keys <code>:food</code> and <code>:drink</code> (with any non-nil value type)
587
626
  is present.</p>
588
627
 
628
+ <h2>Defaults</h2>
629
+
630
+ <p>Starting from version 2.4.0, Schemacop allows you to define default values at
631
+ any point in your schema. If the validated data contains a nil value, it will be
632
+ substituted by the given default value.</p>
633
+
634
+ <p>Note that Schemacop never modifies the data you pass to it. If you want to
635
+ benefit from Schemacop-applied defaults, you need to access the cloned, modified
636
+ data returned by <code>validate</code> or <code>validate!</code>.</p>
637
+
638
+ <p>Applying defaults is done before validating the substructure and before any type
639
+ casting. The provided default will be validated same as user-supplied data, so
640
+ if your given default does not validate properly, a validation error is thrown.
641
+ Make sure your default values always match the underlying schema.</p>
642
+
643
+ <p>Defaults can be specified at any point:</p>
644
+
645
+ <pre class="code ruby"><code class="ruby"><span class='comment'># Basic usage
646
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
647
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hello World</span><span class='tstring_end'>&#39;</span></span>
648
+ <span class='kw'>end</span>
649
+
650
+ <span class='comment'># The default given for the first type will match
651
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
652
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hello World</span><span class='tstring_end'>&#39;</span></span> <span class='comment'># This will always be applied of no value is supplied
653
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
654
+ <span class='kw'>end</span>
655
+
656
+ <span class='comment'># You can also pass entire hashes or arrays to your defaults
657
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
658
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='symbol'>:hash</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbrace'>{</span> <span class='label'>foo:</span> <span class='symbol'>:bar</span> <span class='rbrace'>}</span> <span class='kw'>do</span>
659
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='symbol'>:symbol</span>
660
+ <span class='kw'>end</span>
661
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:bar</span><span class='comma'>,</span> <span class='symbol'>:array</span><span class='comma'>,</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbracket'>[</span><span class='int'>1</span><span class='comma'>,</span> <span class='int'>2</span><span class='comma'>,</span> <span class='int'>3</span><span class='rbracket'>]</span>
662
+ <span class='kw'>end</span>
663
+
664
+ <span class='comment'># Defaults must match the given schema. The following will fail.
665
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
666
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbrace'>{</span> <span class='label'>bar:</span> <span class='symbol'>:baz</span> <span class='rbrace'>}</span> <span class='kw'>do</span>
667
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span>
668
+ <span class='kw'>end</span>
669
+ <span class='kw'>end</span>
670
+ </code></pre>
671
+
672
+ <h3>Required data points</h3>
673
+
674
+ <p>Note that any <em>required</em> validation is done before applying the defaults. If you
675
+ specify a <code>req</code> field, it must always be given, no matter if you have specified
676
+ a default or not. Therefore, specifying <code>req</code> fields do not make sense in
677
+ conjunction with defaults, as the default is always ignored.</p>
678
+
679
+ <h2>Type casting</h2>
680
+
681
+ <p>Starting from version 2.4.0, Schemacop allows you to specify type castings that
682
+ can alter the validated data. Consider the following:</p>
683
+
684
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
685
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:id</span><span class='comma'>,</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>cast:</span> <span class='lbracket'>[</span><span class='const'>String</span><span class='rbracket'>]</span>
686
+ <span class='kw'>end</span>
687
+
688
+ <span class='id identifier rubyid_data'>data</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='label'>id:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>42</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span>
689
+ <span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; { id: 42 }
690
+ </span></code></pre>
691
+
692
+ <p>Note that Schemacop never modifies the data you pass to it. If you want to
693
+ benefit from Schemacop-applied castings, you need to access the cloned, modified
694
+ data returned by <code>validate</code> or <code>validate!</code>.</p>
695
+
696
+ <h3>Specifying type castings</h3>
697
+
698
+ <p>Type castings can be specified using two forms: Either as a hash or as an array.
699
+ While using an array only allows you to specify the supported source types to be
700
+ casted, using a hash allows you to specify custom casting logic as blocks.</p>
701
+
702
+ <p>For hashes, the key must be a class and the value must be either <code>:default</code> for
703
+ using a built-in caster or a callable object (proc or lambda) that receives the
704
+ value and is supposed to cast it. If the value can&#39;t be casted, the proc must
705
+ fail with an exception. The exception message will then be contained in the
706
+ collected validation errors.</p>
707
+
708
+ <p>Example:</p>
709
+
710
+ <pre class="code ruby"><code class="ruby">Schema.new do
711
+ # Pass array to `cast`. This enables casting from String or Float to Integer
712
+ # using the built-in casters.
713
+ req: id_1, :integer, cast: [String, Float]
714
+
715
+ # Pass hash to `cast`. This enables casting from Float to Integer using the
716
+ # built-in caster and from String to Integer using a custom callback.
717
+ req :id_2, :integer, cast: { Float =&gt; :default, String =&gt; proc { |s| Integer(s) }
718
+ end
719
+ </code></pre>
720
+
721
+ <h3>Built-in casters</h3>
722
+
723
+ <p>Schemacop comes with the following casters:</p>
724
+
725
+ <ul>
726
+ <li><code>String</code> to <code>Integer</code> and <code>Float</code></li>
727
+ <li><code>Float</code> to <code>Integer</code></li>
728
+ <li><code>Integer</code> to <code>Float</code></li>
729
+ </ul>
730
+
731
+ <p>Note that all built-in casters are precise, so the string <code>foo</code> will fail with
732
+ an error if casted to an Integer. When casting float values and strings
733
+ containing float values to integers, the decimal places will be discarded
734
+ however.</p>
735
+
736
+ <h3>Execution order</h3>
737
+
738
+ <p>The casting is done <em>before</em> the options <code>if</code> and <code>check</code> are evaluated.
739
+ Example:</p>
740
+
741
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
742
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>if:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span> <span class='op'>==</span> <span class='int'>42</span> <span class='rbrace'>}</span> <span class='comment'># 1
743
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>check:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span> <span class='op'>&lt;</span> <span class='int'>3</span> <span class='rbrace'>}</span> <span class='comment'># 2
744
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span>
745
+ <span class='kw'>end</span>
746
+
747
+ <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>42</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 1 will match
748
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>2</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 2 will match
749
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>234</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 3 will match
750
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='int'>5</span><span class='rparen'>)</span> <span class='comment'># Will fail, as nothing matches
751
+ </span></code></pre>
752
+
753
+ <h3>Caveats</h3>
754
+
755
+ <p>Casting only works with type definitions that only include one type. For
756
+ instance, the <code>Numeric</code> validator includes both <code>Integer</code> and <code>Float</code>, which
757
+ would made it unclear what to cast a string into:</p>
758
+
759
+ <pre class="code ruby"><code class="ruby"><span class='comment'># This does not work, as it is unclear whether to cast the String into an
760
+ </span><span class='comment'># Integer or a Float.
761
+ </span><span class='id identifier rubyid_type'>type</span> <span class='symbol'>:number</span><span class='comma'>,</span> <span class='label'>cast:</span> <span class='lbracket'>[</span><span class='const'>String</span><span class='rbracket'>]</span>
762
+ </code></pre>
763
+
764
+ <p>The same also applies to booleans, as they compound both <code>TrueClass</code> and
765
+ <code>FalseClass</code>. This may be tackled in future releases.</p>
766
+
589
767
  <h2>Exceptions</h2>
590
768
 
591
769
  <p>Schemacop will throw one of the following checked exceptions:</p>
@@ -607,28 +785,32 @@ is present.</p>
607
785
 
608
786
  <ul>
609
787
  <li><p>Schemacop does not yet allow cyclic structures with infinite depth.</p></li>
610
- <li><p>Schemacop aborts when it encounters an error. It is not able to collect a full
611
- list of multiple errors.</p></li>
612
788
  <li><p>Schemacop is not made for validating complex causalities (i.e. field <code>a</code>
613
789
  needs to be given only if field <code>b</code> is present).</p></li>
614
790
  <li><p>Schemacop does not yet support string regex matching.</p></li>
615
791
  </ul>
616
792
 
617
- <h2>Contributors</h2>
793
+ <h2>Development</h2>
794
+
795
+ <p>To run tests:</p>
618
796
 
619
- <p>Thanks to <a href="https://github.com/bbatsov/rubocop">Rubocop</a> for great inspiration
620
- concerning their name and the structure of their README file. And special thanks
621
- to <a href="http://www.subgit.com/">SubGit</a> for their great open source licensing.</p>
797
+ <ul>
798
+ <li><p>Check out the source</p></li>
799
+ <li><p>Run <code>bundle install</code></p></li>
800
+ <li><p>Run <code>bundle exec rake test</code> to run all tests</p></li>
801
+ <li><p>Run <code>bundle exec rake test TEST=test/unit/some/file.rb</code> to run a single test
802
+ file</p></li>
803
+ </ul>
622
804
 
623
805
  <h2>Copyright</h2>
624
806
 
625
- <p>Copyright (c) 2017 Sitrox. See <code>LICENSE</code> for further details.</p>
807
+ <p>Copyright (c) 2019 Sitrox. See <code>LICENSE</code> for further details.</p>
626
808
  </div></div>
627
809
 
628
810
  <div id="footer">
629
- Generated on Thu May 18 13:17:23 2017 by
811
+ Generated on Tue Nov 5 11:16:27 2019 by
630
812
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
631
- 0.9.9 (ruby-2.3.1).
813
+ 0.9.20 (ruby-2.6.2).
632
814
  </div>
633
815
 
634
816
  </div>
@@ -2,7 +2,7 @@
2
2
  <html>
3
3
  <head>
4
4
  <meta charset="utf-8">
5
- <title>Documentation by YARD 0.9.9</title>
5
+ <title>Documentation by YARD 0.9.20</title>
6
6
  </head>
7
7
  <script type="text/javascript" charset="utf-8">
8
8
  var match = unescape(window.location.hash).match(/^#!(.+)/);
@@ -6,7 +6,7 @@
6
6
  <title>
7
7
  File: README
8
8
 
9
- &mdash; Documentation by YARD 0.9.9
9
+ &mdash; Documentation by YARD 0.9.20
10
10
 
11
11
  </title>
12
12
 
@@ -161,7 +161,7 @@ this:</p>
161
161
  <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
162
162
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span>
163
163
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:hash</span> <span class='kw'>do</span>
164
- <span class='id identifier rubyid_req'>req</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>name</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
164
+ <span class='id identifier rubyid_req'>req</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>present</span><span class='tstring_end'>&#39;</span></span> <span class='kw'>do</span>
165
165
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:boolean</span>
166
166
  <span class='kw'>end</span>
167
167
  <span class='kw'>end</span>
@@ -177,12 +177,38 @@ FalseClass).</p>
177
177
  <h3><code>validate</code> vs <code>validate!</code> vs <code>valid?</code></h3>
178
178
 
179
179
  <p>The method <code>validate</code> will return a <code>Collector</code> object that contains all
180
- validation errors (if any), whereas <code>validate!</code> will accumulate all violations
181
- and finally throw an exception describing them.</p>
180
+ validation errors (if any) as well as a deep copy of your data with applied
181
+ defaults and castings, whereas <code>validate!</code> will accumulate all violations
182
+ and finally throw an exception describing them or, if the validation was
183
+ successful, a deep-copy of your supplied data with defaults and castings
184
+ applied.</p>
182
185
 
183
186
  <p>For simply querying the validity of some data, use the methods <code>valid?</code> or
184
187
  <code>invalid?</code>.</p>
185
188
 
189
+ <p>Examples:</p>
190
+
191
+ <pre class="code ruby"><code class="ruby"><span class='comment'># validate! returns your modified data or throws a validation error
192
+ </span><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
193
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
194
+ <span class='kw'>end</span>
195
+ <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span> <span class='comment'># =&gt; { foo: 42 }
196
+ </span>
197
+ <span class='comment'># validate returns a collector
198
+ </span><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
199
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
200
+ <span class='kw'>end</span>
201
+
202
+ <span class='id identifier rubyid_collector'>collector</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate'>validate</span><span class='lparen'>(</span><span class='lbrace'>{</span><span class='rbrace'>}</span><span class='rparen'>)</span>
203
+ <span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span> <span class='comment'># true
204
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; { foo: 42 }
205
+ </span>
206
+ <span class='id identifier rubyid_collector'>collector</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate'>validate</span><span class='lparen'>(</span><span class='lbrace'>{</span> <span class='label'>foo:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>invalid</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span><span class='rparen'>)</span>
207
+ <span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_valid?'>valid?</span> <span class='comment'># false
208
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; nil
209
+ </span><span class='id identifier rubyid_collector'>collector</span><span class='period'>.</span><span class='id identifier rubyid_exceptions'>exceptions</span> <span class='comment'># =&gt; Validation error
210
+ </span></code></pre>
211
+
186
212
  <h2>Schemacop&#39;s DSL</h2>
187
213
 
188
214
  <p>In this section, we will ignore <a href="#short-forms">short forms</a> and explicitly
@@ -235,7 +261,7 @@ proc returns false.&quot;</p>
235
261
 
236
262
  <p>The corresponding schema would look as follows:</p>
237
263
 
238
- <pre class="code ruby"><code class="ruby"><span class='const'>Schma</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
264
+ <pre class="code ruby"><code class="ruby"><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
239
265
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>if:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_data'>data</span><span class='op'>|</span> <span class='id identifier rubyid_data'>data</span><span class='period'>.</span><span class='id identifier rubyid_odd?'>odd?</span> <span class='rbrace'>}</span><span class='comma'>,</span> <span class='label'>max:</span> <span class='int'>15</span>
240
266
  <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span>
241
267
  <span class='kw'>end</span>
@@ -256,8 +282,8 @@ the type checking, meaning that it only gets executed if the data has the right
256
282
  type and the proc in <code>if</code> (if any) has returned true.</p>
257
283
 
258
284
  <p>The proc passed to the <code>check</code> option is given the data being analyzed. It is to
259
- return true if the data passes the custom check. If it returns false, Schemacop
260
- considers the data to be invalid.</p>
285
+ return true if the data passes the custom check. If it returns false or an error
286
+ message as a string, Schemacop considers the data to be invalid.</p>
261
287
 
262
288
  <p>The following example illustrates the use of the option <code>check</code>: Consider a
263
289
  scenario in which you want the following rule set:</p>
@@ -278,6 +304,15 @@ scenario in which you want the following rule set:</p>
278
304
  <p>The above Type Line has type <code>:string</code> and two options (<code>min</code> and <code>check</code>). The
279
305
  option <code>min</code> is supported by the <code>:string</code> validator (covered later).</p>
280
306
 
307
+ <p>You can also specify a custom error message by returning a string:</p>
308
+
309
+ <pre class="code ruby"><code class="ruby"><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
310
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>check:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span><span class='period'>.</span><span class='id identifier rubyid_even?'>even?</span> <span class='op'>?</span> <span class='kw'>true</span> <span class='op'>:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Custom error</span><span class='tstring_end'>&#39;</span></span> <span class='rbrace'>}</span>
311
+ <span class='kw'>end</span>
312
+ </code></pre>
313
+
314
+ <p>This will include <code>Custom error</code> in the validation error message.</p>
315
+
281
316
  <h3>Field Line</h3>
282
317
 
283
318
  <p>Inside a Type Line of type <code>:hash</code>, you may specify an arbitrary number of field
@@ -531,6 +566,10 @@ write Field Lines in the schema instantiation:</p>
531
566
  <span class='kw'>end</span>
532
567
  </code></pre>
533
568
 
569
+ <p>Note that this does not allow you to specify any options for the hash itself.
570
+ You still need to specify <code>:hash</code> as a type if you want to pass any options to
571
+ the hash (i.e. a <code>default</code>).</p>
572
+
534
573
  <h3>Shortform for subtypes</h3>
535
574
 
536
575
  <p>In case of nested arrays, you can group all Type Lines to a single one.</p>
@@ -586,6 +625,145 @@ of type Array with children of type Array with children of type Hash in which at
586
625
  least one of the Symbol keys <code>:food</code> and <code>:drink</code> (with any non-nil value type)
587
626
  is present.</p>
588
627
 
628
+ <h2>Defaults</h2>
629
+
630
+ <p>Starting from version 2.4.0, Schemacop allows you to define default values at
631
+ any point in your schema. If the validated data contains a nil value, it will be
632
+ substituted by the given default value.</p>
633
+
634
+ <p>Note that Schemacop never modifies the data you pass to it. If you want to
635
+ benefit from Schemacop-applied defaults, you need to access the cloned, modified
636
+ data returned by <code>validate</code> or <code>validate!</code>.</p>
637
+
638
+ <p>Applying defaults is done before validating the substructure and before any type
639
+ casting. The provided default will be validated same as user-supplied data, so
640
+ if your given default does not validate properly, a validation error is thrown.
641
+ Make sure your default values always match the underlying schema.</p>
642
+
643
+ <p>Defaults can be specified at any point:</p>
644
+
645
+ <pre class="code ruby"><code class="ruby"><span class='comment'># Basic usage
646
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
647
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hello World</span><span class='tstring_end'>&#39;</span></span>
648
+ <span class='kw'>end</span>
649
+
650
+ <span class='comment'># The default given for the first type will match
651
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
652
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>Hello World</span><span class='tstring_end'>&#39;</span></span> <span class='comment'># This will always be applied of no value is supplied
653
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='int'>42</span>
654
+ <span class='kw'>end</span>
655
+
656
+ <span class='comment'># You can also pass entire hashes or arrays to your defaults
657
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
658
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='symbol'>:hash</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbrace'>{</span> <span class='label'>foo:</span> <span class='symbol'>:bar</span> <span class='rbrace'>}</span> <span class='kw'>do</span>
659
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='symbol'>:symbol</span>
660
+ <span class='kw'>end</span>
661
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:bar</span><span class='comma'>,</span> <span class='symbol'>:array</span><span class='comma'>,</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbracket'>[</span><span class='int'>1</span><span class='comma'>,</span> <span class='int'>2</span><span class='comma'>,</span> <span class='int'>3</span><span class='rbracket'>]</span>
662
+ <span class='kw'>end</span>
663
+
664
+ <span class='comment'># Defaults must match the given schema. The following will fail.
665
+ </span><span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
666
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span><span class='comma'>,</span> <span class='label'>default:</span> <span class='lbrace'>{</span> <span class='label'>bar:</span> <span class='symbol'>:baz</span> <span class='rbrace'>}</span> <span class='kw'>do</span>
667
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:foo</span>
668
+ <span class='kw'>end</span>
669
+ <span class='kw'>end</span>
670
+ </code></pre>
671
+
672
+ <h3>Required data points</h3>
673
+
674
+ <p>Note that any <em>required</em> validation is done before applying the defaults. If you
675
+ specify a <code>req</code> field, it must always be given, no matter if you have specified
676
+ a default or not. Therefore, specifying <code>req</code> fields do not make sense in
677
+ conjunction with defaults, as the default is always ignored.</p>
678
+
679
+ <h2>Type casting</h2>
680
+
681
+ <p>Starting from version 2.4.0, Schemacop allows you to specify type castings that
682
+ can alter the validated data. Consider the following:</p>
683
+
684
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
685
+ <span class='id identifier rubyid_req'>req</span> <span class='symbol'>:id</span><span class='comma'>,</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>cast:</span> <span class='lbracket'>[</span><span class='const'>String</span><span class='rbracket'>]</span>
686
+ <span class='kw'>end</span>
687
+
688
+ <span class='id identifier rubyid_data'>data</span> <span class='op'>=</span> <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='label'>id:</span> <span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>42</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span>
689
+ <span class='id identifier rubyid_data'>data</span> <span class='comment'># =&gt; { id: 42 }
690
+ </span></code></pre>
691
+
692
+ <p>Note that Schemacop never modifies the data you pass to it. If you want to
693
+ benefit from Schemacop-applied castings, you need to access the cloned, modified
694
+ data returned by <code>validate</code> or <code>validate!</code>.</p>
695
+
696
+ <h3>Specifying type castings</h3>
697
+
698
+ <p>Type castings can be specified using two forms: Either as a hash or as an array.
699
+ While using an array only allows you to specify the supported source types to be
700
+ casted, using a hash allows you to specify custom casting logic as blocks.</p>
701
+
702
+ <p>For hashes, the key must be a class and the value must be either <code>:default</code> for
703
+ using a built-in caster or a callable object (proc or lambda) that receives the
704
+ value and is supposed to cast it. If the value can&#39;t be casted, the proc must
705
+ fail with an exception. The exception message will then be contained in the
706
+ collected validation errors.</p>
707
+
708
+ <p>Example:</p>
709
+
710
+ <pre class="code ruby"><code class="ruby">Schema.new do
711
+ # Pass array to `cast`. This enables casting from String or Float to Integer
712
+ # using the built-in casters.
713
+ req: id_1, :integer, cast: [String, Float]
714
+
715
+ # Pass hash to `cast`. This enables casting from Float to Integer using the
716
+ # built-in caster and from String to Integer using a custom callback.
717
+ req :id_2, :integer, cast: { Float =&gt; :default, String =&gt; proc { |s| Integer(s) }
718
+ end
719
+ </code></pre>
720
+
721
+ <h3>Built-in casters</h3>
722
+
723
+ <p>Schemacop comes with the following casters:</p>
724
+
725
+ <ul>
726
+ <li><code>String</code> to <code>Integer</code> and <code>Float</code></li>
727
+ <li><code>Float</code> to <code>Integer</code></li>
728
+ <li><code>Integer</code> to <code>Float</code></li>
729
+ </ul>
730
+
731
+ <p>Note that all built-in casters are precise, so the string <code>foo</code> will fail with
732
+ an error if casted to an Integer. When casting float values and strings
733
+ containing float values to integers, the decimal places will be discarded
734
+ however.</p>
735
+
736
+ <h3>Execution order</h3>
737
+
738
+ <p>The casting is done <em>before</em> the options <code>if</code> and <code>check</code> are evaluated.
739
+ Example:</p>
740
+
741
+ <pre class="code ruby"><code class="ruby"><span class='id identifier rubyid_s'>s</span> <span class='op'>=</span> <span class='const'>Schema</span><span class='period'>.</span><span class='id identifier rubyid_new'>new</span> <span class='kw'>do</span>
742
+ <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>if:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span> <span class='op'>==</span> <span class='int'>42</span> <span class='rbrace'>}</span> <span class='comment'># 1
743
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:integer</span><span class='comma'>,</span> <span class='label'>check:</span> <span class='id identifier rubyid_proc'>proc</span> <span class='lbrace'>{</span> <span class='op'>|</span><span class='id identifier rubyid_i'>i</span><span class='op'>|</span> <span class='id identifier rubyid_i'>i</span> <span class='op'>&lt;</span> <span class='int'>3</span> <span class='rbrace'>}</span> <span class='comment'># 2
744
+ </span> <span class='id identifier rubyid_type'>type</span> <span class='symbol'>:string</span>
745
+ <span class='kw'>end</span>
746
+
747
+ <span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>42</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 1 will match
748
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>2</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 2 will match
749
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='tstring'><span class='tstring_beg'>&#39;</span><span class='tstring_content'>234</span><span class='tstring_end'>&#39;</span></span><span class='rparen'>)</span> <span class='comment'># 3 will match
750
+ </span><span class='id identifier rubyid_s'>s</span><span class='period'>.</span><span class='id identifier rubyid_validate!'>validate!</span><span class='lparen'>(</span><span class='int'>5</span><span class='rparen'>)</span> <span class='comment'># Will fail, as nothing matches
751
+ </span></code></pre>
752
+
753
+ <h3>Caveats</h3>
754
+
755
+ <p>Casting only works with type definitions that only include one type. For
756
+ instance, the <code>Numeric</code> validator includes both <code>Integer</code> and <code>Float</code>, which
757
+ would made it unclear what to cast a string into:</p>
758
+
759
+ <pre class="code ruby"><code class="ruby"><span class='comment'># This does not work, as it is unclear whether to cast the String into an
760
+ </span><span class='comment'># Integer or a Float.
761
+ </span><span class='id identifier rubyid_type'>type</span> <span class='symbol'>:number</span><span class='comma'>,</span> <span class='label'>cast:</span> <span class='lbracket'>[</span><span class='const'>String</span><span class='rbracket'>]</span>
762
+ </code></pre>
763
+
764
+ <p>The same also applies to booleans, as they compound both <code>TrueClass</code> and
765
+ <code>FalseClass</code>. This may be tackled in future releases.</p>
766
+
589
767
  <h2>Exceptions</h2>
590
768
 
591
769
  <p>Schemacop will throw one of the following checked exceptions:</p>
@@ -607,28 +785,32 @@ is present.</p>
607
785
 
608
786
  <ul>
609
787
  <li><p>Schemacop does not yet allow cyclic structures with infinite depth.</p></li>
610
- <li><p>Schemacop aborts when it encounters an error. It is not able to collect a full
611
- list of multiple errors.</p></li>
612
788
  <li><p>Schemacop is not made for validating complex causalities (i.e. field <code>a</code>
613
789
  needs to be given only if field <code>b</code> is present).</p></li>
614
790
  <li><p>Schemacop does not yet support string regex matching.</p></li>
615
791
  </ul>
616
792
 
617
- <h2>Contributors</h2>
793
+ <h2>Development</h2>
794
+
795
+ <p>To run tests:</p>
618
796
 
619
- <p>Thanks to <a href="https://github.com/bbatsov/rubocop">Rubocop</a> for great inspiration
620
- concerning their name and the structure of their README file. And special thanks
621
- to <a href="http://www.subgit.com/">SubGit</a> for their great open source licensing.</p>
797
+ <ul>
798
+ <li><p>Check out the source</p></li>
799
+ <li><p>Run <code>bundle install</code></p></li>
800
+ <li><p>Run <code>bundle exec rake test</code> to run all tests</p></li>
801
+ <li><p>Run <code>bundle exec rake test TEST=test/unit/some/file.rb</code> to run a single test
802
+ file</p></li>
803
+ </ul>
622
804
 
623
805
  <h2>Copyright</h2>
624
806
 
625
- <p>Copyright (c) 2017 Sitrox. See <code>LICENSE</code> for further details.</p>
807
+ <p>Copyright (c) 2019 Sitrox. See <code>LICENSE</code> for further details.</p>
626
808
  </div></div>
627
809
 
628
810
  <div id="footer">
629
- Generated on Thu May 18 13:17:23 2017 by
811
+ Generated on Tue Nov 5 11:16:27 2019 by
630
812
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
631
- 0.9.9 (ruby-2.3.1).
813
+ 0.9.20 (ruby-2.6.2).
632
814
  </div>
633
815
 
634
816
  </div>