kwalify 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,608 @@
1
+ ###
2
+ ### $Rev: 18 $
3
+ ### $Release: 0.2.0 $
4
+ ### copyright(c) 2005 kuwata-lab all rights reserved.
5
+ ###
6
+
7
+ if $0 == __FILE__
8
+ testdir = File.dirname(__FILE__)
9
+ libdir = File.dirname(testdir) + "/lib"
10
+ $LOAD_PATH << libdir << testdir
11
+ require 'test/unit'
12
+ require 'test/unit/ui/console/testrunner'
13
+ require 'kwalify'
14
+ require 'kwalify/util/assert-diff'
15
+ require 'yaml'
16
+ end
17
+
18
+
19
+ class MetaValidatorTest < Test::Unit::TestCase
20
+
21
+ ## define test methods
22
+ #str = DATA.read() # doesn't work when required by other script
23
+ str = File.read(__FILE__)
24
+ str.gsub!(/.*^__END__$/m, '')
25
+ name_table = {}
26
+ YAML.load_documents(str) do |doc|
27
+ doc.default = ''
28
+ !name_table.key?(doc['name']) or raise "*** test name '#{doc['name']}' is duplicated."
29
+ name_table[doc['name']] = true
30
+ s = <<-END
31
+ def test_meta_#{doc['name']}
32
+ @name = #{doc['name'].dump}
33
+ @desc = #{doc['desc'].dump}
34
+ @schema = #{doc['schema'].dump}
35
+ @meta_msg = #{doc['meta-msg'].dump}
36
+ # @rule_msg = #{doc['rule-msg'].dump}
37
+ _test(:meta)
38
+ end
39
+ def test_rule_#{doc['name']}
40
+ @name = #{doc['name'].dump}
41
+ @desc = #{doc['desc'].dump}
42
+ @schema = #{doc['schema'].dump}
43
+ # @meta_msg = #{doc['meta-msg'].dump}
44
+ @rule_msg = #{doc['rule-msg'].dump}
45
+ _test(:rule)
46
+ end
47
+ END
48
+ eval s
49
+ end
50
+
51
+ ## execute test
52
+ def _test(test_type)
53
+ return if $target && $target != @name
54
+ schema = YAML.load(@schema)
55
+ case test_type
56
+ when :meta
57
+ meta_validator = Kwalify.meta_validator()
58
+ errors = meta_validator.validate(schema)
59
+ expected = @meta_msg
60
+ when :rule
61
+ errors = []
62
+ begin
63
+ rule = Kwalify::Validator.new(schema)
64
+ rescue Kwalify::KwalifyError => error
65
+ errors << error
66
+ end
67
+ expected = @rule_msg
68
+ end
69
+ actual = ''
70
+ errors.each do |error|
71
+ raise error if error.is_a?(Kwalify::AssertionError)
72
+ actual << "%-20s: [%s] %s\n" % [error.error_symbol.inspect, error.path, error.message]
73
+ end
74
+ if $print
75
+ print actual
76
+ else
77
+ assert_equal_with_diff(expected, actual)
78
+ end
79
+ end
80
+
81
+ end
82
+
83
+ __END__
84
+ ---
85
+ name: schema_notmap
86
+ desc: schema_notmap
87
+ #
88
+ schema: |
89
+ - type: str
90
+ - type: int
91
+ #
92
+ meta-msg: |
93
+ :type_unmatch : [/] not a mapping.
94
+ #
95
+ rule-msg: |
96
+ :schema_notmap : [/] schema definition is not a mapping.
97
+ # :invalid_schema : [/] schema definition is invalid.
98
+ #
99
+ ---
100
+ name: type_unknown
101
+ desc: type_unknown
102
+ #
103
+ schema: |
104
+ type: map
105
+ mapping:
106
+ "name1":
107
+ type: str
108
+ "name2":
109
+ type: string
110
+ "age1":
111
+ type: int
112
+ "age2":
113
+ type: integer
114
+ "desc1":
115
+ type: text
116
+ "amount1":
117
+ type: float
118
+ "amount2":
119
+ type: number
120
+ "birth1":
121
+ type: date
122
+ "birth2":
123
+ type: time
124
+ "birth3":
125
+ type: timestamp
126
+ "data1":
127
+ type: scalar
128
+ "data2":
129
+ type: schalar
130
+ #
131
+ meta-msg: |
132
+ :enum_notexist : [/mapping/age2/type] 'integer': invalid type value.
133
+ :enum_notexist : [/mapping/name2/type] 'string': invalid type value.
134
+ :enum_notexist : [/mapping/data2/type] 'schalar': invalid type value.
135
+ #
136
+ rule-msg: |
137
+ :type_unknown : [/mapping/age2/type] 'integer': unknown type.
138
+ # :type_unknown : [/mapping/data2/type] 'schalar': unknown type.
139
+ # :type_unknown : [/mapping/data2] type 'schalar' is not found.
140
+ #
141
+ ---
142
+ name: required_notbool
143
+ desc: required_notbool
144
+ #
145
+ schema: |
146
+ type: map
147
+ mapping:
148
+ "name":
149
+ type: str
150
+ required: 1
151
+ #
152
+ meta-msg: |
153
+ :type_unmatch : [/mapping/name/required] '1': not a boolean.
154
+ #
155
+ rule-msg: |
156
+ :required_notbool : [/mapping/name/required] '1': not a boolean.
157
+ # :required_notbool : [/mapping/name] 'required:' is not boolean.
158
+ #
159
+ ---
160
+ name: pattern_syntaxerr
161
+ desc: pattern_syntaxerr
162
+ #
163
+ schema: |
164
+ type: str
165
+ pattern: /[A-/
166
+ #
167
+ meta-msg: |
168
+ :pattern_syntaxerr : [/pattern] '/[A-/': has regexp error.
169
+ #
170
+ rule-msg: |
171
+ :pattern_syntaxerr : [/pattern] '/[A-/': has regexp error.
172
+ # :pattern_syntaxerr : [/] 'pattern:' has regexp error (= /[A-/).
173
+ #
174
+ ---
175
+ name: enum_notseq
176
+ desc: enum_notseq
177
+ #
178
+ schema: |
179
+ type: str
180
+ enum: A, B, C
181
+ #
182
+ meta-msg: |
183
+ :type_unmatch : [/enum] 'A, B, C': not a sequence.
184
+ #
185
+ rule-msg: |
186
+ :enum_notseq : [/enum] 'A, B, C': not a sequence.
187
+ # :enum_notseq : [/] 'enum:' is not a sequence.
188
+ #
189
+ ---
190
+ name: enum_notscalar
191
+ desc: enum_notscalar
192
+ #
193
+ schema: |
194
+ type: seq
195
+ enum:
196
+ - A
197
+ - B
198
+ sequence:
199
+ - type: str
200
+ #
201
+ meta-msg: |
202
+ :enum_notscalar : [/] 'enum:': not available with seq or map.
203
+ #
204
+ rule-msg: |
205
+ :enum_notscalar : [/] 'enum:': not available with seq or map.
206
+ #
207
+ ---
208
+ name: enum_duplicate
209
+ desc: enum_duplicate
210
+ #
211
+ schema: |
212
+ enum:
213
+ - A
214
+ - B
215
+ - A
216
+ #
217
+ meta-msg: |
218
+ :enum_duplicate : [/enum] 'A': duplicated enum value.
219
+ #
220
+ rule-msg: |
221
+ :enum_duplicate : [/enum] 'A': duplicated enum value.
222
+ #
223
+ ---
224
+ name: enum_type_unmatch
225
+ desc: enum_type_unmatch
226
+ #
227
+ schema: |
228
+ enum:
229
+ - 100
230
+ - 200
231
+ #
232
+ meta-msg: |
233
+ :enum_type_unmatch : [/enum] '100': string type expected.
234
+ :enum_type_unmatch : [/enum] '200': string type expected.
235
+ #
236
+ rule-msg: |
237
+ :enum_type_unmatch : [/enum] '100': string type expected.
238
+ #
239
+ ---
240
+ name: assert_notstr
241
+ desc: assert_notstr
242
+ #
243
+ schema: |
244
+ type: number
245
+ assert: 100
246
+ #
247
+ meta-msg: |
248
+ :type_unmatch : [/assert] '100': not a string.
249
+ #
250
+ rule-msg: |
251
+ :assert_notstr : [/assert] '100': not a string.
252
+ # :assert_notstr : [/] 'assert:' is not a string.
253
+ #
254
+ ---
255
+ name: assert_noval
256
+ desc: assert_noval
257
+ #
258
+ schema: |
259
+ type: int
260
+ assert: value > 100
261
+ #
262
+ meta-msg: |
263
+ :pattern_unmatch : [/assert] 'value > 100': not matched to pattern /\bval\b/.
264
+ #
265
+ rule-msg: |
266
+ :assert_noval : [/assert] 'value > 100': 'val' is not used.
267
+ ---
268
+ name: assert_syntaxerr
269
+ desc: assert_syntaxerr
270
+ #
271
+ schema: |
272
+ type: int
273
+ assert: 0 < val &&
274
+ #
275
+ meta-msg: |
276
+ :assert_syntaxerr : [/assert] '0 < val &&': expression syntax error.
277
+ #
278
+ rule-msg: |
279
+ :assert_syntaxerr : [/assert] '0 < val &&': expression syntax error.
280
+ #
281
+ ---
282
+ name: range_notmap
283
+ desc: range_notmap
284
+ #
285
+ schema: |
286
+ type: int
287
+ range: 0 < val && val < 100
288
+ #
289
+ meta-msg: |
290
+ :type_unmatch : [/range] '0 < val && val < 100': not a mapping.
291
+ #
292
+ rule-msg: |
293
+ :range_notmap : [/range] '0 < val && val < 100': not a mapping.
294
+ #
295
+ ---
296
+ name: range_notscalar
297
+ desc: range_notscalar
298
+ #
299
+ schema: |
300
+ type: seq
301
+ sequence:
302
+ - type: str
303
+ range: { max: 10, min: 10 }
304
+ #
305
+ meta-msg: |
306
+ :range_notscalar : [/] 'range:': is available only with scalar type.
307
+ #
308
+ rule-msg: |
309
+ :range_notscalar : [/] 'range:': is available only with scalar type.
310
+ #
311
+ ---
312
+ name: range_type_unmatch
313
+ desc: range_type_unmatch
314
+ #
315
+ schema: |
316
+ type: int
317
+ range: { max: 10, min: 1.0 }
318
+ #
319
+ meta-msg: |
320
+ :range_type_unmatch : [/range/min] '1.0': not a integer.
321
+ #
322
+ rule-msg: |
323
+ :range_type_unmatch : [/range/min] '1.0': not a integer.
324
+ ---
325
+ name: range_undefined
326
+ desc: range_undefined
327
+ #
328
+ schema: |
329
+ type: int
330
+ range: { max: 10, mim: 1 }
331
+ #
332
+ meta-msg: |
333
+ :key_undefined : [/range] key 'mim:' is undefined.
334
+ # :key_undefined : [/range] 'mim:': undefined key.
335
+ #
336
+ rule-msg: |
337
+ :range_undefined : [/range] 'mim:': undefined key.
338
+ # :range_undefined : [/range] key 'mim:' undefined key.
339
+ #
340
+ ---
341
+ name: length_notmap
342
+ desc: length_notmap
343
+ #
344
+ schema: |
345
+ type: text
346
+ length: [ max:10, min:4 ]
347
+ #
348
+ meta-msg: |
349
+ :type_unmatch : [/length] not a mapping.
350
+ #
351
+ rule-msg: |
352
+ :length_notmap : [/length] not a mapping.
353
+ #
354
+ ---
355
+ name: length_nottext
356
+ desc: length_nottext
357
+ #
358
+ schema: |
359
+ type: number
360
+ length: { max: 10, min: 0 }
361
+ #
362
+ meta-msg: |
363
+ :length_nottext : [/] 'length:': is available only with string or text.
364
+ #
365
+ rule-msg: |
366
+ :length_nottext : [/] 'length:': is available only with string or text.
367
+ #
368
+ ---
369
+ name: length_notint
370
+ desc: length_notint
371
+ #
372
+ schema: |
373
+ type: text
374
+ length: { max: 10.1 }
375
+ #
376
+ meta-msg: |
377
+ :type_unmatch : [/length/max] '10.1': not a integer.
378
+ #
379
+ rule-msg: |
380
+ :length_notint : [/length/max] '10.1': not an integer.
381
+ #
382
+ ---
383
+ name: length_undefined
384
+ desc: length_undefined
385
+ #
386
+ schema: |
387
+ type: text
388
+ length: { maximum: 10 }
389
+ #
390
+ meta-msg: |
391
+ :key_undefined : [/length] key 'maximum:' is undefined.
392
+ # :key_undefined : [/length] 'maximum:': undefined key.
393
+ #
394
+ rule-msg: |
395
+ :length_undefined : [/length] 'maximum:': undefined key.
396
+ # :length_undefined : [/length] key 'maximum:' is undefined.
397
+ #
398
+ ---
399
+ name: sequence_notseq
400
+ desc: sequence_notseq
401
+ #
402
+ schema: |
403
+ type: seq
404
+ sequence: |
405
+ - type: str
406
+ #
407
+ meta-msg: |
408
+ :type_unmatch : [/sequence] '- type: str\n': not a sequence.
409
+ #
410
+ rule-msg: |
411
+ :sequence_notseq : [/sequence] '- type: str\n': not a sequence.
412
+ #
413
+ ---
414
+ name: sequence_noelem
415
+ desc: sequence_noelem
416
+ #
417
+ schema: |
418
+ type: seq
419
+ sequence:
420
+ #
421
+ meta-msg: |
422
+ :sequence_noelem : [/sequence] required one element.
423
+ # :type_unmatch : [/sequence] not a sequence.
424
+ #
425
+ rule-msg: |
426
+ :sequence_noelem : [/sequence] required one element.
427
+ #
428
+ ---
429
+ name: sequence_toomany
430
+ desc: sequence_toomany
431
+ #
432
+ schema: |
433
+ type: seq
434
+ sequence:
435
+ - type: text
436
+ - type: text
437
+ #
438
+ meta-msg: |
439
+ :sequence_toomany : [/sequence] required just one element.
440
+ #
441
+ rule-msg: |
442
+ :sequence_toomany : [/sequence] required just one element.
443
+ #
444
+ ---
445
+ name: mapping_notmap
446
+ desc: mapping_notmap
447
+ #
448
+ schema: |
449
+ type: map
450
+ mapping: |
451
+ "name":
452
+ type: str
453
+ #
454
+ meta-msg: |
455
+ :type_unmatch : [/mapping] '"name":\n type: str\n': not a mapping.
456
+ #
457
+ rule-msg: |
458
+ :mapping_notmap : [/mapping] '"name":\n type: str\n': not a mapping.
459
+ #
460
+ ---
461
+ name: mapping_noelem
462
+ desc: mapping_noelem
463
+ #
464
+ schema: |
465
+ type: map
466
+ mapping:
467
+ #
468
+ meta-msg: |
469
+ :mapping_noelem : [/mapping] required at least one element.
470
+ #
471
+ rule-msg: |
472
+ :mapping_noelem : [/mapping] required at least one element.
473
+ #
474
+ ---
475
+ name: key_unknown
476
+ desc: key_unknown
477
+ #
478
+ schema: |
479
+ type: str
480
+ values:
481
+ - one
482
+ - two
483
+ #
484
+ meta-msg: |
485
+ :key_undefined : [/] key 'values:' is undefined.
486
+ # :key_undefined : [/] 'values:': undefined key.
487
+ #
488
+ rule-msg: |
489
+ :key_unknown : [/] 'values:': unknown key.
490
+ # :key_unknown : [/] key 'values:' is unknown.
491
+ #
492
+ ---
493
+ name: seq_nosequence
494
+ desc: seq_nosequence
495
+ #
496
+ schema: |
497
+ type: seq
498
+ #
499
+ meta-msg: |
500
+ :seq_nosequence : [/] type 'seq' requires 'sequence:'.
501
+ #
502
+ rule-msg: |
503
+ :seq_nosequence : [/] type 'seq' requires 'sequence:'.
504
+ #
505
+ ---
506
+ name: seq_conflict
507
+ desc: seq_conflict
508
+ #
509
+ schema: |
510
+ type: seq
511
+ mapping: { name: {type: str} }
512
+ sequence:
513
+ - type: str
514
+ # pattern: /abc/
515
+ # range: { max: 10 }
516
+ # length: { max: 10 }
517
+ # enum: [ A, B, C ]
518
+ #
519
+ meta-msg: |
520
+ :seq_conflict : [/] 'mapping:': not available with sequence.
521
+ # :seq_conflict : [/] 'enum:': not available with sequence.
522
+ # :seq_conflict : [/] 'pattern:': not available with sequence.
523
+ # :seq_conflict : [/] 'range:': not available with sequence.
524
+ # :seq_conflict : [/] 'length:': not available with sequence.
525
+ #
526
+ rule-msg: |
527
+ :seq_conflict : [/] 'mapping:': not available with sequence.
528
+ # :enum_notscalar : [/] 'enum:': not available with seq or map.
529
+ # :seq_conflict : [/] 'enum:': not available with sequence.
530
+ # :seq_conflict : [/] 'pattern:': not available with sequence.
531
+ # :seq_conflict : [/] 'range:': not available with sequence.
532
+ # :seq_conflict : [/] 'length:': not available with sequence.
533
+ #
534
+ ---
535
+ name: map_nomapping
536
+ desc: map_nomapping
537
+ #
538
+ schema: |
539
+ type: map
540
+ #
541
+ meta-msg: |
542
+ :map_nomapping : [/] type 'map' requires 'mapping:'.
543
+ #
544
+ rule-msg: |
545
+ :map_nomapping : [/] type 'map' requires 'mapping:'.
546
+ #
547
+ ---
548
+ name: map_conflict
549
+ desc: map_conflict
550
+ #
551
+ schema: |
552
+ type: map
553
+ mapping:
554
+ "name":
555
+ type: str
556
+ sequence:
557
+ - type: str
558
+ #
559
+ meta-msg: |
560
+ :map_conflict : [/] 'sequence:': not available with mapping.
561
+ #
562
+ rule-msg: |
563
+ :map_conflict : [/] 'sequence:': not available with mapping.
564
+ #
565
+ ---
566
+ name: scalar_confict
567
+ desc: scalar_confict
568
+ #
569
+ schema: |
570
+ type: int
571
+ sequence:
572
+ - type: str
573
+ mapping:
574
+ "name":
575
+ type: str
576
+ #
577
+ meta-msg: |
578
+ :scalar_conflict : [/] 'sequence:': not available with scalar type.
579
+ :scalar_conflict : [/] 'mapping:': not available with scalar type.
580
+ #
581
+ rule-msg: |
582
+ :scalar_conflict : [/] 'sequence:': not available with scalar type.
583
+ # :scalar_conflict : [/] 'mapping:': not available with scalar type.
584
+ #
585
+ ---
586
+ name: enum_conflict
587
+ desc: enum_conflict
588
+ #
589
+ schema: |
590
+ type: str
591
+ required: yes
592
+ enum:
593
+ - aa
594
+ - bb
595
+ range: { max: aa, min: xx }
596
+ length: { max: 3 }
597
+ pattern: /0/
598
+ #
599
+ meta-msg: |
600
+ :enum_conflict : [/] 'range:': not available with 'enum:'.
601
+ :enum_conflict : [/] 'length:': not available with 'enum:'.
602
+ :enum_conflict : [/] 'pattern:': not available with 'enum:'.
603
+ #
604
+ rule-msg: |
605
+ :enum_conflict : [/] 'range:': not available with 'enum:'.
606
+ # :enum_conflict : [/] 'length:': not available with 'enum:'.
607
+ # :enum_conflict : [/] 'pattern:': not available with 'enum:'.
608
+ #