yes 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.
- data/.ruby +41 -0
- data/.yardopts +8 -0
- data/HISTORY.rdoc +31 -0
- data/LICENSE.rdoc +35 -0
- data/QED.rdoc +1036 -0
- data/README.rdoc +144 -0
- data/THANKS.rdoc +10 -0
- data/bin/yes-lint +4 -0
- data/data/yes/yes.yes +21 -0
- data/lib/yes.rb +38 -0
- data/lib/yes/cli.rb +20 -0
- data/lib/yes/constraints/abstract_constraint.rb +121 -0
- data/lib/yes/constraints/choice.rb +39 -0
- data/lib/yes/constraints/count.rb +38 -0
- data/lib/yes/constraints/exclusive.rb +48 -0
- data/lib/yes/constraints/fnmatch.rb +42 -0
- data/lib/yes/constraints/inclusive.rb +50 -0
- data/lib/yes/constraints/key.rb +55 -0
- data/lib/yes/constraints/kind.rb +34 -0
- data/lib/yes/constraints/length.rb +46 -0
- data/lib/yes/constraints/node_constraint.rb +55 -0
- data/lib/yes/constraints/range.rb +43 -0
- data/lib/yes/constraints/regexp.rb +52 -0
- data/lib/yes/constraints/required.rb +45 -0
- data/lib/yes/constraints/requires.rb +57 -0
- data/lib/yes/constraints/tag.rb +55 -0
- data/lib/yes/constraints/tree_constraint.rb +14 -0
- data/lib/yes/constraints/type.rb +91 -0
- data/lib/yes/constraints/value.rb +62 -0
- data/lib/yes/genclass.rb +2 -0
- data/lib/yes/lint.rb +101 -0
- data/lib/yes/logical_and.rb +13 -0
- metadata +110 -0
data/.ruby
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
---
|
2
|
+
name: "yes"
|
3
|
+
version: 0.0.1
|
4
|
+
title: "YES"
|
5
|
+
summary: YAML Easy Schema
|
6
|
+
description: YAML Easy Schemas it a straight-foward but powerful YPath-based schema format and validation program for YAML documents.
|
7
|
+
loadpath:
|
8
|
+
- lib
|
9
|
+
manifest: MANIFEST
|
10
|
+
requires:
|
11
|
+
- name: qed
|
12
|
+
version: 0+
|
13
|
+
group:
|
14
|
+
- test
|
15
|
+
- name: detroit
|
16
|
+
version: 0+
|
17
|
+
group:
|
18
|
+
- build
|
19
|
+
conflicts: []
|
20
|
+
|
21
|
+
replaces: []
|
22
|
+
|
23
|
+
engine_check: []
|
24
|
+
|
25
|
+
organization: RubyWorks
|
26
|
+
contact: transfire@gmail.com
|
27
|
+
created: 2011-06-21
|
28
|
+
copyright: Copyright (c) 2011 Thomas Sawyer
|
29
|
+
licenses:
|
30
|
+
- BSD-2-Clause
|
31
|
+
authors:
|
32
|
+
- Thomas Sawyer
|
33
|
+
maintainers: []
|
34
|
+
|
35
|
+
resources:
|
36
|
+
home: http://rubyworks.github.com/yes
|
37
|
+
work: http://github.com/rubyworks/yes
|
38
|
+
mail: http://groups.google.com/group/rubyworks-mailinglist
|
39
|
+
repositories:
|
40
|
+
public: git://github.com/rubyworks/yes.git
|
41
|
+
spec_version: 1.0.0
|
data/.yardopts
ADDED
data/HISTORY.rdoc
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
= RELEASE HISTORY
|
2
|
+
|
3
|
+
== HEAD / 2011-07-02
|
4
|
+
|
5
|
+
Current Development (7rans)
|
6
|
+
|
7
|
+
Changes:
|
8
|
+
|
9
|
+
* 4 Test Enhancements
|
10
|
+
|
11
|
+
* Add test for RequiresValidation.
|
12
|
+
* Use Lint class, as YES is now a module.
|
13
|
+
* Move QED .rdoc files to .md files.
|
14
|
+
* Add required and count constraint tests.
|
15
|
+
|
16
|
+
* 13 General Enhancements
|
17
|
+
|
18
|
+
* Pass tree to validations and change Required to Requires.
|
19
|
+
* Add node shortcuts to NodeValidation class.
|
20
|
+
* Fix AbstractValidation#match_delta range comparisons.
|
21
|
+
* Rename yaml-yes executable to yes-lint.
|
22
|
+
* Refactored validation into individual validation classes.
|
23
|
+
* Rename range to count and add new constraints.
|
24
|
+
* Add exclusive and improved required validation.
|
25
|
+
* Output a generalized node representation.
|
26
|
+
* Add schema for yes itself.
|
27
|
+
* When node's #type_id is nil use #kind.
|
28
|
+
* Fix typo in README example.
|
29
|
+
* Clarify design in README.
|
30
|
+
* Initial commit.
|
31
|
+
|
data/LICENSE.rdoc
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
= COPYRIGHT NOTICES
|
2
|
+
|
3
|
+
== YES
|
4
|
+
|
5
|
+
Copyright:: (c) 2011 Rubyworks, Thomas Sawyer
|
6
|
+
License:: BSD-2-Clause
|
7
|
+
Website:: http://rubyworks.github.com/yes
|
8
|
+
|
9
|
+
Copyright 2011 Thomas Sawyer. All rights reserved.
|
10
|
+
|
11
|
+
Redistribution and use in source and binary forms, with or without
|
12
|
+
modification, are permitted provided that the following conditions are met:
|
13
|
+
|
14
|
+
* Redistributions of source code must retain the above copyright notice,
|
15
|
+
this list of conditions and the following disclaimer.
|
16
|
+
|
17
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
18
|
+
this list of conditions and the following disclaimer in the documentation
|
19
|
+
and/or other materials provided with the distribution.
|
20
|
+
|
21
|
+
THIS SOFTWARE IS PROVIDED BY Thomas Sawyer ``AS IS'' AND ANY EXPRESS
|
22
|
+
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
23
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
24
|
+
NO EVENT SHALL Thomas Sawyer OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
25
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
26
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
27
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
28
|
+
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
29
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
30
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
31
|
+
|
32
|
+
The views and conclusions contained in the software and documentation are
|
33
|
+
those of the authors and should not be interpreted as representing official
|
34
|
+
policies, either expressed or implied, of Thomas Sawyer.
|
35
|
+
|
data/QED.rdoc
ADDED
@@ -0,0 +1,1036 @@
|
|
1
|
+
= Test Battery
|
2
|
+
|
3
|
+
The following is a long set of validation scenarios, each
|
4
|
+
consists of a schema followed by a set of YAML documents
|
5
|
+
that should or should not be valid under it.
|
6
|
+
|
7
|
+
|
8
|
+
## Count Validation
|
9
|
+
|
10
|
+
Given a Schema:
|
11
|
+
|
12
|
+
---
|
13
|
+
//foo:
|
14
|
+
count: 1
|
15
|
+
|
16
|
+
Then this YAML document is valid:
|
17
|
+
|
18
|
+
---
|
19
|
+
foo: true
|
20
|
+
|
21
|
+
And this YAML document is valid:
|
22
|
+
|
23
|
+
---
|
24
|
+
foo: true
|
25
|
+
bar: true
|
26
|
+
|
27
|
+
But this YAML document is not valid:
|
28
|
+
|
29
|
+
---
|
30
|
+
- foo: true
|
31
|
+
- foo: true
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
## Exclusive Constraints
|
36
|
+
|
37
|
+
As a reminder, exclusion can either be a boolean expression, in which case
|
38
|
+
it validates that there is no more than one matching node, or the value
|
39
|
+
is taken to be a YPath and validates that there are no matching paths
|
40
|
+
if the main selection is present.
|
41
|
+
|
42
|
+
### Boolean Cases
|
43
|
+
|
44
|
+
Given a Schema:
|
45
|
+
|
46
|
+
---
|
47
|
+
//foo:
|
48
|
+
exclusive: true
|
49
|
+
|
50
|
+
Then this YAML document is valid:
|
51
|
+
|
52
|
+
---
|
53
|
+
- foo: true
|
54
|
+
|
55
|
+
And this YAML document is valid:
|
56
|
+
|
57
|
+
---
|
58
|
+
- foo: true
|
59
|
+
- bar: true
|
60
|
+
|
61
|
+
But this YAML document is not valid:
|
62
|
+
|
63
|
+
---
|
64
|
+
- foo: true
|
65
|
+
- foo: false
|
66
|
+
|
67
|
+
### YPath Cases
|
68
|
+
|
69
|
+
Given a Schema:
|
70
|
+
|
71
|
+
---
|
72
|
+
//foo:
|
73
|
+
exclusive: //bar
|
74
|
+
|
75
|
+
Then this YAML document is valid:
|
76
|
+
|
77
|
+
---
|
78
|
+
- foo: true
|
79
|
+
|
80
|
+
But this YAML document is not valid:
|
81
|
+
|
82
|
+
---
|
83
|
+
- foo: true
|
84
|
+
- bar: false
|
85
|
+
|
86
|
+
|
87
|
+
## Inclusive Constraints
|
88
|
+
|
89
|
+
As a reminder, inclusion can either be a boolean expression,
|
90
|
+
in which case it validates that there is at least one matching
|
91
|
+
node, or the value is taken to be a ypath and validates that
|
92
|
+
there are matching paths if the main selection is present.
|
93
|
+
|
94
|
+
### Boolean Cases
|
95
|
+
|
96
|
+
Given a Schema:
|
97
|
+
|
98
|
+
---
|
99
|
+
//foo:
|
100
|
+
inclusive: true
|
101
|
+
|
102
|
+
Then this YAML document is valid:
|
103
|
+
|
104
|
+
---
|
105
|
+
foo: true
|
106
|
+
|
107
|
+
And this YAML document is valid:
|
108
|
+
|
109
|
+
---
|
110
|
+
foo: true
|
111
|
+
bar: true
|
112
|
+
|
113
|
+
But this YAML document is not valid:
|
114
|
+
|
115
|
+
---
|
116
|
+
bar: true
|
117
|
+
|
118
|
+
### YPath Cases
|
119
|
+
|
120
|
+
Given a Schema:
|
121
|
+
|
122
|
+
---
|
123
|
+
//foo:
|
124
|
+
inclusive: //bar
|
125
|
+
|
126
|
+
Then this YAML document is valid:
|
127
|
+
|
128
|
+
---
|
129
|
+
- foo: true
|
130
|
+
- bar: true
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
## Tag Validation
|
135
|
+
|
136
|
+
Given a Schema:
|
137
|
+
|
138
|
+
---
|
139
|
+
//name:
|
140
|
+
tag: "!<tag:yes.com,2011:name>"
|
141
|
+
|
142
|
+
Then this YAML document is valid:
|
143
|
+
|
144
|
+
---
|
145
|
+
name: !!<tag:yes.com,2011:name> Choo Choo Train
|
146
|
+
|
147
|
+
And this YAML document is valid:
|
148
|
+
|
149
|
+
---
|
150
|
+
- name: !!<tag:yes.com,2011:name> Choo Choo Train
|
151
|
+
|
152
|
+
But this YAML document is not valid:
|
153
|
+
|
154
|
+
---
|
155
|
+
- name: Choo Choo Train
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
# Constraints
|
160
|
+
|
161
|
+
|
162
|
+
## Tag Constraint
|
163
|
+
|
164
|
+
Given a schema with a `type` constraint:
|
165
|
+
|
166
|
+
---
|
167
|
+
//name:
|
168
|
+
tag: '<tag:yes.com,2011:name>'
|
169
|
+
|
170
|
+
And a YAML document that has matching nodes:
|
171
|
+
|
172
|
+
---
|
173
|
+
- name: !!<tag:yes.com,2011:name> Choo Choo Train
|
174
|
+
|
175
|
+
Then validation of the YAML document with the schema will
|
176
|
+
be valid and retun no validation errors.
|
177
|
+
|
178
|
+
yes = YES::Lint.new(@schema)
|
179
|
+
errors = yes.validate(@yaml)
|
180
|
+
errors.assert.empty?
|
181
|
+
|
182
|
+
If given a YAML document that lacks matching nodes:
|
183
|
+
|
184
|
+
---
|
185
|
+
- name: Jar Jar Binks
|
186
|
+
|
187
|
+
Then the validation will return errors.
|
188
|
+
|
189
|
+
errors = yes.validate(@yaml)
|
190
|
+
errors.refute.empty?
|
191
|
+
|
192
|
+
|
193
|
+
## Type Constraint
|
194
|
+
|
195
|
+
Given a schema with a `type` constraint:
|
196
|
+
|
197
|
+
---
|
198
|
+
//foo:
|
199
|
+
type: str
|
200
|
+
|
201
|
+
And a YAML document that has matching nodes:
|
202
|
+
|
203
|
+
---
|
204
|
+
- foo: I'm a string!
|
205
|
+
|
206
|
+
Then validation of the YAML document with the schema will
|
207
|
+
be valid and retun no validation errors.
|
208
|
+
|
209
|
+
yes = YES::Lint.new(@schema)
|
210
|
+
errors = yes.validate(@yaml)
|
211
|
+
errors.assert.empty?
|
212
|
+
|
213
|
+
If given a YAML document that lacks matching nodes:
|
214
|
+
|
215
|
+
---
|
216
|
+
- foo: 15907
|
217
|
+
|
218
|
+
Then the validation will return errors.
|
219
|
+
|
220
|
+
errors = yes.validate(@yaml)
|
221
|
+
errors.refute.empty?
|
222
|
+
|
223
|
+
|
224
|
+
## Requires Constraint
|
225
|
+
|
226
|
+
Given a schema with a `requires` constraint:
|
227
|
+
|
228
|
+
---
|
229
|
+
/foo:
|
230
|
+
requires:
|
231
|
+
- bar
|
232
|
+
|
233
|
+
And a YAML document that has the required path:
|
234
|
+
|
235
|
+
---
|
236
|
+
foo:
|
237
|
+
bar: true
|
238
|
+
|
239
|
+
Then validation of the YAML document with the schema will
|
240
|
+
ve valid and retun no validation errors.
|
241
|
+
|
242
|
+
yes = YES::Lint.new(@schema)
|
243
|
+
yes.validate(@yaml).assert.empty?
|
244
|
+
|
245
|
+
Given a YAML document that lacks the required path:
|
246
|
+
|
247
|
+
---
|
248
|
+
foo: true
|
249
|
+
|
250
|
+
Then the validation will return errors.
|
251
|
+
|
252
|
+
errors = yes.validate(@yaml)
|
253
|
+
errors.refute.empty?
|
254
|
+
|
255
|
+
TODO: more detailed assertions on returned errors list.
|
256
|
+
|
257
|
+
|
258
|
+
## Range Constraint
|
259
|
+
|
260
|
+
### Fixed Range
|
261
|
+
|
262
|
+
Given a schema with a `range` constraint using a single value,
|
263
|
+
e.g. `1` then the range is equivalent to `1..1`:
|
264
|
+
|
265
|
+
---
|
266
|
+
//foo:
|
267
|
+
range: 1
|
268
|
+
|
269
|
+
And a YAML document that has matching nodes:
|
270
|
+
|
271
|
+
---
|
272
|
+
- foo: 1
|
273
|
+
|
274
|
+
Then validation of the YAML document with the schema will
|
275
|
+
ve valid and retun no validation errors.
|
276
|
+
|
277
|
+
yes = YES::Lint.new(@schema)
|
278
|
+
errors = yes.validate(@yaml)
|
279
|
+
errors.assert.empty?
|
280
|
+
|
281
|
+
If given a YAML document that lacks matching nodes:
|
282
|
+
|
283
|
+
---
|
284
|
+
- foo: 2
|
285
|
+
|
286
|
+
Then the validation will return errors.
|
287
|
+
|
288
|
+
errors = yes.validate(@yaml)
|
289
|
+
errors.refute.empty?
|
290
|
+
|
291
|
+
### Range
|
292
|
+
|
293
|
+
Given a schema with a `range` constraint using a fixed range:
|
294
|
+
|
295
|
+
---
|
296
|
+
//foo:
|
297
|
+
range: 1..2
|
298
|
+
|
299
|
+
And a YAML document that has matching nodes:
|
300
|
+
|
301
|
+
---
|
302
|
+
- foo: 1
|
303
|
+
- foo: 2
|
304
|
+
|
305
|
+
Then validation of the YAML document with the schema will
|
306
|
+
ve valid and retun no validation errors.
|
307
|
+
|
308
|
+
yes = YES::Lint.new(@schema)
|
309
|
+
errors = yes.validate(@yaml)
|
310
|
+
errors.assert.empty?
|
311
|
+
|
312
|
+
If given a YAML document that lacks matching nodes:
|
313
|
+
|
314
|
+
---
|
315
|
+
- foo: 3
|
316
|
+
|
317
|
+
Then the validation will return errors.
|
318
|
+
|
319
|
+
errors = yes.validate(@yaml)
|
320
|
+
errors.refute.empty?
|
321
|
+
|
322
|
+
### Range N
|
323
|
+
|
324
|
+
Given a schema with a `range` constraint using a range from a fixed number
|
325
|
+
to `n`, respesenting infinity:
|
326
|
+
|
327
|
+
---
|
328
|
+
//foo:
|
329
|
+
range: 2..n
|
330
|
+
|
331
|
+
And a YAML document that has matching nodes:
|
332
|
+
|
333
|
+
---
|
334
|
+
- foo: 2
|
335
|
+
- foo: 3
|
336
|
+
|
337
|
+
Then validation of the YAML document with the schema will
|
338
|
+
be valid and retun no validation errors.
|
339
|
+
|
340
|
+
yes = YES::Lint.new(@schema)
|
341
|
+
errors = yes.validate(@yaml)
|
342
|
+
errors.assert.empty?
|
343
|
+
|
344
|
+
If given a YAML document that lacks matching nodes:
|
345
|
+
|
346
|
+
---
|
347
|
+
- foo: 1
|
348
|
+
|
349
|
+
Then the validation will return errors.
|
350
|
+
|
351
|
+
errors = yes.validate(@yaml)
|
352
|
+
errors.refute.empty?
|
353
|
+
|
354
|
+
TODO: more detailed assertions on returned errors list.
|
355
|
+
|
356
|
+
|
357
|
+
= Regular Expression Constraint
|
358
|
+
|
359
|
+
Becuase regular expresion engines can vary somewhat across implementations
|
360
|
+
it is wise to stick to the basics.
|
361
|
+
|
362
|
+
Given a schema with a `regexp` constraint:
|
363
|
+
|
364
|
+
---
|
365
|
+
//email:
|
366
|
+
regexp: /@/
|
367
|
+
|
368
|
+
And a YAML document that has matching nodes:
|
369
|
+
|
370
|
+
---
|
371
|
+
- email: foo@foo.net
|
372
|
+
|
373
|
+
Then validation of the YAML document with the schema will
|
374
|
+
be valid and retun no validation errors.
|
375
|
+
|
376
|
+
yes = YES::Lint.new(@schema)
|
377
|
+
|
378
|
+
errors = yes.validate(@yaml)
|
379
|
+
errors.assert.empty?
|
380
|
+
|
381
|
+
If given a YAML document that lacks matching nodes:
|
382
|
+
|
383
|
+
---
|
384
|
+
- email: 15907
|
385
|
+
|
386
|
+
Then the validation will return errors.
|
387
|
+
|
388
|
+
errors = yes.validate(@yaml)
|
389
|
+
errors.refute.empty?
|
390
|
+
|
391
|
+
|
392
|
+
= File Name Constraint
|
393
|
+
|
394
|
+
Given a schema with a `fnmatch` constraint:
|
395
|
+
|
396
|
+
---
|
397
|
+
//path:
|
398
|
+
fnmatch: "*.rb"
|
399
|
+
|
400
|
+
And a YAML document that has matching nodes:
|
401
|
+
|
402
|
+
---
|
403
|
+
- email: foo.rb
|
404
|
+
|
405
|
+
Then validation of the YAML document with the schema will
|
406
|
+
be valid and retun no validation errors.
|
407
|
+
|
408
|
+
yes = YES::Lint.new(@schema)
|
409
|
+
errors = yes.validate(@yaml)
|
410
|
+
errors.assert.empty?
|
411
|
+
|
412
|
+
If given a YAML document that lacks matching nodes:
|
413
|
+
|
414
|
+
---
|
415
|
+
- path: foo.txt
|
416
|
+
|
417
|
+
Then the validation will return errors.
|
418
|
+
|
419
|
+
errors = yes.validate(@yaml)
|
420
|
+
errors.refute.empty?
|
421
|
+
|
422
|
+
|
423
|
+
## Length Constraint
|
424
|
+
|
425
|
+
### Fixed Length
|
426
|
+
|
427
|
+
Given a schema with a `length` constraint using a single number:
|
428
|
+
|
429
|
+
---
|
430
|
+
//foo:
|
431
|
+
length: 1
|
432
|
+
|
433
|
+
And a YAML document that has that number of nodes:
|
434
|
+
|
435
|
+
---
|
436
|
+
- foo: "A"
|
437
|
+
|
438
|
+
Then validation of the YAML document with the schema will
|
439
|
+
ve valid and retun no validation errors.
|
440
|
+
|
441
|
+
yes = YES::Lint.new(@schema)
|
442
|
+
errors = yes.validate(@yaml)
|
443
|
+
errors.assert.empty?
|
444
|
+
|
445
|
+
If given a YAML document that lacks the right number of nodes:
|
446
|
+
|
447
|
+
---
|
448
|
+
- foo: "AB"
|
449
|
+
|
450
|
+
Then the validation will return errors.
|
451
|
+
|
452
|
+
errors = yes.validate(@yaml)
|
453
|
+
errors.refute.empty?
|
454
|
+
|
455
|
+
### Range
|
456
|
+
|
457
|
+
Given a schema with a `length` constraint using a fixed range:
|
458
|
+
|
459
|
+
---
|
460
|
+
//foo:
|
461
|
+
length: 1..2
|
462
|
+
|
463
|
+
And a YAML document that has that range of nodes:
|
464
|
+
|
465
|
+
---
|
466
|
+
- foo: "A"
|
467
|
+
- foo: "AB"
|
468
|
+
|
469
|
+
Then validation of the YAML document with the schema will
|
470
|
+
ve valid and retun no validation errors.
|
471
|
+
|
472
|
+
yes = YES::Lint.new(@schema)
|
473
|
+
errors = yes.validate(@yaml)
|
474
|
+
errors.assert.empty?
|
475
|
+
|
476
|
+
If given a YAML document that lacks the right number of nodes:
|
477
|
+
|
478
|
+
---
|
479
|
+
- foo: ""
|
480
|
+
- foo: "ABC"
|
481
|
+
|
482
|
+
Then the validation will return errors.
|
483
|
+
|
484
|
+
errors = yes.validate(@yaml)
|
485
|
+
errors.refute.empty?
|
486
|
+
|
487
|
+
### Range N
|
488
|
+
|
489
|
+
Given a schema with a `length` constraint using a range from a fixed number
|
490
|
+
to `n`, respesenting infinity:
|
491
|
+
|
492
|
+
---
|
493
|
+
//foo:
|
494
|
+
length: 2..n
|
495
|
+
|
496
|
+
And a YAML document that has such a range of nodes:
|
497
|
+
|
498
|
+
---
|
499
|
+
- foo: "AB"
|
500
|
+
- foo: "ABC"
|
501
|
+
|
502
|
+
Then validation of the YAML document with the schema will
|
503
|
+
be valid and retun no validation errors.
|
504
|
+
|
505
|
+
yes = YES::Lint.new(@schema)
|
506
|
+
errors = yes.validate(@yaml)
|
507
|
+
errors.assert.empty?
|
508
|
+
|
509
|
+
If given a YAML document that lacks the right number of nodes:
|
510
|
+
|
511
|
+
---
|
512
|
+
- foo: "A"
|
513
|
+
|
514
|
+
Then the validation will return errors.
|
515
|
+
|
516
|
+
errors = yes.validate(@yaml)
|
517
|
+
errors.refute.empty?
|
518
|
+
|
519
|
+
TODO: more detailed assertions on returned errors list.
|
520
|
+
|
521
|
+
|
522
|
+
## Count Constraint
|
523
|
+
|
524
|
+
### Fixed Count
|
525
|
+
|
526
|
+
Given a schema with a `count` constraint using a single number:
|
527
|
+
|
528
|
+
---
|
529
|
+
//foo:
|
530
|
+
count: 1
|
531
|
+
|
532
|
+
And a YAML document that has that number of nodes:
|
533
|
+
|
534
|
+
---
|
535
|
+
- foo: true
|
536
|
+
|
537
|
+
Then validation of the YAML document with the schema will
|
538
|
+
ve valid and retun no validation errors.
|
539
|
+
|
540
|
+
yes = YES::Lint.new(@schema)
|
541
|
+
errors = yes.validate(@yaml)
|
542
|
+
errors.assert.empty?
|
543
|
+
|
544
|
+
If given a YAML document that lacks the right number of nodes:
|
545
|
+
|
546
|
+
---
|
547
|
+
- foo: true
|
548
|
+
- foo: true
|
549
|
+
|
550
|
+
Then the validation will return errors.
|
551
|
+
|
552
|
+
errors = yes.validate(@yaml)
|
553
|
+
errors.refute.empty?
|
554
|
+
|
555
|
+
### Range
|
556
|
+
|
557
|
+
Given a schema with a `count` constraint using a fixed range:
|
558
|
+
|
559
|
+
---
|
560
|
+
//foo:
|
561
|
+
count: 1..2
|
562
|
+
|
563
|
+
And a YAML document that has that range of nodes:
|
564
|
+
|
565
|
+
---
|
566
|
+
- foo: true
|
567
|
+
|
568
|
+
Then validation of the YAML document with the schema will
|
569
|
+
ve valid and retun no validation errors.
|
570
|
+
|
571
|
+
yes = YES::Lint.new(@schema)
|
572
|
+
errors = yes.validate(@yaml)
|
573
|
+
errors.assert.empty?
|
574
|
+
|
575
|
+
If given a YAML document that lacks the right number of nodes:
|
576
|
+
|
577
|
+
---
|
578
|
+
- foo: true
|
579
|
+
- foo: true
|
580
|
+
- foo: true
|
581
|
+
|
582
|
+
Then the validation will return errors.
|
583
|
+
|
584
|
+
errors = yes.validate(@yaml)
|
585
|
+
errors.refute.empty?
|
586
|
+
|
587
|
+
### Range N
|
588
|
+
|
589
|
+
Given a schema with a `count` constraint using a range from a fixed number
|
590
|
+
to `n`, respesenting infinity:
|
591
|
+
|
592
|
+
---
|
593
|
+
//foo:
|
594
|
+
count: 2..n
|
595
|
+
|
596
|
+
And a YAML document that has such a range of nodes:
|
597
|
+
|
598
|
+
---
|
599
|
+
- foo: true
|
600
|
+
- foo: true
|
601
|
+
- foo: true
|
602
|
+
|
603
|
+
Then validation of the YAML document with the schema will
|
604
|
+
be valid and retun no validation errors.
|
605
|
+
|
606
|
+
yes = YES::Lint.new(@schema)
|
607
|
+
errors = yes.validate(@yaml)
|
608
|
+
errors.assert.empty?
|
609
|
+
|
610
|
+
If given a YAML document that lacks the right number of nodes:
|
611
|
+
|
612
|
+
---
|
613
|
+
- foo: true
|
614
|
+
|
615
|
+
Then the validation will return errors.
|
616
|
+
|
617
|
+
errors = yes.validate(@yaml)
|
618
|
+
errors.refute.empty?
|
619
|
+
|
620
|
+
TODO: more detailed assertions on returned errors list.
|
621
|
+
|
622
|
+
|
623
|
+
## Inclusive Constraint
|
624
|
+
|
625
|
+
### Boolean
|
626
|
+
|
627
|
+
Given a schema with an `inclusive` constraint using a boolean value:
|
628
|
+
|
629
|
+
---
|
630
|
+
//foo:
|
631
|
+
inclusive: true
|
632
|
+
|
633
|
+
And a YAML document that has that includes a matching node:
|
634
|
+
|
635
|
+
---
|
636
|
+
- foo: true
|
637
|
+
|
638
|
+
Then validation of the YAML document with the schema will
|
639
|
+
ve valid and retun no validation errors.
|
640
|
+
|
641
|
+
yes = YES::Lint.new(@schema)
|
642
|
+
errors = yes.validate(@yaml)
|
643
|
+
errors.assert.empty?
|
644
|
+
|
645
|
+
If given a YAML document that lacks a matching node:
|
646
|
+
|
647
|
+
---
|
648
|
+
- bar: true
|
649
|
+
- baz: true
|
650
|
+
|
651
|
+
Then the validation will return errors.
|
652
|
+
|
653
|
+
errors = yes.validate(@yaml)
|
654
|
+
errors.refute.empty?
|
655
|
+
|
656
|
+
### YPath
|
657
|
+
|
658
|
+
Given a schema with an `inclusive` constraint using a YPath value:
|
659
|
+
|
660
|
+
---
|
661
|
+
//foo:
|
662
|
+
inclusive: //bar
|
663
|
+
|
664
|
+
And a YAML document that has that includes a matching node:
|
665
|
+
|
666
|
+
---
|
667
|
+
- foo: true
|
668
|
+
- bar: true
|
669
|
+
|
670
|
+
Then validation of the YAML document with the schema will
|
671
|
+
ve valid and retun no validation errors.
|
672
|
+
|
673
|
+
yes = YES::Lint.new(@schema)
|
674
|
+
errors = yes.validate(@yaml)
|
675
|
+
errors.assert.empty?
|
676
|
+
|
677
|
+
If given a YAML document that lacks a matching node:
|
678
|
+
|
679
|
+
---
|
680
|
+
- foo: true
|
681
|
+
- baz: true
|
682
|
+
|
683
|
+
Then the validation will return errors.
|
684
|
+
|
685
|
+
errors = yes.validate(@yaml)
|
686
|
+
errors.refute.empty?
|
687
|
+
|
688
|
+
|
689
|
+
## Exclusive Constraint
|
690
|
+
|
691
|
+
### Boolean
|
692
|
+
|
693
|
+
Given a schema with an `exclusive` constraint using a boolean value:
|
694
|
+
|
695
|
+
---
|
696
|
+
//foo:
|
697
|
+
exclusive: true
|
698
|
+
|
699
|
+
And a YAML document that has that includes a matching node:
|
700
|
+
|
701
|
+
---
|
702
|
+
- foo: true
|
703
|
+
|
704
|
+
Then validation of the YAML document with the schema will
|
705
|
+
ve valid and retun no validation errors.
|
706
|
+
|
707
|
+
yes = YES::Lint.new(@schema)
|
708
|
+
errors = yes.validate(@yaml)
|
709
|
+
errors.assert.empty?
|
710
|
+
|
711
|
+
If given a YAML document that lacks a matching node:
|
712
|
+
|
713
|
+
---
|
714
|
+
- foo: true
|
715
|
+
- foo: true
|
716
|
+
|
717
|
+
Then the validation will return errors.
|
718
|
+
|
719
|
+
errors = yes.validate(@yaml)
|
720
|
+
errors.refute.empty?
|
721
|
+
|
722
|
+
### YPath
|
723
|
+
|
724
|
+
Given a schema with an `exclusive` constraint using a YPath value:
|
725
|
+
|
726
|
+
---
|
727
|
+
//foo:
|
728
|
+
exclusive: //bar
|
729
|
+
|
730
|
+
And a YAML document that has that includes a matching node:
|
731
|
+
|
732
|
+
---
|
733
|
+
- foo: true
|
734
|
+
- gah: true
|
735
|
+
|
736
|
+
Then validation of the YAML document with the schema will
|
737
|
+
ve valid and retun no validation errors.
|
738
|
+
|
739
|
+
yes = YES::Lint.new(@schema)
|
740
|
+
errors = yes.validate(@yaml)
|
741
|
+
errors.assert.empty?
|
742
|
+
|
743
|
+
If given a YAML document that lacks a matching node:
|
744
|
+
|
745
|
+
---
|
746
|
+
- foo: true
|
747
|
+
- bar: true
|
748
|
+
|
749
|
+
Then the validation will return errors.
|
750
|
+
|
751
|
+
errors = yes.validate(@yaml)
|
752
|
+
errors.refute.empty?
|
753
|
+
|
754
|
+
That covers the basics of exclusive constraints.
|
755
|
+
See here[../99_battery/exclusive_validations.md]
|
756
|
+
for an exhustive battery of tests.
|
757
|
+
|
758
|
+
## Value Constraint
|
759
|
+
|
760
|
+
The value constraint differs from other constraints in that it
|
761
|
+
actually applies a separate set of constraints on the value
|
762
|
+
of a sequence's or mapping's elements.
|
763
|
+
|
764
|
+
Given a schema with an `valuee` constraint:
|
765
|
+
|
766
|
+
---
|
767
|
+
//foo:
|
768
|
+
value:
|
769
|
+
type: str
|
770
|
+
|
771
|
+
And a YAML document that that includes a matching node:
|
772
|
+
|
773
|
+
---
|
774
|
+
foo:
|
775
|
+
- "okay"
|
776
|
+
|
777
|
+
Then validation of the YAML document with the schema will
|
778
|
+
be valid and retun no validation errors.
|
779
|
+
|
780
|
+
yes = YES::Lint.new(@schema)
|
781
|
+
errors = yes.validate(@yaml)
|
782
|
+
errors.assert.empty?
|
783
|
+
|
784
|
+
If given a YAML document that lacks a matching node:
|
785
|
+
|
786
|
+
---
|
787
|
+
foo:
|
788
|
+
- 0
|
789
|
+
|
790
|
+
Then the validation will return errors.
|
791
|
+
|
792
|
+
errors = yes.validate(@yaml)
|
793
|
+
errors.refute.empty?
|
794
|
+
|
795
|
+
|
796
|
+
## Key Constraint
|
797
|
+
|
798
|
+
The key constraint differs from other constraints in that it
|
799
|
+
actually applies a separate set of constraints on the keys
|
800
|
+
of a mapping.
|
801
|
+
|
802
|
+
Given a schema with a `key` constraint:
|
803
|
+
|
804
|
+
---
|
805
|
+
//foo:
|
806
|
+
key:
|
807
|
+
type: str
|
808
|
+
|
809
|
+
And a YAML document that that includes a matching node:
|
810
|
+
|
811
|
+
---
|
812
|
+
foo:
|
813
|
+
bar: okay
|
814
|
+
baz: okay
|
815
|
+
|
816
|
+
Then validation of the YAML document with the schema will
|
817
|
+
be valid and retun no validation errors.
|
818
|
+
|
819
|
+
yes = YES::Lint.new(@schema)
|
820
|
+
errors = yes.validate(@yaml)
|
821
|
+
errors.assert.empty?
|
822
|
+
|
823
|
+
If given a YAML document that lacks a matching node:
|
824
|
+
|
825
|
+
---
|
826
|
+
foo:
|
827
|
+
0: "not okay"
|
828
|
+
1: "not okay"
|
829
|
+
|
830
|
+
Then the validation will return errors.
|
831
|
+
|
832
|
+
errors = yes.validate(@yaml)
|
833
|
+
errors.refute.empty?
|
834
|
+
|
835
|
+
|
836
|
+
## Required Constraint
|
837
|
+
|
838
|
+
Given a schema with a `required` constraint:
|
839
|
+
|
840
|
+
---
|
841
|
+
//foo:
|
842
|
+
required: true
|
843
|
+
|
844
|
+
And a YAML document that hasthe required path:
|
845
|
+
|
846
|
+
---
|
847
|
+
foo: true
|
848
|
+
|
849
|
+
Then validation of the YAML document with the schema will
|
850
|
+
ve valid and retun no validation errors.
|
851
|
+
|
852
|
+
yes = YES::Lint.new(@schema)
|
853
|
+
yes.validate(@yaml).assert.empty?
|
854
|
+
|
855
|
+
If given a YAML document that lacks the required path:
|
856
|
+
|
857
|
+
---
|
858
|
+
bar: true
|
859
|
+
|
860
|
+
Then the validation will return errors.
|
861
|
+
|
862
|
+
errors = yes.validate(@yaml)
|
863
|
+
errors.refute.empty?
|
864
|
+
|
865
|
+
TODO: more detailed assertions on returned errors list.
|
866
|
+
|
867
|
+
|
868
|
+
|
869
|
+
|
870
|
+
## Lint#select_nodes
|
871
|
+
|
872
|
+
The `select_nodes` method can take a YPath string or a complex selector.
|
873
|
+
|
874
|
+
A Complex selector is a mapping (i.e. a Ruby Hash) that uses node constraints
|
875
|
+
to select nodes from the document tree.
|
876
|
+
|
877
|
+
To try this out we need a Lint instance, which we will supply an empty, dummy
|
878
|
+
schema, as w won't be testing validation.
|
879
|
+
|
880
|
+
yes = YES::Lint.new('')
|
881
|
+
|
882
|
+
Given a YAML document:
|
883
|
+
|
884
|
+
---
|
885
|
+
- Choo Choo Train
|
886
|
+
- Choo Choo Toy
|
887
|
+
|
888
|
+
Which we parse into a node tree.
|
889
|
+
|
890
|
+
tree = YAML.parse(@yaml)
|
891
|
+
|
892
|
+
A complex selector can be used to match nodes using the #select_nodes method.
|
893
|
+
|
894
|
+
complex_selector = { regexp: /^Choo/ }
|
895
|
+
|
896
|
+
selected = yes.select_nodes(complex_selector, tree)
|
897
|
+
|
898
|
+
selected.size.assert == 2
|
899
|
+
|
900
|
+
|
901
|
+
## Sub-Selecting Nodes with Map Field
|
902
|
+
|
903
|
+
The `map` field, while appearing alongside constraint definitions
|
904
|
+
in the schema, is not actually a constraint, but rather a sub-ypath
|
905
|
+
selector that combines the parent ypath with the mapping keys
|
906
|
+
that are given under it. This provides a convenient way to keep
|
907
|
+
sub-paths local to their parent nodes, rather then create separate
|
908
|
+
long-name ypath entries. Obviously the `map` field only effectively
|
909
|
+
applies to mapping nodes.
|
910
|
+
|
911
|
+
Lets' take an example of the more explicit form:
|
912
|
+
|
913
|
+
---
|
914
|
+
foo:
|
915
|
+
type: map
|
916
|
+
foo/bar:
|
917
|
+
type: str
|
918
|
+
|
919
|
+
This can be writ instead, Given a schema with a `map` field:
|
920
|
+
|
921
|
+
---
|
922
|
+
foo:
|
923
|
+
type: map
|
924
|
+
map:
|
925
|
+
bar:
|
926
|
+
type: str
|
927
|
+
|
928
|
+
And a YAML document that includes a matching node:
|
929
|
+
|
930
|
+
---
|
931
|
+
foo:
|
932
|
+
bar: okay
|
933
|
+
|
934
|
+
Then validation of the YAML document with the schema will
|
935
|
+
be valid and retun no validation errors.
|
936
|
+
|
937
|
+
yes = YES::Lint.new(@schema)
|
938
|
+
errors = yes.validate(@yaml)
|
939
|
+
errors.assert.empty?
|
940
|
+
|
941
|
+
If given a YAML document that lacks a matching node:
|
942
|
+
|
943
|
+
---
|
944
|
+
foo:
|
945
|
+
bar: 0
|
946
|
+
|
947
|
+
Then the validation will return errors.
|
948
|
+
|
949
|
+
errors = yes.validate(@yaml)
|
950
|
+
errors.refute.empty?
|
951
|
+
|
952
|
+
|
953
|
+
## Using a Complex Selector
|
954
|
+
|
955
|
+
Given a schema with a hash based selector:
|
956
|
+
|
957
|
+
---
|
958
|
+
? { regexp: /^Choo/ }
|
959
|
+
: { count: 2 }
|
960
|
+
|
961
|
+
And a YAML document that has matching nodes:
|
962
|
+
|
963
|
+
---
|
964
|
+
- Choo Choo Train
|
965
|
+
- Choo Choo Toy
|
966
|
+
|
967
|
+
Then validation of the YAML document with the schema will
|
968
|
+
be valid and retun no validation errors.
|
969
|
+
|
970
|
+
yes = YES::Lint.new(@schema)
|
971
|
+
|
972
|
+
errors = yes.validate(@yaml)
|
973
|
+
errors.assert.empty?
|
974
|
+
|
975
|
+
If given a YAML document that lacks matching nodes:
|
976
|
+
|
977
|
+
---
|
978
|
+
- Choo Choo Train
|
979
|
+
|
980
|
+
Then the validation will return errors.
|
981
|
+
|
982
|
+
errors = yes.validate(@yaml)
|
983
|
+
errors.refute.empty?
|
984
|
+
|
985
|
+
|
986
|
+
## YPath Index
|
987
|
+
|
988
|
+
Given a YAML document:
|
989
|
+
|
990
|
+
---
|
991
|
+
foo: "foo1"
|
992
|
+
bar:
|
993
|
+
foo: "foo2"
|
994
|
+
baz: "baz"
|
995
|
+
|
996
|
+
Lets let try out some YPaths.
|
997
|
+
|
998
|
+
s = @yaml.select('foo')
|
999
|
+
|
1000
|
+
s.size.assert == 1
|
1001
|
+
|
1002
|
+
s1 = s.first
|
1003
|
+
s1.value.assert == "foo1"
|
1004
|
+
|
1005
|
+
Try another
|
1006
|
+
|
1007
|
+
s = @yaml.select('//foo')
|
1008
|
+
|
1009
|
+
s.size.assert == 2
|
1010
|
+
|
1011
|
+
s1 = s.last
|
1012
|
+
s1.value.assert == "foo2"
|
1013
|
+
|
1014
|
+
|
1015
|
+
## YPath by Tag
|
1016
|
+
|
1017
|
+
Given a YAML document:
|
1018
|
+
|
1019
|
+
---
|
1020
|
+
foo: "foo1"
|
1021
|
+
bar: !example
|
1022
|
+
foo: "foo2"
|
1023
|
+
baz: "baz"
|
1024
|
+
|
1025
|
+
It would be nice if we could select nodes by tag, like:
|
1026
|
+
|
1027
|
+
s = @yaml.select('!example')
|
1028
|
+
|
1029
|
+
s.size.assert == 1
|
1030
|
+
|
1031
|
+
s1 = s.first
|
1032
|
+
s1.type.assert == "map"
|
1033
|
+
|
1034
|
+
But this does not work at this time.
|
1035
|
+
|
1036
|
+
|