schemacop 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7ff5d0ab4c17e94b315ae9d4b765f80876dbcdcd
4
+ data.tar.gz: 21f7ac81ccd77383b15e1b07a6e131d6d8d99bb8
5
+ SHA512:
6
+ metadata.gz: 92f19ccddbc4201eb295e2e8216bb8f6096a92a6a54658f79c0cabc244c7e8c6e9a77ded4941c5147ab3f1d1a644645466d335fadd98bef5c0252a23f64dd897
7
+ data.tar.gz: 863cc1423683b8eaeed9ae889c0a3a424030bf35b2efbb0a34a41edc14edd29d790e6d59ed6199af6df00d7e86e3d2babfcba3b592d9ae70a13a27c0e8dd4836
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /bin/ruby
2
+ /.bundle
3
+ .DS_Store
4
+ *.tmproj
5
+ tmtags
6
+ /Gemfile.lock
7
+ *~
8
+ \#*
9
+ .\#*
10
+ *.swp
11
+ /vendor/gems/*
12
+ /vendor/bundle/*
13
+ /spec/reports
14
+ /.yardoc
15
+ .idea
data/.rubocop.yml ADDED
@@ -0,0 +1,42 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'local/**/*'
4
+ - 'vendor/**/*'
5
+ - 'tmp/**/*'
6
+ - '*.gemspec'
7
+
8
+ DisplayCopNames: true
9
+
10
+ Metrics/MethodLength:
11
+ Enabled: false
12
+
13
+ Metrics/AbcSize:
14
+ Enabled: False
15
+
16
+ Metrics/CyclomaticComplexity:
17
+ Enabled: False
18
+
19
+ Metrics/PerceivedComplexity:
20
+ Enabled: False
21
+
22
+ Metrics/LineLength:
23
+ Max: 160
24
+
25
+ Style/IfUnlessModifier:
26
+ Enabled: false
27
+
28
+ Style/Documentation:
29
+ Enabled: false
30
+
31
+ Style/RedundantReturn:
32
+ Enabled: false
33
+
34
+ Style/GuardClause:
35
+ Enabled: false
36
+
37
+ Style/ClassAndModuleChildren:
38
+ Enabled: false
39
+ EnforcedStyle: compact
40
+ SupportedStyles:
41
+ - nested
42
+ - compact
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.2
5
+ - 2.3.0
6
+ script: bundle exec rake test
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --markup=markdown --readme=README.md --no-private lib/**/*.rb
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify gem dependencies in the .gemspec file
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Sitrox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,346 @@
1
+ [![Build Status](https://travis-ci.org/sitrox/schemacop.svg?branch=master)](https://travis-ci.org/sitrox/schemacop)
2
+
3
+
4
+ # Schemacop
5
+
6
+ Schemacop validates ruby structures consisting of nested hashes and arrays
7
+ against simple schema definitions.
8
+
9
+ Example:
10
+
11
+ ```ruby
12
+ schema = {
13
+ type: :hash,
14
+ hash: {
15
+ first_name: :string,
16
+ last_name: :string
17
+ }
18
+ }
19
+
20
+ data = {
21
+ first_name: 'John',
22
+ last_name: 'Doe'
23
+ }
24
+
25
+ Schemacop.validate!(schema, data)
26
+ ```
27
+
28
+ ## Installation
29
+
30
+ To install the **Schemacop** gem:
31
+
32
+ ```sh
33
+ $ gem install schemacop
34
+ ```
35
+
36
+ To install it using `bundler` (recommended for any application), add it
37
+ to your `Gemfile`:
38
+
39
+ ```ruby
40
+ gem 'schemacop'
41
+ ```
42
+
43
+ ## Basic usage
44
+
45
+ Schemacop's interface is very simple:
46
+
47
+ ```ruby
48
+ Schemacop.validate!(schema, data)
49
+ ```
50
+
51
+ It will throw an exception if either the schema is wrong or the given data does
52
+ not comply with the schema. See section *Exceptions* for more information.
53
+
54
+ ## Defining schemas
55
+
56
+ Schemacop can validate recursive structures of arrays nested into hashes and
57
+ vice-versa. 'Leaf-nodes' can be of any data type, but their internal structure
58
+ is not validated.
59
+
60
+ Schema definitions are always a hash, even if they specify an array. Each level
61
+ of a definition hash has to define a type.
62
+
63
+ You can specify any type, but only the types `:hash` and `:array` allow you to
64
+ specify a sub structure.
65
+
66
+ ### Defining hashes
67
+
68
+ Once a level is defined as a hash (`type: :hash`), you can provide the key
69
+ `hash` which in turn specifies the keys contained in that hash:
70
+
71
+ ```ruby
72
+ {
73
+ type: :hash,
74
+ hash: {
75
+ first_name: { type: :string },
76
+ last_name: { type: :string }
77
+ }
78
+ }
79
+ ```
80
+
81
+ If you don't provide the `:hash` key, the hash won't be validated (other than
82
+ the verification that it really is a hash):
83
+
84
+ ```ruby
85
+ { type: :hash }
86
+ ```
87
+
88
+ Hash definitions can be nested deeply:
89
+
90
+ ```ruby
91
+ {
92
+ type: :hash,
93
+ hash: {
94
+ name: {
95
+ type: :hash,
96
+ hash: {
97
+ first_name: { type: :string },
98
+ last_name: { type: :string }
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### Defining arrays
106
+
107
+ When you define a level as an array (`type: :array`), you can provide further
108
+ specification of the array's contents uby supplying the key `:array`:
109
+
110
+ ```ruby
111
+ {
112
+ type: :array,
113
+ array: {
114
+ type: :string
115
+ }
116
+ }
117
+ ```
118
+
119
+ This example would define an array of strings.
120
+
121
+ Arrays can nest hashes and vice-versa:
122
+
123
+ ```ruby
124
+ {
125
+ type: :array,
126
+ array: {
127
+ type: :string
128
+ }
129
+ }
130
+ ```
131
+
132
+ If you don't provide the `:array` key, the array contents won't be validated:
133
+
134
+ ```ruby
135
+ { type: :array }
136
+ ```
137
+
138
+ ## Types
139
+
140
+ For each level in your schema, you can specify the type in one of the following
141
+ manors:
142
+
143
+ - A ruby class:
144
+
145
+ ```ruby
146
+ { type: String }
147
+ ```
148
+
149
+ - A type alias (see {Schemacop::Validator::TYPE_ALIASES} for a full list of
150
+ available type aliasses):
151
+
152
+ ```ruby
153
+ { type: :boolean }
154
+ ```
155
+
156
+ - A list of ruby classes or type aliases:
157
+
158
+ ```ruby
159
+ { type: [String, :integer] }
160
+ ```
161
+
162
+ When specifying more than one type, it is validated that the given data
163
+ structure matches *one* of the given types.
164
+
165
+ If you specify both `:array` and `:hash` in such a type array, you can provide
166
+ a specification for both `array` and `hash` types:
167
+
168
+ ```ruby
169
+ {
170
+ type: [:array, :hash],
171
+ array: {
172
+ type: :string
173
+ },
174
+ hash: {
175
+ first_name: :string
176
+ }
177
+ }
178
+ ```
179
+
180
+ It will then determine which specification to use based on the actual data.
181
+
182
+ ## Null and required
183
+
184
+ Using the optional parameters `required` and `null`, you can control whether a
185
+ specific substructure must be provided (`required`) and if it can be `nil`
186
+ (`null`).
187
+
188
+ These two parameters can be combined in any way.
189
+
190
+ ### Required validation
191
+
192
+ When validating with `required = false`, it means that the whole key can be
193
+ omitted. As an example:
194
+
195
+ ```ruby
196
+ # Successfully validates data hash: {}
197
+ {
198
+ type: :hash,
199
+ hash: {
200
+ first_name: { type: :string, required: false }
201
+ }
202
+ }
203
+ ```
204
+
205
+ ### Null validation
206
+
207
+ When validating with `null = true`, the key must still be present, but it can
208
+ also be `nil`.
209
+
210
+ ```ruby
211
+ # Successfully validates data hash: { first_name: nil }
212
+ {
213
+ type: :hash,
214
+ hash: {
215
+ first_name: { type: :string, null: false }
216
+ }
217
+ }
218
+ ```
219
+
220
+ ## Allowed values
221
+
222
+ For any level, you can optionally specify an array of values that are allowed.
223
+
224
+ For example:
225
+
226
+ ```ruby
227
+ {
228
+ type: :hash,
229
+ hash: {
230
+ category: { type: :integer, allowed_values: [1, 2, 3] }
231
+ }
232
+ }
233
+ ```
234
+
235
+ ## Shortcuts
236
+
237
+ ### Type shortcut
238
+
239
+ If you'd just like to define a type for a level but don't need to supply any
240
+ additional information, you can just skip passing an extra hash and just pass
241
+ the type instead.
242
+
243
+ For example, the following
244
+
245
+ ```ruby
246
+ {
247
+ type: :array,
248
+ array: {
249
+ type: :string
250
+ }
251
+ }
252
+ ```
253
+
254
+ can also be written as:
255
+
256
+ ```ruby
257
+ {
258
+ type: :array,
259
+ array: :string
260
+ }
261
+ ```
262
+
263
+ ### Quick hash and array
264
+
265
+ When specifying a level as hash or array and you're further specifying the
266
+ hashe's fields or the array's content types, you can omit the `type` key.
267
+
268
+ For example, the following
269
+
270
+ ```ruby
271
+ {
272
+ type: :array,
273
+ array: {
274
+ type: :string
275
+ }
276
+ }
277
+ ```
278
+
279
+ can also be written as:
280
+
281
+ ```ruby
282
+ {
283
+ array: :string
284
+ }
285
+ ```
286
+
287
+ ## Example schema
288
+
289
+ ```ruby
290
+ {
291
+ hash: {
292
+ id: [Integer, String],
293
+ name: :string,
294
+ meta: {
295
+ hash: {
296
+ groups: { array: :integer },
297
+ birthday: Date,
298
+ comment: {
299
+ type: :string,
300
+ required: false,
301
+ null: true
302
+ },
303
+ ar_object: User
304
+ }
305
+ }
306
+ },
307
+ }
308
+ ```
309
+
310
+ ## Exceptions
311
+
312
+ Schemacop will throw one of the following checked exceptions:
313
+
314
+ * {Schemacop::Exceptions::InvalidSchema}
315
+
316
+ This exception is thrown when the given schema definition format is invalid.
317
+
318
+ * {Schemacop::Exceptions::Validation}
319
+
320
+ This exception is thrown when the given data does not comply with the given
321
+ schema definition.
322
+
323
+ ## Known limitations
324
+
325
+ * Schemacop does not yet allow cyclic structures with infinite depth.
326
+
327
+ * Schemacop aborts when it encounters an error. It is not able to collect a full
328
+ list of multiple errors.
329
+
330
+ * Schemacop is not made for validating complex causalities (i.e. field `a`
331
+ needs to be given only if field `b` is present).
332
+
333
+ * Schemacop does not yet support string regex matching.
334
+
335
+ ## Contributors
336
+
337
+ Thanks to [Rubocop](https://github.com/bbatsov/rubocop) for great inspiration
338
+ concerning their name and the structure of their README file.
339
+
340
+ ## Changelog
341
+
342
+ Schemacop's changelog is available [here](CHANGELOG.md).
343
+
344
+ ## Copyright
345
+
346
+ Copyright (c) 2016 Sitrox. See [LICENSE](LICENSE) for further details.