schemacop 3.0.0.rc1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5caf1b6b11b5c690dc05694cab67e34fb6ecc326381f9d7b63b9c016b5249d9c
4
- data.tar.gz: 8b819ad6e32dd2329bd20c0869c216c677b766a5d7374a49f6a9c146d0e743d5
3
+ metadata.gz: eb25d83997e507cf7bf5e905143584e01b543c296f74e190eae487fe1a8bfdc0
4
+ data.tar.gz: 896f9bc4e14ac0e59831eacd83ae2e5a691a53e377f0b4895790b3686c24c2db
5
5
  SHA512:
6
- metadata.gz: 5db8ca31cdf29cea9744529fec11af70dc1c534dc970639931e3a9c287f3005cc578e2d7e9b0525ceefdbcb17d5f01d46d42c0a5b5868b62cabafe2779464ccc
7
- data.tar.gz: a12d18800342da6d1d9fdc39bffbec18877872c0cffb62c9b4a41cbd8954b0915c68afeb0b9e03c7e3bdd21f5803fa57daa7deb9cfd49a14363b67586e4e2fc0
6
+ metadata.gz: 461b762ba18edeac632010db52d368978ead449c6de8a88f6b6883d0109cfa3ff3e8b9bf4c8f2780023b60624bfc80f6456a421a8044fdf4ed7b565d8779db5c
7
+ data.tar.gz: 693beb806323f0695fce4183ad65d65670d5cab8b76692d74b4a467e396a52540bbb4fa9b9c03bef9940a35c1f62a32fcd0e51ea435f450bc134b502ca5839df
data/.releaser_config CHANGED
@@ -1,4 +1,3 @@
1
1
  version_file: VERSION
2
2
  always_from_master: true
3
- yard_path: doc
4
3
  gem_style: github
data/CHANGELOG.md CHANGED
@@ -10,7 +10,47 @@
10
10
  ### Changes
11
11
  -->
12
12
 
13
- ## 3.0.0.rc0
13
+ ## 3.0.0 (2021-02-08)
14
+
15
+ * Setup Zeitwerk ignores for Rails applications
16
+
17
+ * Read previous `3.0.0.rcX` entries for all changes included
18
+ in this stable release
19
+
20
+ ## 3.0.0.rc5 (2021-02-05)
21
+
22
+ * Use `ruby2_keywords` for compatibility with ruby `2.6.2`
23
+
24
+ ## 3.0.0.rc4 (2021-02-02)
25
+
26
+ * Fix some minor bugs
27
+
28
+ * Improve documentation
29
+
30
+ * `used_external_schemas` for the `ReferenceNode` is now applied
31
+ recursively
32
+
33
+ ## 3.0.0.rc3 (2021-01-28)
34
+
35
+ * Add minor improvements to the documentation
36
+
37
+ * Internal restructuring, no changes in API
38
+
39
+ ## 3.0.0.rc2 (2021-01-28)
40
+
41
+ * Represent node names as strings internally
42
+
43
+ * Update documentation
44
+
45
+ ## 3.0.0.rc1 (2021-01-22)
46
+
47
+ * Add support for ruby `3.0.0`
48
+
49
+ * Add `ruby-3.0.0` to travis testing
50
+
51
+ * Document all `v3` nodes
52
+
53
+ ## 3.0.0.rc0 (2021-01-14)
14
54
 
15
55
  * Add `Schemacop::Schema3`
16
56
 
data/README.md CHANGED
@@ -118,4 +118,4 @@ To run tests:
118
118
 
119
119
  ## Copyright
120
120
 
121
- Copyright (c) 2020 Sitrox. See `LICENSE` for further details.
121
+ Copyright © 2016 - 2021 Sitrox. See `LICENSE` for further details.
data/README_V3.md CHANGED
@@ -1,15 +1,11 @@
1
1
  # Schemacop schema V3
2
2
 
3
- Please note that Schemacop v3 is still a work in progress, especially the documentation.
3
+ ## Table of Contents
4
4
 
5
- Use at your own discretion.
6
-
7
- # Table of Contents
8
- 1. [Introduction](#Introduction)
9
- 2. [Validation](#validation)
10
- 3. [Exceptions](#exceptions)
11
- 4. [Generic Keywords](#generic-keywords)
12
- 5. [Nodes](#nodes)
5
+ 1. [Validation](#validation)
6
+ 2. [Exceptions](#exceptions)
7
+ 3. [Generic Keywords](#generic-keywords)
8
+ 4. [Nodes](#nodes)
13
9
  1. [String](#string)
14
10
  2. [Integer](#integer)
15
11
  3. [Number](#number)
@@ -23,16 +19,12 @@ Use at your own discretion.
23
19
  11. [OneOf](#oneOf)
24
20
  12. [IsNot](#isNot)
25
21
  13. [Reference](#reference)
26
- 6. [Context](#context)
27
- 7. [External schemas](#external-schemas)
28
-
29
- ## Introduction
30
-
31
- TODO: Write short section about using schemacop V3
22
+ 5. [Context](#context)
23
+ 6. [External schemas](#external-schemas)
32
24
 
33
25
  ## Validation
34
26
 
35
- Using schemacop, you can either choose to validate the data either using the
27
+ Using Schemacop, you can either choose to validate your data either using the
36
28
  graceful `validate` method, or the bang variant, `validate!`.
37
29
 
38
30
  The `validate` method on a schema with some supplied data will return a
@@ -74,19 +66,120 @@ schema.validate!('Foo') # => Schemacop::Exceptions::ValidationError: /:
74
66
 
75
67
  ## Exceptions
76
68
 
77
- TODO: Describe the exceptions raised by schemacop
69
+ Schemacop can raise the following exceptions:
70
+
71
+ * `Schemacop::Exceptions::ValidationError`: This exception is raised when the
72
+ `validate!` method is used, and the data that was passed in is invalid. The
73
+ exception message contains additional information why the validation failed.
74
+
75
+ Example:
76
+
77
+ ```ruby
78
+ schema = Schemacop::Schema3.new do
79
+ int! :foo
80
+ end
81
+
82
+ schema.validate!(foo: 'bar')
83
+ # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "integer".
84
+ ```
78
85
 
79
- `Schemacop::Exceptions::ValidationError`
80
- `Schemacop::Exceptions::InvalidSchemaError`
86
+ * `Schemacop::Exceptions::InvalidSchemaError`: This exception is raised when the
87
+ schema itself is not valid. The exception message contains additional
88
+ information why the validation failed.
89
+
90
+ Example:
91
+
92
+ ```ruby
93
+ Schemacop::Schema3.new :hash do
94
+ int!
95
+ end
96
+
97
+ # => Schemacop::Exceptions::InvalidSchemaError: Child nodes must have a name.
98
+ ```
81
99
 
82
100
  ## Generic Keywords
83
101
 
84
- TODO: Complete this
102
+ The nodes in Schemacop v3 also support generic keywords, similar to JSON schema:
103
+
104
+ * `title`: Short string, should be self-explanatory
105
+ * `description`: Description of the schema
106
+ * `examples`: Here, you can provide examples which will be valid for the schema
107
+ * `enum`: Here, you may enumerate values which will be valid, if the provided
108
+ value is not in the array, the validation will fail
109
+ * `default`: You may provide a default value for items that will be set if the
110
+ value is not given
111
+
112
+ The three keywords `title`, `description` and `examples` aren't used for validation,
113
+ but can be used to document the schema. They will be included in the JSON output
114
+ when you use the `as_json` method:
115
+
116
+ ```ruby
117
+ schema = Schemacop::Schema3.new :hash do
118
+ str! :name, title: 'Name', description: 'Holds the name of the user', examples: ['Joe', 'Anna']
119
+ end
120
+
121
+ schema.as_json
122
+
123
+ # => {"properties"=>{"name"=>{"type"=>"string", "title"=>"Name", "examples"=>["Joe", "Anna"], "description"=>"Holds the name of the user"}}, "additionalProperties"=>false, "required"=>["name"], "type"=>"object"}
124
+ ```
125
+
126
+ The `enum` keyword can be used to only allow a subset of values:
127
+
128
+ ```ruby
129
+ schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar']
130
+
131
+ schema.validate!('foo') # => "foo"
132
+ schema.validate!('bar') # => "bar"
133
+ schema.validate!('baz') # => Schemacop::Exceptions::ValidationError: /: Value not included in enum ["foo", "bar"].
134
+ ```
135
+
136
+ Please note that you can also specify values in the enum that are not valid for
137
+ the schema. This means that the validation will still fail:
138
+
139
+ ```ruby
140
+ schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar', 42]
141
+
142
+ schema.validate!('foo') # => "foo"
143
+ schema.validate!('bar') # => "bar"
144
+ schema.validate!(42) # => Schemacop::Exceptions::ValidationError: /: Invalid type, expected "string".
145
+ ```
146
+
147
+ The enum will also be provided in the json output:
148
+
149
+ ```ruby
150
+ schema = Schemacop::Schema3.new :string, enum: ['foo', 'bar']
151
+
152
+ schema.as_json
153
+ # => {"type"=>"string", "enum"=>["foo", "bar", 42]}
154
+ ```
155
+
156
+ And finally, the `default` keyword lets you set a default value to use when no
157
+ value is provided:
158
+
159
+ ```ruby
160
+ schema = Schemacop::Schema3.new :string, default: 'Schemacop'
161
+
162
+ schema.validate!('foo') # => "foo"
163
+ schema.validate!(nil) # => "Schemacop"
164
+ ```
85
165
 
86
- * enum
87
- * title
88
- * description
89
- * examples
166
+ The default value will also be provided in the json output:
167
+
168
+ ```ruby
169
+ schema = Schemacop::Schema3.new :string, default: 'Schemacop'
170
+
171
+ schema.as_json
172
+ # => {"type"=>"string", "default"=>"Schemacop"}
173
+ ```
174
+
175
+ Note that the default value you use is also validated against the schema:
176
+
177
+ ```ruby
178
+ schema = Schemacop::Schema3.new :string, default: 42
179
+
180
+ schema.validate!('foo') # => "foo"
181
+ schema.validate!(nil) # => Schemacop::Exceptions::ValidationError: /: Invalid type, expected "string".
182
+ ```
90
183
 
91
184
  ## Nodes
92
185
 
@@ -102,9 +195,9 @@ transformed into various types.
102
195
  #### Options
103
196
 
104
197
  * `min_length`
105
- Defines the minimum required string length
198
+ Defines the (inclusive) minimum required string length
106
199
  * `max_length`
107
- Defines the maximum required string length
200
+ Defines the (inclusive) maximum required string length
108
201
  * `pattern`
109
202
  Defines a (ruby) regex pattern the value will be matched against. Must be a
110
203
  string and should generally start with `^` and end with `$` so as to evaluate
@@ -136,7 +229,7 @@ transformed into various types.
136
229
 
137
230
  * `boolean`
138
231
  The string must be either `true` or `false`. This value will be casted to
139
- ruby's `TrueClass` or `FalseClass`.
232
+ Ruby's `TrueClass` or `FalseClass`.
140
233
 
141
234
  * `binary`
142
235
  The string is expected to contain binary contents. No casting or additional
@@ -287,7 +380,7 @@ schema.validate!(1234) # => Schemacop::Exceptions::ValidationError: /: Invali
287
380
  ### Array
288
381
 
289
382
  Type: `:array`\
290
- DSL: `arr`
383
+ DSL: `ary`
291
384
 
292
385
  The array type represents a ruby `Array`.
293
386
  It consists of one or multiple values, which can be validated using arbitrary nodes.
@@ -309,11 +402,11 @@ It consists of one or multiple values, which can be validated using arbitrary no
309
402
 
310
403
  #### Contains
311
404
 
312
- The `array` node features the contains node, which you can use with the DSL
313
- method `cont`. With that DSL method, you can specify a schema which at least
314
- one item in the array needs to validate against.
405
+ The `array` node features the *contains* node, which you can use with the DSL
406
+ method `cont`. With that DSL method, you can specify a schema which at least one
407
+ item in the array needs to validate against.
315
408
 
316
- One usecase for example could be that you want an array of integers, from which
409
+ One use case for example could be that you want an array of integers, from which
317
410
  at least one must be 5 or larger:
318
411
 
319
412
  ```ruby
@@ -353,9 +446,10 @@ how you specify your array contents.
353
446
 
354
447
  List validation validates a sequence of arbitrary length where each item matches
355
448
  the same schema. Unless you specify a `min_items` count on the array node, an
356
- empty array will also validate. To specify a list validation, use the `list`
357
- DSL method, and specify the type you want to validate against. Here, you need
358
- to specify the type of the element using the long `type` name (e.g. `integer` and not `int`).
449
+ empty array will also suffice. To specify a list validation, use the `list` DSL
450
+ method, and specify the type you want to validate against. Here, you need to
451
+ specify the type of the element using the long `type` name (e.g. `integer` and
452
+ not `int`).
359
453
 
360
454
  For example, you can specify that you want an array with only integers between 1 and 5:
361
455
 
@@ -448,8 +542,8 @@ schema.validate!([1, 'foo', 'bar']) # => Schemacop::Exceptions::ValidationError:
448
542
  schema.validate!([1, 'foo', 2, 3]) # => [1, "foo", 2, 3]
449
543
  ```
450
544
 
451
- Please note, that you cannot use multiple `add` in the same array schema, this will result in
452
- an exception:
545
+ Please note that you cannot use multiple `add` in the same array schema, this
546
+ will result in an exception:
453
547
 
454
548
  ```ruby
455
549
  schema = Schemacop::Schema3.new :array do
@@ -461,9 +555,10 @@ end
461
555
  # => Schemacop::Exceptions::InvalidSchemaError: You can only use "add" once to specify additional items.
462
556
  ```
463
557
 
464
- If you want to specify that your schema accept multiple additional types, use the `one_of`
465
- type (see below for more infos). The correct way to specify that you want to allow additional
466
- items, which may be an integer or a string is as follows:
558
+ If you want to specify that your schema accept multiple additional types, use
559
+ the `one_of` type (see below for more infos). The correct way to specify that
560
+ you want to allow additional items, which may be an integer or a string is as
561
+ follows:
467
562
 
468
563
  ```ruby
469
564
  schema = Schemacop::Schema3.new :array do
@@ -492,13 +587,14 @@ It consists of key-value-pairs that can be validated using arbitrary nodes.
492
587
 
493
588
  * `additional_properties`
494
589
  This option specifies whether additional, unspecified properties are allowed
495
- (`true`) or not (`false`). By default, this is `true` if no properties are
496
- 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.
497
593
 
498
594
  * `property_names`
499
595
  This option allows to specify a regexp pattern (as string) which validates the
500
596
  keys of any properties that are not specified in the hash. This option only
501
- makes sense if `additional_properties` is enabled. See below for more informations.
597
+ makes sense if `additional_properties` is enabled. See below for more information.
502
598
 
503
599
  * `min_properties`
504
600
  Specifies the (inclusive) minimum number of properties a hash must contain.
@@ -523,11 +619,116 @@ schema = Schemacop::Schema3.new :hash do
523
619
  end
524
620
 
525
621
  schema.validate!({}) # => Schemacop::Exceptions::ValidationError: /foo: Value must be given.
526
- schema.validate!({foo: 'str'}) # => {:foo=>"str"}
527
- schema.validate!({foo: 'str', bar: 42}) # => {:foo=>"str", :bar=>42}
622
+ schema.validate!({foo: 'str'}) # => {"foo"=>"str"}
623
+ schema.validate!({foo: 'str', bar: 42}) # => {"foo"=>"str", "bar"=>42}
528
624
  schema.validate!({bar: 42}) # => Schemacop::Exceptions::ValidationError: /foo: Value must be given.
529
625
  ```
530
626
 
627
+ The name of the properties may either be a string or a symbol, and you can pass
628
+ in the property either identified by a symbol or a string:
629
+
630
+ The following two schemas are equal:
631
+
632
+ ```ruby
633
+ schema = Schemacop::Schema3.new :hash do
634
+ int! :foo
635
+ end
636
+
637
+ schema.validate!(foo: 42) # => {"foo"=>42}
638
+ schema.validate!('foo' => 42) # => {"foo"=>42}
639
+
640
+ schema = Schemacop::Schema3.new :hash do
641
+ int! 'foo'
642
+ end
643
+
644
+ schema.validate!(foo: 42) # => {"foo"=>42}
645
+ schema.validate!('foo' => 42) # => {"foo"=>42}
646
+ ```
647
+
648
+ The result in both cases will be a
649
+ [HashWithIndifferentAccess](https://api.rubyonrails.org/classes/ActiveSupport/HashWithIndifferentAccess.html),
650
+ which means that you can access the data in the hash with the symbol as well as
651
+ the string representation:
652
+
653
+ ```ruby
654
+ schema = Schemacop::Schema3.new :hash do
655
+ int! :foo
656
+ end
657
+
658
+ result = schema.validate!(foo: 42)
659
+
660
+ result.class # => ActiveSupport::HashWithIndifferentAccess
661
+ result[:foo] # => 42
662
+ result['foo'] # 42
663
+ ```
664
+
665
+ Please note that if you specify the value twice in the data you want to
666
+ validate, once with the key being a symbol and once being a string, Schemacop
667
+ will raise an error:
668
+
669
+ ```ruby
670
+ schema = Schemacop::Schema3.new :hash do
671
+ int! :foo
672
+ end
673
+
674
+ schema.validate!(foo: 42, 'foo' => 43) # => Schemacop::Exceptions::ValidationError: /: Has 1 ambiguous properties: [:foo].
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
+
531
732
  ##### Pattern properties
532
733
 
533
734
  In addition to symbols, property keys can also be a regular expression. Here,
@@ -543,8 +744,8 @@ schema = Schemacop::Schema3.new :hash do
543
744
  end
544
745
 
545
746
  schema.validate!({}) # => {}
546
- schema.validate!({id_foo: 1}) # => {:id_foo=>1}
547
- schema.validate!({id_foo: 1, id_bar: 2}) # => {:id_foo=>1, :id_bar=>2}
747
+ schema.validate!({id_foo: 1}) # => {"id_foo"=>1}
748
+ schema.validate!({id_foo: 1, id_bar: 2}) # => {"id_foo"=>1, "id_bar"=>2}
548
749
  schema.validate!({foo: 3}) # => Schemacop::Exceptions::ValidationError: /: Obsolete property "foo".
549
750
  ```
550
751
 
@@ -562,7 +763,7 @@ enable all of them by enabling the option `additional_properties`:
562
763
  schema = Schemacop::Schema3.new :hash, additional_properties: true
563
764
 
564
765
  schema.validate!({}) # => {}
565
- schema.validate!({foo: :bar, baz: 42}) # => {:foo=>:bar, :baz=>42}
766
+ schema.validate!({foo: :bar, baz: 42}) # => {"foo"=>:bar, "baz"=>42}
566
767
  ```
567
768
 
568
769
  Using the DSL method `add` in the hash-node's body however, you can specify
@@ -578,8 +779,8 @@ Schemacop::Schema3.new :hash do
578
779
  add :string
579
780
  end
580
781
 
581
- schema.validate!({id: 1}) # => {:id=>1}
582
- schema.validate!({id: 1, foo: 'bar'}) # => {:foo=>"bar", :id=>1}
782
+ schema.validate!({id: 1}) # => {"id"=>1}
783
+ schema.validate!({id: 1, foo: 'bar'}) # => {"id"=>1, "foo"=>"bar"}
583
784
  schema.validate!({id: 1, foo: 42}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "string".
584
785
  ```
585
786
 
@@ -589,12 +790,12 @@ any additional property **keys** must adhere to:
589
790
  ```ruby
590
791
  # The following schema allows any number of properties, but all keys must
591
792
  # consist of downcase letters from a-z.
592
- schema = Schemacop::Schema3.new :hash, additional_properties: :true, property_names: '^[a-z]+$'
793
+ schema = Schemacop::Schema3.new :hash, additional_properties: true, property_names: '^[a-z]+$'
593
794
 
594
795
 
595
796
  schema.validate!({}) # => {}
596
- schema.validate!({foo: 123}) # => {:foo=>123}
597
- schema.validate!({Foo: 'bar'}) # => Schemacop::Exceptions::ValidationError: /: Property name :Foo does not match "^[a-z]+$".
797
+ schema.validate!({foo: 123}) # => {"foo"=>123}
798
+ schema.validate!({Foo: 'bar'}) # => Schemacop::Exceptions::ValidationError: /: Property name "Foo" does not match "^[a-z]+$".
598
799
 
599
800
  # The following schema allows any number of properties, but all keys must
600
801
  # consist of downcase letters from a-z AND the properties must be arrays.
@@ -603,7 +804,7 @@ schema = Schemacop::Schema3.new :hash, additional_properties: true, property_nam
603
804
  end
604
805
 
605
806
  schema.validate!({}) # => {}
606
- schema.validate!({foo: [1, 2, 3]}) # => {:foo=>[1, 2, 3]}
807
+ schema.validate!({foo: [1, 2, 3]}) # => {"foo"=>[1, 2, 3]}
607
808
  schema.validate!({foo: :bar}) # => Schemacop::Exceptions::ValidationError: /foo: Invalid type, expected "array".
608
809
  schema.validate!({Foo: :bar}) # => Schemacop::Exceptions::ValidationError: /: Property name :Foo does not match "^[a-z]+$". /Foo: Invalid type, expected "array".
609
810
  ```
@@ -627,7 +828,7 @@ schema = Schemacop::Schema3.new :hash do
627
828
  end
628
829
 
629
830
  schema.validate!({}) # => Schemacop::Exceptions::ValidationError: /name: Value must be given.
630
- schema.validate!({name: 'Joe Doe'}) # => {:name=>"Joe Doe"}
831
+ schema.validate!({name: 'Joe Doe'}) # => {"name"=>"Joe Doe"}
631
832
  schema.validate!({
632
833
  name: 'Joe Doe',
633
834
  billing_address: 'Street 42'
@@ -646,7 +847,7 @@ schema.validate!({
646
847
  phone_number: '000-000-00-00',
647
848
  credit_card: 'XXXX XXXX XXXX XXXX X'
648
849
  })
649
- # => {:name=>"Joe Doe", :credit_card=>"XXXX XXXX XXXX XXXX X", :billing_address=>"Street 42", :phone_number=>"000-000-00-00"}
850
+ # => {"name"=>"Joe Doe", "credit_card"=>"XXXX XXXX XXXX XXXX X", "billing_address"=>"Street 42", "phone_number"=>"000-000-00-00"}
650
851
  ```
651
852
 
652
853
  ### Object
@@ -654,10 +855,11 @@ schema.validate!({
654
855
  Type: `:object`\
655
856
  DSL: `obj`
656
857
 
657
- The object type represents a ruby `Object`. Please note that the `as_json? method
658
- on nodes of this type will just return `{}` (an empty JSON object), as there isn't
659
- a useful way to represent a ruby object without conflicting with the `Hash` type.
660
- If you want to represent an JSON object, you should use the `Hash` node.
858
+ The object type represents a Ruby `Object`. Please note that the `as_json`
859
+ method on nodes of this type will just return `{}` (an empty JSON object), as
860
+ there isn't a useful way to represent a Ruby object without conflicting with the
861
+ `Hash` type. If you want to represent a JSON object, you should use the `Hash`
862
+ node.
661
863
 
662
864
  In the most basic form, this node will accept anything:
663
865
 
@@ -738,7 +940,7 @@ schema.validate!('foooo') # => Schemacop::Exceptions::ValidationError: /: Does n
738
940
  Type: `:any_of`\
739
941
  DSL: `any_of`
740
942
 
741
- Similar to the AllOf node, you can specify multiple schemas, for which the
943
+ Similar to the `all_of` node, you can specify multiple schemas, for which the
742
944
  given value needs to validate against at least one of the schemas.
743
945
 
744
946
  For example, your value needs to be either a string which is at least 2
@@ -755,7 +957,7 @@ schema.validate!('foo') # => "foo"
755
957
  schema.validate!(42) # => 42
756
958
  ```
757
959
 
758
- Please note that you need to specify at least one item in the AllOf node:
960
+ Please note that you need to specify at least one item in the `any_of` node:
759
961
 
760
962
  ```ruby
761
963
  Schemacop::Schema3.new :any_of # => Schemacop::Exceptions::InvalidSchemaError: Node "any_of" makes only sense with at least 1 item.
@@ -766,9 +968,9 @@ Schemacop::Schema3.new :any_of # => Schemacop::Exceptions::InvalidSchemaError: N
766
968
  Type: `:one_of`\
767
969
  DSL: `one_of`
768
970
 
769
- Similar to the AllOf node, you can specify multiple schemas, for which the
770
- given value needs to validate against at exaclty one of the schemas. If the
771
- given value validates against multiple schemas, the value is invalid.
971
+ Similar to the `all_of` node, you can specify multiple schemas, for which the
972
+ given value needs to validate against exaclty one of the schemas. If the given
973
+ value validates against multiple schemas, the value is invalid.
772
974
 
773
975
  For example, if you want an integer which is either a multiple of 2 or 3,
774
976
  but not both (i.e. no multiple of 6), you could do it as follows:
@@ -807,7 +1009,7 @@ schema.validate!(6) # => Schemacop::Exceptions::ValidationError: /: Matches 2 de
807
1009
  Type: `:is_not`\
808
1010
  DSL: `is_not`
809
1011
 
810
- With the IsNot node, you can specify a schema which the given value must not
1012
+ With the `is_not` node, you can specify a schema which the given value must not
811
1013
  validate against, i.e. every value which matches the schema will make this node
812
1014
  invalid.
813
1015
 
@@ -825,7 +1027,7 @@ schema.validate!(3) # => Schemacop::Exceptions::ValidationError: /: Must not
825
1027
  schema.validate!('foo') # => "foo"
826
1028
  ```
827
1029
 
828
- Note that a IsNot node needs exactly one item:
1030
+ Note that a `is_not` node needs exactly one item:
829
1031
 
830
1032
  ```ruby
831
1033
  schema = Schemacop::Schema3.new :is_not # => Schemacop::Exceptions::InvalidSchemaError: Node "is_not" only allows exactly one item.
@@ -840,7 +1042,7 @@ Type: `reference`
840
1042
  **Definition**
841
1043
  DSL: `scm`
842
1044
 
843
- Finally, with the Reference node, you can define schemas and then later reference
1045
+ Finally, with the *Reference* node, you can define schemas and then later reference
844
1046
  them for usage, e.g. when you have a rather long schema which you need at multiple
845
1047
  places.
846
1048
 
@@ -884,7 +1086,7 @@ schema.validate!({
884
1086
  }
885
1087
  })
886
1088
 
887
- # => {:shipping_address=>{:street=>"Example Street 42", :zip_code=>"12345", :location=>"London", :country=>"United Kingdom"}, :billing_address=>{:street=>"Main St.", :zip_code=>"54321", :location=>"Washington DC", :country=>"USA"}}
1089
+ # => {"shipping_address"=>{"street"=>"Example Street 42", "zip_code"=>"12345", "location"=>"London", "country"=>"United Kingdom"}, "billing_address"=>{"street"=>"Main St.", "zip_code"=>"54321", "location"=>"Washington DC", "country"=>"USA"}}
888
1090
  ```
889
1091
 
890
1092
  Note that if you use the reference node with the long type name `reference`,
@@ -902,13 +1104,13 @@ schema = Schemacop::Schema3.new :array do
902
1104
  end
903
1105
 
904
1106
  schema.validate!([]) # => []
905
- schema.validate!([{first_name: 'Joe', last_name: 'Doe'}]) # => [{:first_name=>"Joe", :last_name=>"Doe"}]
1107
+ schema.validate!([{first_name: 'Joe', last_name: 'Doe'}]) # => [{"first_name"=>"Joe", "last_name"=>"Doe"}]
906
1108
  schema.validate!([id: 42, first_name: 'Joe']) # => Schemacop::Exceptions::ValidationError: /[0]/last_name: Value must be given. /[0]: Obsolete property "id".
907
1109
  ```
908
1110
 
909
1111
  ## Context
910
1112
 
911
- Schemacop als features the concept of a `Context`. You can define schemas in a
1113
+ Schemacop also features the concept of a `Context`. You can define schemas in a
912
1114
  context, and then reference them in other schemas in that context. This is e.g.
913
1115
  useful if you need a part of the schema to be different depending on the
914
1116
  business action.
@@ -932,7 +1134,7 @@ context.schema :PersonInfo do
932
1134
  end
933
1135
 
934
1136
  # Now we can define our general schema, where we reference the :Person schema.
935
- # Note that at this point, we don't know what's in the :Person sche,a
1137
+ # Note that at this point, we don't know what's in the :Person schema.
936
1138
  schema = Schemacop::Schema3.new :reference, path: :Person
937
1139
 
938
1140
  # Validate the data in the context we defined before, where we need the first_name
@@ -940,7 +1142,7 @@ schema = Schemacop::Schema3.new :reference, path: :Person
940
1142
  # of the person.
941
1143
  Schemacop.with_context context do
942
1144
  schema.validate!({first_name: 'Joe', last_name: 'Doe', info: { born_at: '1980-01-01'} })
943
- # => {:first_name=>"Joe", :last_name=>"Doe", :info=>{:born_at=>Tue, 01 Jan 1980}}
1145
+ # => {"first_name"=>"Joe", "last_name"=>"Doe", "info"=>{"born_at"=>Tue, 01 Jan 1980}}
944
1146
  end
945
1147
 
946
1148
  # Now we might want another context, where the person is more anonymous, and as
@@ -953,7 +1155,7 @@ other_context.schema :Person do
953
1155
  end
954
1156
 
955
1157
  # Finally, validate the data in the new context. We do not want the real name or
956
- # birth date of the person, instead only the nickname is allowed
1158
+ # birth date of the person, instead only the nickname is allowed.
957
1159
  Schemacop.with_context other_context do
958
1160
  schema.validate!({first_name: 'Joe', last_name: 'Doe', info: { born_at: '1980-01-01'} })
959
1161
  # => Schemacop::Exceptions::ValidationError: /nickname: Value must be given.
@@ -961,7 +1163,7 @@ Schemacop.with_context other_context do
961
1163
  # /: Obsolete property "last_name".
962
1164
  # /: Obsolete property "info".
963
1165
 
964
- schema.validate!({nickname: 'J.'}) # => {:nickname=>"J."}
1166
+ schema.validate!({nickname: 'J.'}) # => {"nickname"=>"J."}
965
1167
  end
966
1168
  ```
967
1169
 
@@ -971,11 +1173,11 @@ to use other data in the second context than in the first.
971
1173
 
972
1174
  ## External schemas
973
1175
 
974
- Finally, schemacop features the possibilit to specify schemas in seperate files.
975
- This is especially useful is you have schemas in your application which are used
976
- multiple times through the application.
1176
+ Finally, Schemacop features the possibility to specify schemas in seperate
1177
+ files. This is especially useful is you have schemas in your application which
1178
+ are used multiple times throughout the application.
977
1179
 
978
- For each schema, you define the schema in a single file, and after loading the
1180
+ For each schema, you define the schema in a separate file, and after loading the
979
1181
  schemas, you can reference them in other schemas.
980
1182
 
981
1183
  The default load path is `'app/schemas'`, but this can be configured by setting
@@ -989,14 +1191,17 @@ local schemas > context schemas > global schemas
989
1191
 
990
1192
  Where:
991
1193
 
992
- * local schemas: Defined by using the DSL method? `scm`
1194
+ * local schemas: Defined by using the DSL method `scm`
993
1195
  * context schemas: Defined in the current context using `context.schema`
994
1196
  * global schemas: Defined in a ruby file in the load path
995
1197
 
996
1198
  ### Rails applications
997
1199
 
998
- In Rails applications, your schemas are automatically eager-laoded from the load
999
- path `'app/schemas'` when your application is started.
1200
+ In Rails applications, your schemas are automatically eager-loaded from the load
1201
+ path `'app/schemas'` when your application is started, unless your application
1202
+ is running in the `DEVELOPMENT` environment. In the `DEVELOPMENT` environment,
1203
+ schemas are loaded each time when they are used, and as such you can make changes
1204
+ to your external schemas without having to restart the server each time.
1000
1205
 
1001
1206
  After starting your application, you can reference them like normally defined
1002
1207
  reference schemas, with the name being relative to the load path.
@@ -1032,20 +1237,24 @@ schema = Schemacop::Schema3.new :hash do
1032
1237
  end
1033
1238
 
1034
1239
  schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe'}})
1035
- # => {:usr=>{:first_name=>"Joe", :last_name=>"Doe"}}
1240
+ # => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe"}}
1036
1241
 
1037
1242
  schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe', groups: []}})
1038
- # => {:usr=>{:first_name=>"Joe", :last_name=>"Doe", :groups=>[]}}
1243
+ # => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe", "groups"=>[]}}
1039
1244
 
1040
1245
  schema.validate!({usr: {first_name: 'Joe', last_name: 'Doe', groups: [{name: 'foo'}, {name: 'bar'}]}})
1041
- # => {:usr=>{:first_name=>"Joe", :last_name=>"Doe", :groups=>[{:name=>"foo"}, {:name=>"bar"}]}}
1246
+ # => {"usr"=>{"first_name"=>"Joe", "last_name"=>"Doe", "groups"=>[{"name"=>"foo"}, {"name"=>"bar"}]}}
1042
1247
  ```
1043
1248
 
1044
1249
  ### Non-Rails applications
1045
1250
 
1046
1251
  Usage in non-Rails applications is the same as with usage in Rails applications,
1047
- however you need to eager load the schemas yourself:
1252
+ however you might need to eager load the schemas yourself:
1048
1253
 
1049
1254
  ```ruby
1050
1255
  Schemacop::V3::GlobalContext.eager_load!
1051
- ```
1256
+ ```
1257
+
1258
+ As mentioned before, you can also use the external schemas without having to
1259
+ eager-load them, but if you use the schemas multiple times, it might be better
1260
+ to eager-load them on start of your application / script.