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,526 @@
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 ValidatorTest < 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
+ !name_table.key?(doc['name']) or raise "*** test name '#{doc['name']}' is duplicated."
28
+ name_table[doc['name']] = true
29
+ s = <<-END
30
+ def test_#{doc['name']}
31
+ @name = #{doc['name'].dump}
32
+ @schema = #{doc['schema'].dump}
33
+ @valid = #{doc['valid'].dump}
34
+ @invalid = #{doc['invalid'].dump}
35
+ @error = #{doc['error'].dump}
36
+ _test()
37
+ end
38
+ END
39
+ eval s
40
+ end
41
+
42
+ ## execute test
43
+ def _test()
44
+ return if $target && $target != @name
45
+ schema = YAML.load(@schema)
46
+ validator = Kwalify::Validator.new(schema)
47
+ _test_body(validator, @valid, '')
48
+ _test_body(validator, @invalid, @error)
49
+ end
50
+
51
+ def _test_body(validator, input, expected)
52
+ document = YAML.load(input)
53
+ error_list = validator.validate(document)
54
+ actual = ""
55
+ error_list.each do |error|
56
+ actual << "%-20s: [%s] %s\n" % [error.error_symbol.inspect, error.path, error.message]
57
+ end
58
+ if $flag_print
59
+ print actual
60
+ else
61
+ assert_equal_with_diff(expected, actual)
62
+ end
63
+ #return error_list
64
+ end
65
+
66
+ end
67
+
68
+
69
+ #if $0 == __FILE__
70
+ # suite = Test::Unit::TestSuite.new()
71
+ # suite << ValidatorTest.suite()
72
+ # Test::Unit::UI::Console::TestRunner.run(suite)
73
+ #end
74
+
75
+ __END__
76
+ ---
77
+ name: mapping1
78
+ desc: mapping test
79
+ #
80
+ schema: |
81
+ type: map
82
+ required: true
83
+ mapping:
84
+ name:
85
+ type: str
86
+ required: true
87
+ email:
88
+ type: str
89
+ pattern: /@/
90
+ required: yes
91
+ age:
92
+ type: int
93
+ blood:
94
+ type: str
95
+ enum:
96
+ - A
97
+ - B
98
+ - O
99
+ - AB
100
+ birth:
101
+ type: date
102
+ #
103
+ valid: |
104
+ name: foo
105
+ email: foo@mail.com
106
+ age: 20
107
+ blood: AB
108
+ birth: 1985-01-01
109
+ #
110
+ invalid: |
111
+ nam: foo
112
+ email: foo(at)mail.com
113
+ age: twenty
114
+ blood: ab
115
+ birth: Jul 01, 1985
116
+ #
117
+ error: |
118
+ :required_nokey : [/] key 'name:' is required.
119
+ :key_undefined : [/] key 'nam:' is undefined.
120
+ :enum_notexist : [/blood] 'ab': invalid blood value.
121
+ :type_unmatch : [/birth] 'Jul 01, 1985': not a date.
122
+ :type_unmatch : [/age] 'twenty': not a integer.
123
+ :pattern_unmatch : [/email] 'foo(at)mail.com': not matched to pattern /@/.
124
+ #
125
+ ---
126
+ name: sequence1
127
+ desc: sequence test
128
+ #
129
+ schema: |
130
+ type: seq
131
+ required: true
132
+ sequence:
133
+ - type: str
134
+ required: true
135
+ #
136
+ valid: |
137
+ - foo
138
+ - bar
139
+ - baz
140
+ #
141
+ invalid: |
142
+ - foo
143
+ - bar
144
+ -
145
+ - baz
146
+ - 100
147
+ #
148
+ error: |
149
+ :required_novalue : [/2] value required but none.
150
+ :type_unmatch : [/4] '100': not a string.
151
+ #
152
+ ---
153
+ name: nested1
154
+ desc: nest of seq and map
155
+ #
156
+ schema: |
157
+ type: map
158
+ required: true
159
+ mapping:
160
+ address-book:
161
+ type: seq
162
+ required: true
163
+ sequence:
164
+ - type: map
165
+ mapping:
166
+ name:
167
+ type: str
168
+ required: yes
169
+ email:
170
+ type: str
171
+ pattern: /@/
172
+ required: yes
173
+ age:
174
+ type: int
175
+ blood:
176
+ type: str
177
+ enum:
178
+ - A
179
+ - B
180
+ - O
181
+ - AB
182
+ birth:
183
+ type: date
184
+ #
185
+ valid: |
186
+ address-book:
187
+ - name: foo
188
+ email: foo@mail.com
189
+ age: 20
190
+ blood: AB
191
+ birth: 1985-01-01
192
+ - name: bar
193
+ email: foo@mail.com
194
+ #
195
+ invalid: |
196
+ address-book:
197
+ - name: foo
198
+ mail: foo@mail.com
199
+ age: twenty
200
+ blood: ab
201
+ birth: 1985/01/01
202
+ - name: bar
203
+ email: bar(at)mail.com
204
+ #
205
+ error: |
206
+ :required_nokey : [/address-book/0] key 'email:' is required.
207
+ :key_undefined : [/address-book/0] key 'mail:' is undefined.
208
+ :enum_notexist : [/address-book/0/blood] 'ab': invalid blood value.
209
+ :type_unmatch : [/address-book/0/birth] '1985/01/01': not a date.
210
+ :type_unmatch : [/address-book/0/age] 'twenty': not a integer.
211
+ :pattern_unmatch : [/address-book/1/email] 'bar(at)mail.com': not matched to pattern /@/.
212
+ #
213
+ ---
214
+ name: anchor1
215
+ desc: schema with anchor
216
+ #
217
+ schema: |
218
+ type: seq
219
+ required: true
220
+ sequence:
221
+ - type: map
222
+ required: true
223
+ mapping:
224
+ first-name: &name
225
+ type: str
226
+ required: yes
227
+ family-name: *name
228
+ #
229
+ valid: |
230
+ - first-name: foo
231
+ family-name: Foo
232
+ - first-name: bar
233
+ family-name: Bar
234
+ #
235
+ invalid: |
236
+ - first-name: foo
237
+ last-name: Foo
238
+ - first-name: bar
239
+ family-name: 100
240
+ #
241
+ error: |
242
+ :required_nokey : [/0] key 'family-name:' is required.
243
+ :key_undefined : [/0] key 'last-name:' is undefined.
244
+ :type_unmatch : [/1/family-name] '100': not a string.
245
+ #
246
+ ---
247
+ name: anchor2
248
+ desc: schema with anchor 2
249
+ #
250
+ schema: |
251
+ type: map
252
+ required: true
253
+ mapping:
254
+ title: &name
255
+ type: str
256
+ required: true
257
+ address-book:
258
+ type: seq
259
+ required: true
260
+ sequence:
261
+ - type: map
262
+ mapping:
263
+ name: *name
264
+ email:
265
+ type: str
266
+ required: yes
267
+ #
268
+ valid: |
269
+ title: my friends
270
+ address-book:
271
+ - name: foo
272
+ email: foo@mail.com
273
+ - name: bar
274
+ email: bar@mail.com
275
+ #
276
+ invalid: |
277
+ title: my friends
278
+ address-book:
279
+ - name: 100
280
+ email: foo@mail.com
281
+ - first-name: bar
282
+ email: bar@mail.com
283
+ #
284
+ error: |
285
+ :type_unmatch : [/address-book/0/name] '100': not a string.
286
+ :required_nokey : [/address-book/1] key 'name:' is required.
287
+ :key_undefined : [/address-book/1] key 'first-name:' is undefined.
288
+ #
289
+ ---
290
+ name: anchor3
291
+ desc: document with anchor
292
+ #
293
+ schema: |
294
+ type: seq
295
+ sequence:
296
+ - &employee
297
+ type: map
298
+ mapping:
299
+ name:
300
+ type: str
301
+ post:
302
+ type: str
303
+ enum:
304
+ - exective
305
+ - manager
306
+ - clerk
307
+ supervisor: *employee
308
+ #
309
+ valid: |
310
+ - &foo
311
+ name: foo
312
+ post: exective
313
+ - &bar
314
+ name: bar
315
+ post: manager
316
+ supervisor: *foo
317
+ - &baz
318
+ name: baz
319
+ post: clerk
320
+ supervisor: *bar
321
+ - &zak
322
+ name: zak
323
+ post: clerk
324
+ supervisor: *bar
325
+ #
326
+ invalid: |
327
+ - &foo
328
+ name: 100
329
+ post: exective
330
+ supervisor: *foo
331
+ - &bar
332
+ name: foo
333
+ post: worker
334
+ supervisor: *foo
335
+ #
336
+ error: |
337
+ :type_unmatch : [/0/name] '100': not a string.
338
+ :enum_notexist : [/1/post] 'worker': invalid post value.
339
+ #
340
+ ---
341
+ name: range1
342
+ desc: range test && bug#?????
343
+ #
344
+ schema: |
345
+ type: map
346
+ mapping:
347
+ "max-only":
348
+ type: seq
349
+ sequence:
350
+ - type: number
351
+ required: yes
352
+ range: { max: 100 }
353
+ "min-only":
354
+ type: seq
355
+ sequence:
356
+ - type: number
357
+ required: yes
358
+ range: { min: 10.0 }
359
+ "max-and-min":
360
+ type: seq
361
+ sequence:
362
+ - type: number
363
+ required: yes
364
+ range: { max: 100.0, min: 10.0 }
365
+ #
366
+ valid: |
367
+ max-only:
368
+ - 100
369
+ - 100.0
370
+ min-only:
371
+ - 10
372
+ - 10.0
373
+ max-and-min:
374
+ - 100
375
+ - 10
376
+ - 100.0
377
+ - 10.0
378
+ #
379
+ invalid: |
380
+ max-only:
381
+ - 101
382
+ - 100.1
383
+ min-only:
384
+ - 9
385
+ - 9.99
386
+ max-and-min:
387
+ - 101
388
+ - 100.1
389
+ - 9
390
+ - 9.99
391
+ #
392
+ error: |
393
+ :range_toosmall : [/min-only/0] '9': too small (< min 10.0).
394
+ :range_toosmall : [/min-only/1] '9.99': too small (< min 10.0).
395
+ :range_toolarge : [/max-and-min/0] '101': too large (> max 100.0).
396
+ :range_toolarge : [/max-and-min/1] '100.1': too large (> max 100.0).
397
+ :range_toosmall : [/max-and-min/2] '9': too small (< min 10.0).
398
+ :range_toosmall : [/max-and-min/3] '9.99': too small (< min 10.0).
399
+ :range_toolarge : [/max-only/0] '101': too large (> max 100).
400
+ :range_toolarge : [/max-only/1] '100.1': too large (> max 100).
401
+ #
402
+ ---
403
+ name: length1
404
+ desc: length test
405
+ #
406
+ schema: |
407
+ type: map
408
+ mapping:
409
+ "max-only":
410
+ type: seq
411
+ sequence:
412
+ - type: text
413
+ length: { max: 8 }
414
+ "min-only":
415
+ type: seq
416
+ sequence:
417
+ - type: text
418
+ length: { min: 4 }
419
+ "max-and-min":
420
+ type: seq
421
+ sequence:
422
+ - type: text
423
+ length: { max: 8, min: 4 }
424
+ #
425
+ valid: |
426
+ max-only:
427
+ - hogehoge
428
+ - 12345678
429
+ - a
430
+ -
431
+ min-only:
432
+ - hoge
433
+ - 1234
434
+ - hogehogehogehogehoge
435
+ max-and-min:
436
+ - hogehoge
437
+ - 12345678
438
+ - hoge
439
+ - 1234
440
+ #
441
+ invalid: |
442
+ max-only:
443
+ - hogehoge!
444
+ min-only:
445
+ - foo
446
+ -
447
+ max-and-min:
448
+ - foobarbaz
449
+ - foo
450
+ #
451
+ error: |
452
+ :length_tooshort : [/min-only/0] 'foo': too short (length 3 < min 4).
453
+ :length_toolong : [/max-and-min/0] 'foobarbaz': too long (length 9 > max 8).
454
+ :length_tooshort : [/max-and-min/1] 'foo': too short (length 3 < min 4).
455
+ :length_toolong : [/max-only/0] 'hogehoge!': too long (length 9 > max 8).
456
+ #
457
+ ---
458
+ name: assert1
459
+ desc: assert test
460
+ #
461
+ schema: |
462
+ type: seq
463
+ sequence:
464
+ - type: map
465
+ mapping:
466
+ "less-than":
467
+ type: number
468
+ assert: val < 8
469
+ "more-than":
470
+ type: number
471
+ assert: 3 < val
472
+ "between":
473
+ type: number
474
+ assert: 3 < val && val < 8
475
+ "except":
476
+ type: number
477
+ assert: val < 3 || 8 < val
478
+ #
479
+ valid: |
480
+ - less-than: 5
481
+ - more-than: 5
482
+ - between: 5
483
+ - except: 0
484
+ #
485
+ invalid: |
486
+ - less-than: 8
487
+ - more-than: 3
488
+ - between: 2.9
489
+ - except: 3.1
490
+ #
491
+ error: |
492
+ :assert_failed : [/0/less-than] '8': assertion expression failed (val < 8).
493
+ :assert_failed : [/1/more-than] '3': assertion expression failed (3 < val).
494
+ :assert_failed : [/2/between] '2.9': assertion expression failed (3 < val && val < 8).
495
+ :assert_failed : [/3/except] '3.1': assertion expression failed (val < 3 || 8 < val).
496
+ #
497
+ ---
498
+ name: deftype1
499
+ desc: default type test
500
+ #
501
+ schema: |
502
+ type: seq
503
+ sequence:
504
+ - type: map
505
+ mapping:
506
+ "name":
507
+ "email":
508
+ #
509
+ valid: |
510
+ - name: foo
511
+ email: foo@mail.com
512
+ - name: bar
513
+ - email: baz@mail.com
514
+ #
515
+ invalid: |
516
+ - name: 123
517
+ email: true
518
+ - name: 3.14
519
+ - email: 2004-01-01
520
+ #
521
+ error: |
522
+ :type_unmatch : [/0/name] '123': not a string.
523
+ :type_unmatch : [/0/email] 'true': not a string.
524
+ :type_unmatch : [/1/name] '3.14': not a string.
525
+ :type_unmatch : [/2/email] '2004-01-01': not a string.
526
+ #