kwalify 0.4.1 → 0.5.0

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.
@@ -0,0 +1,179 @@
1
+ ###
2
+ ### $Rev: 42 $
3
+ ### $Release: 0.5.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ unless defined?(TESTDIR)
8
+ TESTDIR = File.dirname(__FILE__)
9
+ libdir = File.dirname(TESTDIR) + "/lib"
10
+ $LOAD_PATH << libdir << TESTDIR
11
+ end
12
+
13
+ require 'test/unit'
14
+ require 'test/unit/ui/console/testrunner'
15
+ require 'kwalify'
16
+ require 'kwalify/util/assert-diff'
17
+ require 'kwalify/main.rb'
18
+ require 'yaml'
19
+
20
+ module Kwalify
21
+ class Main
22
+ public :_parse_argv
23
+ end
24
+ end
25
+
26
+ class File
27
+ def self.move(filename, dirname)
28
+ File.rename(filename, "#{dirname}/filename")
29
+ end
30
+ end
31
+
32
+ class MainTest < Test::Unit::TestCase
33
+
34
+ ## define test methods
35
+ filename = __FILE__.sub(/\.rb$/, ".yaml")
36
+ str = File.read(filename)
37
+ @@docs = {}
38
+ YAML.load_documents(str) do |doc|
39
+ name = doc['name']
40
+ !@@docs.key?(name) or raise "*** test name '#{name}' is duplicated."
41
+ @@docs[name] = doc
42
+ doc.each do |key, val|
43
+ doc[$1] ||= val['ruby'] if key =~ /\A(.*)\*\z/
44
+ end
45
+ s = <<-END
46
+ def test_#{name}
47
+ doc = @@docs['#{name}']
48
+ @name = doc['name']
49
+ @desc = doc['desc']
50
+ @args = doc['args']
51
+ @inspect = doc['inspect']
52
+ @exception = #{doc['exception'] ? "Kwalify::" + doc['exception'] : 'nil'}
53
+ @error_symbol = doc['error_symbol']
54
+ @expected = doc['expected']
55
+ @schema = doc['schema']
56
+ @document = doc['document']
57
+ @valid = doc['valid']
58
+ @invalid = doc['invalid']
59
+ @valid_out = doc['valid-out']
60
+ @invalid_out = doc['invalid-out']
61
+ @method = doc['method']
62
+ # @options = doc['options']
63
+
64
+ case @method
65
+ when 'parseOptions'
66
+ _test_parse_options()
67
+ when 'execute'
68
+ raise "*** #{doc['name']}: args is not defined." unless doc['args']
69
+ raise "*** #{doc['name']}: expected is not defined." unless doc['expected']
70
+ _test_execute()
71
+ when 'validation'
72
+ _test_validation()
73
+ raise "*** #{doc['name']}: schema is not defined." unless doc['schema']
74
+ raise "*** #{doc['name']}: valid is not defined." unless doc['valid']
75
+ raise "*** #{doc['name']}: invalid is not defined." unless doc['invalid']
76
+
77
+ else
78
+ raise "*** #{@method}: invalid method name."
79
+ end
80
+ end
81
+ END
82
+ eval s
83
+ end
84
+
85
+
86
+ ## temporary directory
87
+ @@tmpdir = "tmp.dir"
88
+ Dir.mkdir(@@tmpdir) unless test(?d, @@tmpdir)
89
+
90
+
91
+ ## validation test
92
+ def _test_validation()
93
+ return if $target && $target != @name
94
+ raise "*** schema is not defined." unless @schema
95
+ raise "*** valid is not defined." unless @valid
96
+ raise "*** invalid is not defined." unless @invalid
97
+ #
98
+ schema_filename = @name + ".schema"
99
+ valid_filename = @name + ".valid"
100
+ invalid_filename = @name + ".invalid"
101
+ #
102
+ begin
103
+ #
104
+ File.open(schema_filename, 'w') { |f| f.write(@schema) }
105
+ File.open(valid_filename, 'w') { |f| f.write(@valid) }
106
+ File.open(invalid_filename, 'w') { |f| f.write(@invalid) }
107
+ #
108
+ main = Kwalify::Main.new('kwalify')
109
+ args = [ "-lf", schema_filename, valid_filename ]
110
+ output = main.execute(args)
111
+ assert_equal_with_diff(@valid_out, output)
112
+ #
113
+ main = Kwalify::Main.new('kwalify')
114
+ args = [ "-lf", schema_filename, invalid_filename ]
115
+ output = main.execute(args)
116
+ assert_equal_with_diff(@invalid_out, output)
117
+ #
118
+ ensure
119
+ File.move(schema_filename, @@tmpdir)
120
+ File.move(valid_filename, @@tmpdir)
121
+ File.move(invalid_filename, @@tmpdir)
122
+ end
123
+ end
124
+
125
+ ## execute test
126
+ def _test_execute()
127
+ return if $target && $target != @name
128
+ raise "*** args is required when method is 'execute'." unless @args
129
+ raise "*** expected is required when method is 'execute'." unless @expected
130
+ #
131
+ File.open("#{@name}.schema", 'w') { |f| f.write(@schema) } if @schema
132
+ File.open("#{@name}.document", 'w') { |f| f.write(@document) } if @document
133
+ #
134
+ begin
135
+ main = Kwalify::Main.new("kwalify")
136
+ if (! @exception)
137
+ actual = main.execute(@args)
138
+ assert_equal_with_diff(@expected, actual)
139
+ else
140
+ assert_raise(@exception) do
141
+ main.execute(@args)
142
+ end
143
+ end
144
+ ensure
145
+ File.move("#{@name}.schema", @@tmpdir) if @schema
146
+ File.move("#{@name}.document", @@tmpdir) if @document
147
+ end
148
+ end
149
+
150
+ ## command option test
151
+ def _test_parse_options()
152
+ return if $target && $target != @name
153
+ main = Kwalify::Main.new("kwalify")
154
+ begin
155
+ filenames = main._parse_argv(@args)
156
+ s = main._inspect()
157
+ s << "filenames:\n"
158
+ filenames.each do |filename|
159
+ s << " - #{filename}\n"
160
+ end
161
+ actual = s
162
+ assert_equal_with_diff(@inspect, actual)
163
+ rescue => ex
164
+ #klass = @exception
165
+ if @exception && ex.class == @exception
166
+ # OK
167
+ assert_equal(@error_symbol, ex.error_symbol) if ex.respond_to?(:error_symbol)
168
+ else
169
+ # NG
170
+ raise ex
171
+ end
172
+ end
173
+ end
174
+
175
+ end
176
+
177
+ #if $0 == __FILE__
178
+ # Test::Unit::UI::Console::TestRunner.run(ValidatorTest)
179
+ #end
@@ -0,0 +1,756 @@
1
+ ##
2
+ ## $Rev: 42 $
3
+ ## $Release: 0.5.0 $
4
+ ## copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ##
6
+ ---
7
+ name: parseOptions1
8
+ desc: test Main#parseOptions()
9
+ method: parseOptions
10
+ args: [ -hvsmtlDf, schema.yaml, document.yaml, document2.yaml ]
11
+ inspect: |
12
+ command : kwalify
13
+ flag_help : true
14
+ flag_version : true
15
+ flag_silent : true
16
+ flag_meta : true
17
+ flag_untabify : true
18
+ flag_linenum : true
19
+ flag_debug : true
20
+ schema_filename : schema.yaml
21
+ properties:
22
+ filenames:
23
+ - document.yaml
24
+ - document2.yaml
25
+ #
26
+ ---
27
+ name: parseOptions2
28
+ desc: -ffilename
29
+ method: parseOptions
30
+ args: [ -lfschema.yaml]
31
+ inspect: |
32
+ command : kwalify
33
+ flag_help : false
34
+ flag_version : false
35
+ flag_silent : false
36
+ flag_meta : false
37
+ flag_untabify : false
38
+ flag_linenum : true
39
+ flag_debug : false
40
+ schema_filename : schema.yaml
41
+ properties:
42
+ filenames:
43
+ #
44
+ ---
45
+ name: parseOptions3
46
+ desc: "'--help' is equal to '-h'"
47
+ method: parseOptions
48
+ args: [ --help, document.yaml ]
49
+ inspect: |
50
+ command : kwalify
51
+ flag_help : true
52
+ flag_version : false
53
+ flag_silent : false
54
+ flag_meta : false
55
+ flag_untabify : false
56
+ flag_linenum : false
57
+ flag_debug : false
58
+ schema_filename : null
59
+ properties:
60
+ help: true
61
+ filenames:
62
+ - document.yaml
63
+ #
64
+ ---
65
+ name: optionError1
66
+ desc: invalid command-line option
67
+ method: parseOptions
68
+ args: [ -hvi ]
69
+ inspect: '*'
70
+ exception*:
71
+ ruby: CommandOptionError
72
+ java: CommandOptionException
73
+ message: "-i: invalid command option."
74
+ error_symbol*:
75
+ ruby: !ruby/sym :command_option_invalid
76
+ java: command.option.invalid
77
+ #
78
+ ---
79
+ name: optionError2
80
+ desc: no argument of '-f'
81
+ method: parseOptions
82
+ args: [ -f ]
83
+ inspect: '*'
84
+ exception*:
85
+ ruby: CommandOptionError
86
+ java: CommandOptionException
87
+ message: "-f: schema filename is required."
88
+ error_symbol*:
89
+ ruby: !ruby/sym :command_option_noschema
90
+ java: command.option.noschema
91
+ #
92
+ ##---
93
+ ##name: optionError3
94
+ ##desc: invalid property
95
+ ##method: parseOptions
96
+ ##args: [ --foo@var ]
97
+ ##inspect: '*'
98
+ ##exception*:
99
+ ## ruby: CommandOptionError
100
+ ## #java: CommandOptionException
101
+ ##message: "'--foo@var': invalid property."
102
+ ##error_symbol*:
103
+ ## ruby: !ruby/sym :command_property_invalid
104
+ ## #java: command.property.invalid
105
+ ---
106
+ name: optionError4
107
+ desc: action required
108
+ method: execute
109
+ args: [ document.yaml ]
110
+ inspect: '*'
111
+ expected: |
112
+ exception*:
113
+ ruby: CommandOptionError
114
+ java: CommandOptionException
115
+ message: "command-line option '-f' or '-m' required."
116
+ error_symbol*:
117
+ ruby: !ruby/sym :command_option_noschema
118
+ java: command.option.noaction
119
+
120
+ ---
121
+ name: version
122
+ desc: option '-v'
123
+ method: execute
124
+ args: [ -vt, document.yaml ]
125
+ expected: |
126
+ 0.0.0
127
+ #
128
+ ---
129
+ name: help
130
+ desc: option '-h'
131
+ method: execute
132
+ args: [ -hD, document.yaml ]
133
+ expected: |
134
+ Usage1: kwalify [-hvstl] -f schema.yaml document.yaml [document2.yaml ...]
135
+ Usage2: kwalify [-hvstl] -m schema.yaml [schema2.yaml ...]
136
+ -h, --help : help
137
+ -v : version
138
+ -s : silent
139
+ -f schema.yaml : schema definition file
140
+ -m : meta-validation mode
141
+ -t : expand tab character automatically
142
+ -l : show linenumber when errored (experimental)
143
+ #
144
+ ---
145
+ name: silent1
146
+ desc: option '-s' (valid)
147
+ method: execute
148
+ args: [ -sf, silent1.schema, silent1.document ]
149
+ expected: |
150
+ schema: |
151
+ type: seq
152
+ sequence:
153
+ - type: str
154
+ document: |
155
+ - foo
156
+ - bar
157
+ - baz
158
+ #
159
+ ---
160
+ name: silent2
161
+ desc: option '-s' (invalid)
162
+ method: execute
163
+ args: [ -sf, silent2.schema, silent2.document ]
164
+ expected: |
165
+ silent2.document#1: INVALID
166
+ - [/1] '123': not a string.
167
+ - [/2] 'true': not a string.
168
+ schema: |
169
+ type: seq
170
+ sequence:
171
+ - type: str
172
+ document: |
173
+ - foo
174
+ - bar
175
+ - baz
176
+ ---
177
+ - foo
178
+ - 123
179
+ - true
180
+ #
181
+ ---
182
+ name: untabify
183
+ desc: option '-t'
184
+ method: execute
185
+ args: [ -tf, untabify.schema, untabify.document ]
186
+ expected: |
187
+ untabify.document#0: valid.
188
+ schema: |
189
+ type: seq
190
+ sequence:
191
+ - type: map
192
+ mapping:
193
+ "key":
194
+ type: text
195
+ required: yes
196
+ "value":
197
+ type: any
198
+ required: yes
199
+ document: |
200
+ #
201
+ - key: foo
202
+ value: 123
203
+ - key: bar
204
+ value: [a, b, c]
205
+ #
206
+ ---
207
+ name: stream
208
+ desc: stream document
209
+ method: validation
210
+ schema: |
211
+ type: seq
212
+ sequence:
213
+ - type: str
214
+ valid: |
215
+ ---
216
+ - foo
217
+ - bar
218
+ - baz
219
+ ---
220
+ - aaa
221
+ - bbb
222
+ - ccc
223
+ valid-out: |
224
+ stream.valid#0: valid.
225
+ stream.valid#1: valid.
226
+ invalid: |
227
+ ---
228
+ - foo
229
+ - 123
230
+ - baz
231
+ ---
232
+ - aaa
233
+ - bbb
234
+ - true
235
+ invalid-out: |
236
+ stream.invalid#0: INVALID
237
+ - (line 3) [/1] '123': not a string.
238
+ stream.invalid#1: INVALID
239
+ - (line 8) [/2] 'true': not a string.
240
+ #
241
+ ---
242
+ name: meta1
243
+ desc: meta validation (valid)
244
+ method: execute
245
+ args: [ -m, meta1.schema ]
246
+ schema: |
247
+ type: seq
248
+ sequence:
249
+ - type: str
250
+ document: |
251
+ expected: |
252
+ meta1.schema: ok.
253
+ #
254
+ ---
255
+ name: meta2
256
+ desc: meta validation (invalid)
257
+ method: execute
258
+ args: [ -m, meta2.schema ]
259
+ schema: |
260
+ type: map
261
+ sequence:
262
+ - type: str
263
+ document: |
264
+ expected: |
265
+ meta2.schema: NG!
266
+ - [/] type 'map' requires 'mapping:'.
267
+ - [/] 'sequence:': not available with mapping.
268
+ #
269
+
270
+ ####
271
+ #### user's guide
272
+ ####
273
+ ---
274
+ name: validation01
275
+ desc: basic validation
276
+ method: validation
277
+ schema: |
278
+ type: seq
279
+ sequence:
280
+ - type: str
281
+ valid: |
282
+ - foo
283
+ - bar
284
+ - baz
285
+ valid-out: |
286
+ validation01.valid#0: valid.
287
+ invalid: |
288
+ - foo
289
+ - 123
290
+ - baz
291
+ invalid-out: |
292
+ validation01.invalid#0: INVALID
293
+ - (line 2) [/1] '123': not a string.
294
+ #
295
+ ---
296
+ name: validation02
297
+ desc: basic validation
298
+ method: validation
299
+ schema: |
300
+ type: map
301
+ mapping:
302
+ name:
303
+ type: str
304
+ required: yes
305
+ email:
306
+ type: str
307
+ pattern: /@/
308
+ age:
309
+ type: int
310
+ birth:
311
+ type: date
312
+ valid: |
313
+ name: foo
314
+ email: foo@mail.com
315
+ age: 20
316
+ birth: 1985-01-01
317
+ valid-out: |
318
+ validation02.valid#0: valid.
319
+ invalid: |
320
+ name: foo
321
+ email: foo(at)mail.com
322
+ age: twenty
323
+ birth: Jun 01, 1985
324
+ invalid-out: |
325
+ validation02.invalid#0: INVALID
326
+ - (line 2) [/email] 'foo(at)mail.com': not matched to pattern /@/.
327
+ - (line 3) [/age] 'twenty': not a integer.
328
+ - (line 4) [/birth] 'Jun 01, 1985': not a date.
329
+ #
330
+ ---
331
+ name: validation03
332
+ desc: sequence of mapping
333
+ method: validation
334
+ schema: |
335
+ type: seq
336
+ sequence:
337
+ - type: map
338
+ mapping:
339
+ name:
340
+ type: str
341
+ required: true
342
+ email:
343
+ type: str
344
+ valid: |
345
+ - name: foo
346
+ email: foo@mail.com
347
+ - name: bar
348
+ email: bar@mail.net
349
+ - name: baz
350
+ email: baz@mail.org
351
+ valid-out: |
352
+ validation03.valid#0: valid.
353
+ invalid: |
354
+ - name: foo
355
+ email: foo@mail.com
356
+ - naem: bar
357
+ email: bar@mail.net
358
+ - name: baz
359
+ mail: baz@mail.org
360
+ invalid-out: |
361
+ validation03.invalid#0: INVALID
362
+ - (line 3) [/1] key 'name:' is required.
363
+ - (line 3) [/1/naem] key 'naem:' is undefined.
364
+ - (line 6) [/2/mail] key 'mail:' is undefined.
365
+ #
366
+ ---
367
+ name: validation04
368
+ desc: mapping of sequence
369
+ method: validation
370
+ schema: |
371
+ type: map
372
+ mapping:
373
+ company:
374
+ type: str
375
+ required: yes
376
+ email:
377
+ type: str
378
+ employees:
379
+ type: seq
380
+ sequence:
381
+ - type: map
382
+ mapping:
383
+ code:
384
+ type: int
385
+ required: yes
386
+ name:
387
+ type: str
388
+ required: yes
389
+ email:
390
+ type: str
391
+ valid: |
392
+ company: Kuwata lab.
393
+ email: webmaster@kuwata-lab.com
394
+ employees:
395
+ - code: 101
396
+ name: foo
397
+ email: foo@kuwata-lab.com
398
+ - code: 102
399
+ name: bar
400
+ email: bar@kuwata-lab.com
401
+ valid-out: |
402
+ validation04.valid#0: valid.
403
+ invalid: |
404
+ company: Kuwata Lab.
405
+ email: webmaster@kuwata-lab.com
406
+ employees:
407
+ - code: A101
408
+ name: foo
409
+ email: foo@kuwata-lab.com
410
+ - code: 102
411
+ name: bar
412
+ mail: bar@kuwata-lab.com
413
+ invalid-out: |
414
+ validation04.invalid#0: INVALID
415
+ - (line 4) [/employees/0/code] 'A101': not a integer.
416
+ - (line 9) [/employees/1/mail] key 'mail:' is undefined.
417
+ #
418
+ ---
419
+ name: validation05
420
+ desc: rule and entry
421
+ method: validation
422
+ schema: |
423
+ type: seq # new rule
424
+ sequence:
425
+ -
426
+ type: map # new rule
427
+ mapping:
428
+ name:
429
+ type: str # new rule
430
+ required: yes
431
+ email:
432
+ type: str # new rule
433
+ required: yes
434
+ pattern: /@/
435
+ password:
436
+ type: str # new rule
437
+ length: { max: 16, min: 8 }
438
+ age:
439
+ type: int # new rule
440
+ range: { max: 30, min: 18 }
441
+ # or assert: 18 <= val && val <= 30
442
+ blood:
443
+ type: str # new rule
444
+ enum:
445
+ - A
446
+ - B
447
+ - O
448
+ - AB
449
+ birth:
450
+ type: date # new rule
451
+ memo:
452
+ type: any # new rule
453
+ valid: |
454
+ - name: foo
455
+ email: foo@mail.com
456
+ password: xxx123456
457
+ age: 20
458
+ blood: A
459
+ birth: 1985-01-01
460
+ - name: bar
461
+ email: bar@mail.net
462
+ age: 25
463
+ blood: AB
464
+ birth: 1980-01-01
465
+ valid-out: |
466
+ validation05.valid#0: valid.
467
+ invalid: |
468
+ - name: foo
469
+ email: foo(at)mail.com
470
+ password: xxx123
471
+ age: twenty
472
+ blood: a
473
+ birth: 1985-01-01
474
+ - given-name: bar
475
+ family-name: Bar
476
+ email: bar@mail.net
477
+ age: 15
478
+ blood: AB
479
+ birth: 1980/01/01
480
+ invalid-out*:
481
+ ruby: |
482
+ validation05.invalid#0: INVALID
483
+ - (line 2) [/0/email] 'foo(at)mail.com': not matched to pattern /@/.
484
+ - (line 3) [/0/password] 'xxx123': too short (length 6 < min 8).
485
+ - (line 4) [/0/age] 'twenty': not a integer.
486
+ - (line 5) [/0/blood] 'a': invalid blood value.
487
+ - (line 7) [/1/given-name] key 'given-name:' is undefined.
488
+ - (line 7) [/1] key 'name:' is required.
489
+ - (line 8) [/1/family-name] key 'family-name:' is undefined.
490
+ - (line 10) [/1/age] '15': too small (< min 18).
491
+ - (line 12) [/1/birth] '1980/01/01': not a date.
492
+ java: |
493
+ validation05.invalid#0: INVALID
494
+ - (line 2) [/0/email] 'foo(at)mail.com': not matched to pattern /@/.
495
+ - (line 3) [/0/password] 'xxx123': too short (length 6 < min 8).
496
+ - (line 4) [/0/age] 'twenty': not a integer.
497
+ - (line 5) [/0/blood] 'a': invalid blood value.
498
+ - (line 7) [/1] key 'name:' is required.
499
+ - (line 7) [/1/given-name] key 'given-name:' is undefined.
500
+ - (line 8) [/1/family-name] key 'family-name:' is undefined.
501
+ - (line 10) [/1/age] '15': too small (< min 18).
502
+ - (line 12) [/1/birth] '1980/01/01': not a date.
503
+ #
504
+ ---
505
+ name: validation06
506
+ desc: unique constraint
507
+ method: validation
508
+ schema: |
509
+ type: seq
510
+ sequence:
511
+ - type: map
512
+ required: yes
513
+ mapping:
514
+ name:
515
+ type: str
516
+ required: yes
517
+ unique: yes
518
+ email:
519
+ type: str
520
+ groups:
521
+ type: seq
522
+ sequence:
523
+ - type: str
524
+ unique: yes
525
+ valid: |
526
+ - name: foo
527
+ email: admin@mail.com
528
+ groups:
529
+ - users
530
+ - foo
531
+ - admin
532
+ - name: bar
533
+ email: admin@mail.com
534
+ groups:
535
+ - users
536
+ - admin
537
+ - name: baz
538
+ email: baz@mail.com
539
+ groups:
540
+ - users
541
+ valid-out: |
542
+ validation06.valid#0: valid.
543
+ invalid: |
544
+ - name: foo
545
+ email: admin@mail.com
546
+ groups:
547
+ - foo
548
+ - users
549
+ - admin
550
+ - foo
551
+ - name: bar
552
+ email: admin@mail.com
553
+ groups:
554
+ - admin
555
+ - users
556
+ - name: bar
557
+ email: baz@mail.com
558
+ groups:
559
+ - users
560
+ invalid-out: |
561
+ validation06.invalid#0: INVALID
562
+ - (line 7) [/0/groups/3] 'foo': is already used at '/0/groups/0'.
563
+ - (line 13) [/2/name] 'bar': is already used at '/1/name'.
564
+ #
565
+ ---
566
+ name: validation12
567
+ desc: json
568
+ method: validation
569
+ schema: |
570
+ { "type": "map",
571
+ "required": true,
572
+ "mapping": {
573
+ "name": {
574
+ "type": "str",
575
+ "required": true
576
+ },
577
+ "email": {
578
+ "type": "str"
579
+ },
580
+ "age": {
581
+ "type": "int"
582
+ },
583
+ "gender": {
584
+ "type": "str",
585
+ "enum": ["M", "F"]
586
+ },
587
+ "favorite": {
588
+ "type": "seq",
589
+ "sequence": [
590
+ { "type": "str" }
591
+ ]
592
+ }
593
+ }
594
+ }
595
+ valid: |
596
+ { "name": "Foo",
597
+ "email": "foo@mail.com",
598
+ "age": 20,
599
+ "gender": "F",
600
+ "favorite": [
601
+ "football",
602
+ "basketball",
603
+ "baseball"
604
+ ]
605
+ }
606
+ valid-out: |
607
+ validation12.valid#0: valid.
608
+ invalid: |
609
+ {
610
+ "mail": "foo@mail.com",
611
+ "age": twenty,
612
+ "gender": "X",
613
+ "favorite": [ 123, 456 ]
614
+ }
615
+ invalid-out: |
616
+ validation12.invalid#0: INVALID
617
+ - (line 1) [/] key 'name:' is required.
618
+ - (line 2) [/mail] key 'mail:' is undefined.
619
+ - (line 3) [/age] 'twenty': not a integer.
620
+ - (line 4) [/gender] 'X': invalid gender value.
621
+ - (line 5) [/favorite/0] '123': not a string.
622
+ - (line 5) [/favorite/1] '456': not a string.
623
+ #
624
+ ---
625
+ name: validation13
626
+ desc: anchor and alias
627
+ method: validation
628
+ schema: |
629
+ type: seq
630
+ sequence:
631
+ - &employee
632
+ type: map
633
+ mapping:
634
+ "given-name": &name
635
+ type: str
636
+ required: yes
637
+ "family-name": *name
638
+ "post":
639
+ enum:
640
+ - exective
641
+ - manager
642
+ - clerk
643
+ "supervisor": *employee
644
+ valid: |
645
+ - &foo
646
+ given-name: foo
647
+ family-name: Foo
648
+ post: exective
649
+ - &bar
650
+ given-name: bar
651
+ family-name: Bar
652
+ post: manager
653
+ supervisor: *foo
654
+ - given-name: baz
655
+ family-name: Baz
656
+ post: clerk
657
+ supervisor: *bar
658
+ - given-name: zak
659
+ family-name: Zak
660
+ post: clerk
661
+ supervisor: *bar
662
+ valid-out: |
663
+ validation13.valid#0: valid.
664
+ invalid: |
665
+ - &foo
666
+ #given-name: foo
667
+ family-name: Foo
668
+ post: exective
669
+ - &bar
670
+ given-name: bar
671
+ family-name: Bar
672
+ post: manager
673
+ supervisor: *foo
674
+ - given-name: baz
675
+ family-name: Baz
676
+ post: clerk
677
+ supervisor: *bar
678
+ - given-name: zak
679
+ family-name: Zak
680
+ post: clerk
681
+ supervisor: *bar
682
+ invalid-out: |
683
+ validation13.invalid#0: INVALID
684
+ - (line 1) [/0] key 'given-name:' is required.
685
+ #
686
+ ---
687
+ name: validation14
688
+ desc: anchor and alias
689
+ method: validation
690
+ schema: |
691
+ type: map
692
+ mapping:
693
+ =: # default rule
694
+ type: number
695
+ range: { max: 1, min: -1 }
696
+ valid: |
697
+ value1: 0
698
+ value2: 0.5
699
+ value3: -0.9
700
+ valid-out: |
701
+ validation14.valid#0: valid.
702
+ invalid: |
703
+ value1: 0
704
+ value2: 1.1
705
+ value3: -2.0
706
+ invalid-out: |
707
+ validation14.invalid#0: INVALID
708
+ - (line 2) [/value2] '1.1': too large (> max 1).
709
+ - (line 3) [/value3] '-2.0': too small (< min -1).
710
+ #
711
+ ---
712
+ name: validation15
713
+ desc: anchor and alias
714
+ method: validation
715
+ schema: |
716
+ type: map
717
+ mapping:
718
+ "group":
719
+ type: map
720
+ mapping:
721
+ "name": &name
722
+ type: str
723
+ required: yes
724
+ "email": &email
725
+ type: str
726
+ pattern: /@/
727
+ required: no
728
+ "user":
729
+ type: map
730
+ mapping:
731
+ "name":
732
+ <<: *name # merge
733
+ length: { max: 16 } # override
734
+ "email":
735
+ <<: *email # merge
736
+ required: yes # add
737
+ valid: |
738
+ group:
739
+ name: foo
740
+ email: foo@mail.com
741
+ user:
742
+ name: bar
743
+ email: bar@mail.com
744
+ valid-out: |
745
+ validation15.valid#0: valid.
746
+ invalid: |
747
+ group:
748
+ name: foo
749
+ email: foo@mail.com
750
+ user:
751
+ name: toooooo-looooong-name
752
+ invalid-out: |
753
+ validation15.invalid#0: INVALID
754
+ - (line 4) [/user] key 'email:' is required.
755
+ - (line 5) [/user/name] 'toooooo-looooong-name': too long (length 21 > max 16).
756
+ #