oktest 1.0.0 → 1.1.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 +4 -4
- data/README.md +287 -51
- data/Rakefile.rb +1 -1
- data/lib/oktest.rb +393 -19
- data/oktest.gemspec +2 -2
- data/test/assertion_test.rb +70 -5
- data/test/filter_test.rb +2 -2
- data/test/fixture_test.rb +1 -1
- data/test/generator_test.rb +1 -1
- data/test/helper_test.rb +1 -1
- data/test/initialize.rb +8 -1
- data/test/mainapp_test.rb +42 -5
- data/test/matcher_test.rb +424 -0
- data/test/misc_test.rb +1 -1
- data/test/node_test.rb +34 -1
- data/test/reporter_test.rb +34 -6
- data/test/runner_test.rb +90 -9
- data/test/util_test.rb +1 -1
- data/test/visitor_test.rb +1 -1
- metadata +3 -2
data/oktest.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.1.1 $
|
5
5
|
### $License: MIT License $
|
6
6
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
7
7
|
###
|
@@ -13,7 +13,7 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.name = "oktest"
|
14
14
|
s.author = "kwatch"
|
15
15
|
s.email = "kwatch@gmail.com"
|
16
|
-
s.version = "$Release: 1.
|
16
|
+
s.version = "$Release: 1.1.1 $".split()[1]
|
17
17
|
s.license = "MIT"
|
18
18
|
s.platform = Gem::Platform::RUBY
|
19
19
|
s.homepage = "https://github.com/kwatch/oktest/tree/ruby"
|
data/test/assertion_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.1.1 $
|
5
5
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -170,6 +170,15 @@ END
|
|
170
170
|
" $<expected>: \"str\""
|
171
171
|
FAIL!(errmsg) { ok {String}.NOT === 'str' }
|
172
172
|
end
|
173
|
+
it "[!mjh4d] raises error when combination of 'not_ok()' and matcher object." do
|
174
|
+
errmsg = "negative `===` is not available with matcher object."
|
175
|
+
assert_exc(Oktest::OktestError, errmsg) do
|
176
|
+
not_ok {Oktest::JsonMatcher.new({})} === {}
|
177
|
+
end
|
178
|
+
assert_exc(Oktest::OktestError, errmsg) do
|
179
|
+
ok {Oktest::JsonMatcher.new({})}.NOT === {}
|
180
|
+
end
|
181
|
+
end
|
173
182
|
end
|
174
183
|
|
175
184
|
describe '>' do
|
@@ -423,11 +432,11 @@ describe '#method_missing()' do
|
|
423
432
|
assert NoMethodError < NameError, "NoMethodError extends NameError"
|
424
433
|
ERROR!(NoMethodError, /foobar/) { ok {pr}.raise?(NameError) }
|
425
434
|
end
|
426
|
-
it "[!hwg0z] compares error class with '.is_a?' if '
|
435
|
+
it "[!hwg0z] compares error class with '.is_a?' if '_subclass: true' specified." do
|
427
436
|
pr = proc { "SOS".foobar }
|
428
437
|
PASS! { ok {pr}.raise?(NoMethodError, nil) }
|
429
438
|
assert NoMethodError < NameError, "NoMethodError extends NameError"
|
430
|
-
PASS! { ok {pr}.raise?(NameError, nil,
|
439
|
+
PASS! { ok {pr}.raise?(NameError, nil, _subclass: true) }
|
431
440
|
end
|
432
441
|
it "[!4n3ed] reraises if exception is not matched to specified error class." do
|
433
442
|
pr = proc { "SOS".sos }
|
@@ -483,11 +492,11 @@ describe '#method_missing()' do
|
|
483
492
|
assert NoMethodError < NameError, "NoMethodError extends NameError"
|
484
493
|
ERROR!(NoMethodError) { ok {pr}.NOT.raise?(NameError) }
|
485
494
|
end
|
486
|
-
it "[!34nd8] compares error class with '.is_a?' if '
|
495
|
+
it "[!34nd8] compares error class with '.is_a?' if '_subclass: true' specified." do
|
487
496
|
pr = proc { "SOS".foobar }
|
488
497
|
FAIL!(/foobar/) { ok {pr}.NOT.raise?(NoMethodError, nil) }
|
489
498
|
assert NoMethodError < NameError, "NoMethodError extends NameError"
|
490
|
-
FAIL!(/foobar/) { ok {pr}.NOT.raise?(NameError, nil,
|
499
|
+
FAIL!(/foobar/) { ok {pr}.NOT.raise?(NameError, nil, _subclass: true) }
|
491
500
|
end
|
492
501
|
it "[!shxne] reraises exception if different from specified error class." do
|
493
502
|
pr = proc { 1/0 }
|
@@ -814,4 +823,60 @@ describe '#method_missing()' do
|
|
814
823
|
end
|
815
824
|
end
|
816
825
|
|
826
|
+
describe '#JSON()' do
|
827
|
+
it "[!n0k03] creates JsonMatcher object." do
|
828
|
+
o = JSON({})
|
829
|
+
assert_eq o.class, Oktest::JsonMatcher
|
830
|
+
end
|
831
|
+
end
|
832
|
+
|
833
|
+
describe '#Enum()' do
|
834
|
+
it "[!fbfr0] creates Enum object which is a subclass of Set." do
|
835
|
+
o = Enum("a", "b", "c")
|
836
|
+
assert_eq o.class, Oktest::JsonMatcher::Enum
|
837
|
+
assert o.class < Set
|
838
|
+
assert_eq (o === "a"), true
|
839
|
+
assert_eq (o === "b"), true
|
840
|
+
assert_eq (o === "c"), true
|
841
|
+
assert_eq (o === "d"), false
|
842
|
+
end
|
843
|
+
end
|
844
|
+
|
845
|
+
describe '#Bool()' do
|
846
|
+
it "[!vub5j] creates a set of true and false." do
|
847
|
+
assert_eq Bool().class, Oktest::JsonMatcher::Enum
|
848
|
+
assert Bool() === true
|
849
|
+
assert Bool() === false
|
850
|
+
assert_eq (Bool() === 1), false
|
851
|
+
assert_eq (Bool() === 0), false
|
852
|
+
end
|
853
|
+
end
|
854
|
+
|
855
|
+
describe '#OR()' do
|
856
|
+
it "[!9e8im] creates `OR` object." do
|
857
|
+
o = OR(1, 2, 3)
|
858
|
+
assert_eq o.class, Oktest::JsonMatcher::OR
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
describe '#AND()' do
|
863
|
+
it "[!38jln] creates `AND` object." do
|
864
|
+
o = AND(4, 5, 6)
|
865
|
+
assert_eq o.class, Oktest::JsonMatcher::AND
|
866
|
+
end
|
867
|
+
end
|
868
|
+
|
869
|
+
describe '#Length()' do
|
870
|
+
it "[!qqas3] creates Length object." do
|
871
|
+
o = Length(3)
|
872
|
+
assert_eq o.class, Oktest::JsonMatcher::Length
|
873
|
+
end
|
874
|
+
end
|
875
|
+
|
876
|
+
describe '#Any()' do
|
877
|
+
it "[!dlo1o] creates an 'Any' object." do
|
878
|
+
assert_eq Any().class, Oktest::JsonMatcher::Any
|
879
|
+
end
|
880
|
+
end
|
881
|
+
|
817
882
|
end
|
data/test/filter_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.1.1 $
|
5
5
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -188,7 +188,7 @@ class Filter_TC < TC
|
|
188
188
|
Oktest::Runner.new(reporter).start()
|
189
189
|
end
|
190
190
|
assert_eq serr, ""
|
191
|
-
return sout.sub(/^## total:.*\n/, '')
|
191
|
+
return sout.sub(/^## total:.*\n/, '').sub(/^## test\/filter_test\.rb\n/, '')
|
192
192
|
end
|
193
193
|
|
194
194
|
def uncolor(s)
|
data/test/fixture_test.rb
CHANGED
data/test/generator_test.rb
CHANGED
data/test/helper_test.rb
CHANGED
data/test/initialize.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
|
3
3
|
###
|
4
|
-
### $Release: 1.
|
4
|
+
### $Release: 1.1.1 $
|
5
5
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
6
|
### $License: MIT License $
|
7
7
|
###
|
@@ -12,3 +12,10 @@ end
|
|
12
12
|
|
13
13
|
require_relative './tc'
|
14
14
|
require 'oktest'
|
15
|
+
|
16
|
+
|
17
|
+
# for Ruby 2.4 or older
|
18
|
+
require 'set'
|
19
|
+
unless Set.instance_methods(false).include?(:===)
|
20
|
+
class Set; alias === include?; end
|
21
|
+
end
|
data/test/mainapp_test.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
###
|
2
|
-
### $Release: 1.
|
2
|
+
### $Release: 1.1.1 $
|
3
3
|
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
4
4
|
### $License: MIT License $
|
5
5
|
###
|
@@ -201,7 +201,7 @@ END
|
|
201
201
|
Usage: #{File.basename($0)} [<options>] [<file-or-directory>...]
|
202
202
|
-h, --help : show help
|
203
203
|
--version : print version
|
204
|
-
-s <STYLE>
|
204
|
+
-s <REPORT-STYLE> : verbose/simple/compact/plain/quiet, or v/s/c/p/q
|
205
205
|
-F <PATTERN> : filter topic or spec with pattern (see below)
|
206
206
|
--color[={on|off}] : enable/disable output coloring forcedly
|
207
207
|
-C, --create : print test code skeleton
|
@@ -241,7 +241,7 @@ END
|
|
241
241
|
end
|
242
242
|
|
243
243
|
it "[!qqizl] '--version' option prints version number." do
|
244
|
-
expected = '$Release: 1.
|
244
|
+
expected = '$Release: 1.1.1 $'.split()[1] + "\n"
|
245
245
|
#
|
246
246
|
ret, sout, serr = run("--version")
|
247
247
|
assert_eq ret, 0
|
@@ -251,6 +251,7 @@ END
|
|
251
251
|
|
252
252
|
it "[!0qd92] '-s verbose' or '-sv' option prints test results in verbose mode." do
|
253
253
|
expected = <<END
|
254
|
+
## _tmp_test.rb
|
254
255
|
* <b>Parent</b>
|
255
256
|
* <b>Child1</b>
|
256
257
|
- [<B>pass</B>] 1+1 should be 2
|
@@ -272,9 +273,12 @@ END
|
|
272
273
|
assert_eq serr, ""
|
273
274
|
end
|
274
275
|
|
275
|
-
it "[!
|
276
|
+
it "[!zfdr5] '-s simple' or '-ss' option prints test results in simple mode." do
|
276
277
|
expected = <<END
|
277
|
-
|
278
|
+
## _tmp_test.rb
|
279
|
+
* <b>Parent</b>: <B>.</B><B>.</B>
|
280
|
+
* <b>Child1</b>: <B>.</B><B>.</B>
|
281
|
+
* <b>Child2</b>: <R>f</R><R>E</R>
|
278
282
|
----------------------------------------------------------------------
|
279
283
|
END
|
280
284
|
#
|
@@ -289,6 +293,23 @@ END
|
|
289
293
|
assert_eq serr, ""
|
290
294
|
end
|
291
295
|
|
296
|
+
it "[!ef5v7] '-s compact' or '-sc' option prints test results in compact mode." do
|
297
|
+
expected = <<END
|
298
|
+
#{@testfile}: <B>.</B><B>.</B><R>f</R><R>E</R><Y>s</Y><Y>t</Y><B>.</B><B>.</B>
|
299
|
+
----------------------------------------------------------------------
|
300
|
+
END
|
301
|
+
#
|
302
|
+
ret, sout, serr = run("-sc", @testfile)
|
303
|
+
assert_eq ret, 2
|
304
|
+
assert edit_actual(sout).start_with?(edit_expected(expected)), "invalid testcase output"
|
305
|
+
assert_eq serr, ""
|
306
|
+
#
|
307
|
+
ret, sout, serr = run("-s", "compact", @testfile)
|
308
|
+
assert_eq ret, 2
|
309
|
+
assert edit_actual(sout).start_with?(edit_expected(expected)), "invalid testcase output"
|
310
|
+
assert_eq serr, ""
|
311
|
+
end
|
312
|
+
|
292
313
|
it "[!244te] '-s plain' or '-sp' option prints test results in plain mode." do
|
293
314
|
expected = <<END
|
294
315
|
<B>.</B><B>.</B><R>f</R><R>E</R><Y>s</Y><Y>t</Y><B>.</B><B>.</B>
|
@@ -325,6 +346,7 @@ END
|
|
325
346
|
|
326
347
|
it "[!yz7g5] '-F topic=...' option filters topics." do
|
327
348
|
expected = <<END
|
349
|
+
## _tmp_test.rb
|
328
350
|
* <b>Parent</b>
|
329
351
|
* <b>Child1</b>
|
330
352
|
- [<B>pass</B>] 1+1 should be 2
|
@@ -340,6 +362,7 @@ END
|
|
340
362
|
|
341
363
|
it "[!ww2mp] '-F spec=...' option filters specs." do
|
342
364
|
expected = <<END
|
365
|
+
## _tmp_test.rb
|
343
366
|
* <b>Parent</b>
|
344
367
|
* <b>Child1</b>
|
345
368
|
- [<B>pass</B>] 1-1 should be 0
|
@@ -354,6 +377,7 @@ END
|
|
354
377
|
|
355
378
|
it "[!8uvib] '-F tag=...' option filters by tag name." do
|
356
379
|
expected = <<'END'
|
380
|
+
## _tmp_test.rb
|
357
381
|
* <b>Parent</b>
|
358
382
|
* <b>Child1</b>
|
359
383
|
- [<B>pass</B>] 1-1 should be 0
|
@@ -373,6 +397,7 @@ END
|
|
373
397
|
|
374
398
|
it "[!m0iwm] '-F sid=...' option filters by spec id." do
|
375
399
|
expected = <<'END'
|
400
|
+
## _tmp_test.rb
|
376
401
|
* <b>Parent</b>
|
377
402
|
- <b>When x is negative</b>
|
378
403
|
- [<B>pass</B>] [!6hs1j] x*x is positive.
|
@@ -387,6 +412,7 @@ END
|
|
387
412
|
|
388
413
|
it "[!noi8i] '-F' option supports negative filter." do
|
389
414
|
expected = <<'END'
|
415
|
+
## _tmp_test.rb
|
390
416
|
* <b>Parent</b>
|
391
417
|
* <b>Child1</b>
|
392
418
|
- [<B>pass</B>] 1+1 should be 2
|
@@ -408,6 +434,17 @@ END
|
|
408
434
|
end
|
409
435
|
end
|
410
436
|
|
437
|
+
it "[!j01y7] if filerting by '-F' matched nothing, then prints zero result." do
|
438
|
+
expected = <<'END'
|
439
|
+
## total:0 (pass:0, fail:0, error:0, skip:0, todo:0) in 0.000s
|
440
|
+
END
|
441
|
+
#
|
442
|
+
ret, sout, serr = run("-F", "tag=blablabla", @testfile)
|
443
|
+
assert_eq ret, 0
|
444
|
+
assert_eq edit_actual(sout), edit_expected(expected)
|
445
|
+
assert_eq serr, ""
|
446
|
+
end
|
447
|
+
|
411
448
|
it "[!6ro7j] '--color=on' option enables output coloring forcedly." do
|
412
449
|
[true, false].each do |bool|
|
413
450
|
[true, false].each do |tty|
|
@@ -0,0 +1,424 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
###
|
4
|
+
### $Release: 1.1.1 $
|
5
|
+
### $Copyright: copyright(c) 2011-2021 kuwata-lab.com all rights reserved $
|
6
|
+
### $License: MIT License $
|
7
|
+
###
|
8
|
+
|
9
|
+
require_relative './initialize'
|
10
|
+
require 'set'
|
11
|
+
|
12
|
+
|
13
|
+
class Matcher_TC < TC
|
14
|
+
|
15
|
+
describe '#===' do
|
16
|
+
it "[!spybn] raises NotImplementedError." do
|
17
|
+
errmsg = "Oktest::Matcher#===(): not implemented yet."
|
18
|
+
assert_exc(NotImplementedError, errmsg) do
|
19
|
+
Oktest::Matcher.new(nil) === nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#==' do
|
25
|
+
it "[!ymt1b] raises OktestError." do
|
26
|
+
errmsg = "JSON(): use `===` instead of `==`."
|
27
|
+
assert_exc(Oktest::OktestError, errmsg) do
|
28
|
+
Oktest::Matcher.new(nil) == nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#fail()' do
|
34
|
+
it "[!8qpsd] raises assertion error." do
|
35
|
+
errmsg = "<<errmsg>>"
|
36
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
37
|
+
Oktest::Matcher.new(nil).fail("<<errmsg>>")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
class JsonMatcher_TC < TC
|
46
|
+
|
47
|
+
def JSON(x)
|
48
|
+
return Oktest::JsonMatcher.new(x)
|
49
|
+
end
|
50
|
+
|
51
|
+
def OR(*args)
|
52
|
+
return Oktest::JsonMatcher::OR.new(*args)
|
53
|
+
end
|
54
|
+
|
55
|
+
def AND(*args)
|
56
|
+
return Oktest::JsonMatcher::AND.new(*args)
|
57
|
+
end
|
58
|
+
|
59
|
+
def ANY()
|
60
|
+
return Oktest::JsonMatcher::Any.new
|
61
|
+
end
|
62
|
+
|
63
|
+
describe '#===' do
|
64
|
+
it "[!4uf1o] raises assertion error when JSON not matched." do
|
65
|
+
assert_exc(Oktest::FAIL_EXCEPTION) do
|
66
|
+
JSON({"status": "ok"}) === {"status": "OK"}
|
67
|
+
end
|
68
|
+
end
|
69
|
+
it "[!0g0u4] returns true when JSON matched." do
|
70
|
+
result = JSON({"status": "ok"}) === {"status": "ok"}
|
71
|
+
assert_eq result, true
|
72
|
+
end
|
73
|
+
it "[!1ukbv] scalar value matches to integer, string, bool, and so son." do
|
74
|
+
actual = {"name": "Alice", "age": 20, "deleted": false}
|
75
|
+
result = JSON(actual) === {"name": "Alice", "age": 20, "deleted": false}
|
76
|
+
assert_eq result, true
|
77
|
+
#
|
78
|
+
errmsg = ("$<JSON>[\"name\"]: $<expected> === $<actual> : failed.\n"\
|
79
|
+
" $<actual>: \"Alice\"\n"\
|
80
|
+
" $<expected>: \"alice\"\n")
|
81
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
82
|
+
JSON(actual) === {"name": "alice", "age": 20, "deleted": false}
|
83
|
+
end
|
84
|
+
end
|
85
|
+
it "[!8o55d] class object matches to instance object." do
|
86
|
+
actual = {"name": "Alice", "age": 20, "deleted": false}
|
87
|
+
result = JSON(actual) === {"name": String, "age": Integer, "deleted": FalseClass}
|
88
|
+
assert_eq result, true
|
89
|
+
#
|
90
|
+
errmsg = ("$<JSON>[\"deleted\"]: $<expected> === $<actual> : failed.\n"\
|
91
|
+
" $<actual>: false\n"\
|
92
|
+
" $<expected>: TrueClass\n")
|
93
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
94
|
+
JSON(actual) === {"name": String, "age": Integer, "deleted": TrueClass}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
it "[!s625d] regexp object matches to string value." do
|
98
|
+
actual = {"email": "alice@example.com"}
|
99
|
+
result = JSON(actual) === {"email": /^\w[-.\w]+@example\.(com|net|org)$/}
|
100
|
+
assert_eq result, true
|
101
|
+
#
|
102
|
+
errmsg = ("$<JSON>[\"email\"]: $<expected> === $<actual> : failed.\n"\
|
103
|
+
" $<actual>: \"alice@example.com\"\n"\
|
104
|
+
" $<expected>: /^\\w[-.\\w]+@example\\.org$/\n")
|
105
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
106
|
+
JSON(actual) === {"email": /^\w[-.\w]+@example\.org$/}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
it "[!aqkk0] range object matches to scalar value." do
|
110
|
+
actual = {"int": 5, "float": 3.14, "str": "abc"}
|
111
|
+
result = JSON(actual) === {"int": 1..10, "float": 3.1..3.2, "str": "aaa".."zzz"}
|
112
|
+
assert_eq result, true
|
113
|
+
#
|
114
|
+
errmsg = ("$<JSON>[\"int\"]: $<expected> === $<actual> : failed.\n"\
|
115
|
+
" $<actual>: 5\n"\
|
116
|
+
" $<expected>: 1...5\n")
|
117
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
118
|
+
JSON(actual) === {"int": 1...5, "float": 3.1..3.2, "str": "aaa".."zzz"}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
it "[!4ymj2] fails when actual value is not matched to item class of range object." do
|
122
|
+
actual = {"val": 1.5}
|
123
|
+
errmsg = ("$<JSON>[\"val\"]: expected #{1.class.name} value, but got Float value.\n"\
|
124
|
+
" $<actual>: 1.5\n"\
|
125
|
+
" $<expected>: 1..10\n")
|
126
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
127
|
+
JSON(actual) === {"val": 1..10}
|
128
|
+
end
|
129
|
+
end
|
130
|
+
it "[!a7bfs] Set object matches to enum value." do
|
131
|
+
actual = {"gender": "female"}
|
132
|
+
result = JSON(actual) === {"gender": Set.new(["male", "female"])}
|
133
|
+
assert_eq result, true
|
134
|
+
#
|
135
|
+
errmsg = ("$<JSON>[\"gender\"]: $<expected> === $<actual> : failed.\n"\
|
136
|
+
" $<actual>: \"female\"\n"\
|
137
|
+
" $<expected>: #<Set: {\"M\", \"F\"}>\n")
|
138
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
139
|
+
JSON(actual) === {"gender": Set.new(["M", "F"])}
|
140
|
+
end
|
141
|
+
end
|
142
|
+
it "[!sh5cg] Enumerator object matches to repeat of rule." do
|
143
|
+
actual = {"tags": ["foo", "bar", "baz"]}
|
144
|
+
result = JSON(actual) === {"tags": [String].each}
|
145
|
+
assert_eq result, true
|
146
|
+
#
|
147
|
+
errmsg = ("$<JSON>[\"tags\"][0]: $<expected> === $<actual> : failed.\n"\
|
148
|
+
" $<actual>: \"foo\"\n"\
|
149
|
+
" $<expected>: Integer\n")
|
150
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
151
|
+
JSON(actual) === {"tags": [Integer].each}
|
152
|
+
end
|
153
|
+
end
|
154
|
+
it "[!ljrmc] fails when expected is an Enumerator object and actual is not an array." do
|
155
|
+
actual = {"tags": "foo"}
|
156
|
+
errmsg = ("$<JSON>[\"tags\"]: Array value expected but got String value.\n"\
|
157
|
+
" $<actual>: \"foo\"\n"\
|
158
|
+
" $<expected>: [String].each\n")
|
159
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
160
|
+
JSON(actual) === {"tags": [String].each}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
it "[!lh6d6] compares array items recursively." do
|
164
|
+
actual = {"items": [{"name": "Alice", "id": 101}, {"name": "Bob"}]}
|
165
|
+
result = JSON(actual) === {
|
166
|
+
"items": [{"name": String, "id?": 100..999}].each
|
167
|
+
}
|
168
|
+
assert_eq result, true
|
169
|
+
#
|
170
|
+
errmsg = ("$<JSON>[\"items\"][0][\"id\"]: $<expected> === $<actual> : failed.\n"\
|
171
|
+
" $<actual>: 101\n"\
|
172
|
+
" $<expected>: 1000..9999\n")
|
173
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
174
|
+
JSON(actual) === {
|
175
|
+
"items": [{"name": String, "id?": 1000..9999}].each
|
176
|
+
}
|
177
|
+
end
|
178
|
+
end
|
179
|
+
it "[!bz74w] fails when array lengths are different." do
|
180
|
+
actual = {"arr": ["A", "B", "C"]}
|
181
|
+
errmsg = ("$<JSON>[\"arr\"]: $<actual>.length == $<expected>.length : failed.\n"\
|
182
|
+
" $<actual>.length: 3\n"\
|
183
|
+
" $<expected>.length: 4\n"\
|
184
|
+
" $<actual>: [\"A\", \"B\", \"C\"]\n"\
|
185
|
+
" $<expected>: [\"A\", \"B\", \"C\", \"D\"]\n")
|
186
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
187
|
+
JSON(actual) === {"arr": ["A", "B", "C", "D"]}
|
188
|
+
end
|
189
|
+
end
|
190
|
+
it "[!fmxyg] compares hash objects recursively." do
|
191
|
+
actual = {
|
192
|
+
"owner": {"name": "Alice", "age": 20},
|
193
|
+
"item": {"id": 10001, "name": "Something", "price": 500},
|
194
|
+
}
|
195
|
+
result = JSON(actual) === {
|
196
|
+
"owner": {"name": String, "age": 0..100},
|
197
|
+
"item": {"id": 1..99999, "name": String, "price?": Numeric},
|
198
|
+
}
|
199
|
+
assert_eq result, true
|
200
|
+
#
|
201
|
+
errmsg = ("$<JSON>[\"item\"][\"price\"]: $<expected> === $<actual> : failed.\n"\
|
202
|
+
" $<actual>: 500\n"\
|
203
|
+
" $<expected>: Float\n")
|
204
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
205
|
+
JSON(actual) === {
|
206
|
+
"owner": {"name": String, "age": 0..100},
|
207
|
+
"item": {"id": 1..99999, "name": String, "price?": Float},
|
208
|
+
}
|
209
|
+
end
|
210
|
+
end
|
211
|
+
it "[!rkv0z] compares two hashes with converting keys into string." do
|
212
|
+
actual1 = {k1: "A", k2: "B"}
|
213
|
+
result = JSON(actual1) === {"k1"=>"A", "k2"=>"B"}
|
214
|
+
assert_eq result, true
|
215
|
+
#
|
216
|
+
actual2 = {"k1"=>"A", "k2"=>"B"}
|
217
|
+
result = JSON(actual2) === {k1: "A", k2: "B"}
|
218
|
+
assert_eq result, true
|
219
|
+
end
|
220
|
+
it "[!jbyv6] key 'aaa?' represents optional key." do
|
221
|
+
actual1 = {"name": "alice", "birth": "2000-01-01"}
|
222
|
+
result = JSON(actual1) === {"name": "alice", "birth?": "2000-01-01"}
|
223
|
+
assert_eq result, true
|
224
|
+
#
|
225
|
+
actual2 = {"name": "alice"}
|
226
|
+
result = JSON(actual2) === {"name": "alice", "birth?": "2000-01-01"}
|
227
|
+
assert_eq result, true
|
228
|
+
#
|
229
|
+
actual3 = {"name": "alice", "birth": nil}
|
230
|
+
result = JSON(actual3) === {"name": "alice", "birth?": "2000-01-01"}
|
231
|
+
assert_eq result, true
|
232
|
+
#
|
233
|
+
actual4 = {"name": "alice", "birth?": "2000-01-01"} # TODO
|
234
|
+
result = JSON(actual4) === {"name": "alice", "birth?": "2000-01-01"}
|
235
|
+
assert_eq result, true
|
236
|
+
end
|
237
|
+
it "[!mpbvu] fails when unexpected key exists in actual hash." do
|
238
|
+
actual = {"id": 101, "name": "Alice"}
|
239
|
+
errmsg = ("$<JSON>: key \"gender\" expected but not found.\n"\
|
240
|
+
" $<actual>.keys: \"id\", \"name\"\n"\
|
241
|
+
" $<expected>.keys: \"gender\", \"id\", \"name\"\n")
|
242
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
243
|
+
JSON(actual) === {"id": Integer, "name": String, "gender": String}
|
244
|
+
end
|
245
|
+
end
|
246
|
+
it "[!4oasq] fails when expected key not exist in actual hash." do
|
247
|
+
actual = {"id": 101, "name": "Alice"}
|
248
|
+
errmsg = ("$<JSON>[\"id\"]: unexpected key.\n"\
|
249
|
+
" $<actual>: 101\n")
|
250
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
251
|
+
JSON(actual) === {"name": String}
|
252
|
+
end
|
253
|
+
end
|
254
|
+
it "[!eqr3b] `OR()` matches to any of arguments." do
|
255
|
+
result = JSON({"val": 123}) === {"val": OR(String, Integer)}
|
256
|
+
assert_eq result, true
|
257
|
+
result = JSON({"val": "123"}) === {"val": OR(String, Integer)}
|
258
|
+
assert_eq result, true
|
259
|
+
#
|
260
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
261
|
+
" $<actual>: 3.14\n"\
|
262
|
+
" $<expected>: OR(String, Integer)\n")
|
263
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
264
|
+
JSON({"val": 3.14}) === {"val": OR(String, Integer)}
|
265
|
+
end
|
266
|
+
end
|
267
|
+
it "[!4hk96] `AND()` matches to all of arguments." do
|
268
|
+
result = JSON({"val": "alice"}) === {"val": AND(String, /^[a-z]+$/)}
|
269
|
+
assert_eq result, true
|
270
|
+
#
|
271
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
272
|
+
" $<actual>: \"Alice\"\n"\
|
273
|
+
" $<expected>: AND(/^[a-z]+$/)\n")
|
274
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
275
|
+
JSON({"val": "Alice"}) === {"val": AND(String, /^[a-z]+$/)}
|
276
|
+
end
|
277
|
+
end
|
278
|
+
it "[!5ybfg] `OR()` can contain `AND()`." do
|
279
|
+
expected = {"val": OR(AND(String, /^\d+$/), AND(Integer, 100..999))}
|
280
|
+
result = JSON({"val": "123"}) === expected
|
281
|
+
assert_eq result, true
|
282
|
+
result = JSON({"val": 123}) === expected
|
283
|
+
assert_eq result, true
|
284
|
+
#
|
285
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
286
|
+
" $<actual>: \"abc\"\n"\
|
287
|
+
" $<expected>: OR(AND(String, /^\\d+$/), AND(Integer, 100..999))\n")
|
288
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
289
|
+
JSON({"val": "abc"}) === expected
|
290
|
+
end
|
291
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
292
|
+
" $<actual>: 99\n"\
|
293
|
+
" $<expected>: OR(AND(String, /^\\d+$/), AND(Integer, 100..999))\n")
|
294
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
295
|
+
JSON({"val": 99}) === expected
|
296
|
+
end
|
297
|
+
end
|
298
|
+
it "[!scx22] `AND()` can contain `OR()`." do
|
299
|
+
expected = {"val": AND(OR(String, Integer), OR(/^\d{3}$/, 100..999))}
|
300
|
+
result = JSON({"val": "123"}) === expected
|
301
|
+
assert_eq result, true
|
302
|
+
result = JSON({"val": 123}) === expected
|
303
|
+
assert_eq result, true
|
304
|
+
#
|
305
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
306
|
+
" $<actual>: \"1\"\n"\
|
307
|
+
" $<expected>: AND(OR(/^\\d{3}$/, 100..999))\n")
|
308
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
309
|
+
JSON({"val": "1"}) === expected
|
310
|
+
end
|
311
|
+
errmsg = ("$<JSON>[\"val\"]: $<expected> === $<actual> : failed.\n"\
|
312
|
+
" $<actual>: 0\n"\
|
313
|
+
" $<expected>: AND(OR(/^\\d{3}$/, 100..999))\n")
|
314
|
+
assert_exc(Oktest::FAIL_EXCEPTION, errmsg) do
|
315
|
+
JSON({"val": 0}) === expected
|
316
|
+
end
|
317
|
+
end
|
318
|
+
it "[!uc4ag] key '*' matches to any key name." do
|
319
|
+
actual = {"name": "Alice", "age": 20}
|
320
|
+
result = JSON(actual) === {"name": String, "*": Integer}
|
321
|
+
assert_eq result, true
|
322
|
+
result = JSON(actual) === {"name": String, "*": ANY()}
|
323
|
+
assert_eq result, true
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe '#_compare?()' do
|
328
|
+
it "[!nkvqo] returns true when nothing raised." do
|
329
|
+
result = JSON(nil).instance_eval { _compare?([], "abc", /^\w+$/) }
|
330
|
+
assert_eq result, true
|
331
|
+
end
|
332
|
+
it "[!57m2j] returns false when assertion error raised." do
|
333
|
+
result = JSON(nil).instance_eval { _compare?([], "abc", /^\d+$/) }
|
334
|
+
assert_eq result, false
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
end
|
339
|
+
|
340
|
+
|
341
|
+
class OR_TC < TC
|
342
|
+
|
343
|
+
describe '#inspect()' do
|
344
|
+
it "[!2mu33] returns 'OR(...)' string." do
|
345
|
+
o = Oktest::JsonMatcher::OR.new('A', 'B', 'C')
|
346
|
+
assert_eq o.inspect(), 'OR("A", "B", "C")'
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
|
353
|
+
class AND_TC < TC
|
354
|
+
|
355
|
+
describe '#inspect()' do
|
356
|
+
it "[!w43ag] returns 'AND(...)' string." do
|
357
|
+
o = Oktest::JsonMatcher::AND.new('A', 'B', 'C')
|
358
|
+
assert_eq o.inspect(), 'AND("A", "B", "C")'
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
end
|
363
|
+
|
364
|
+
|
365
|
+
class Enum_TC < TC
|
366
|
+
|
367
|
+
describe '#inspect()' do
|
368
|
+
it "[!fam11] returns 'Enum(...)' string." do
|
369
|
+
o = Oktest::JsonMatcher::Enum.new(['A', 'B', 'C'])
|
370
|
+
assert_eq o.inspect(), 'Enum("A", "B", "C")'
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
|
377
|
+
class Length_TC < TC
|
378
|
+
|
379
|
+
describe '#===' do
|
380
|
+
it "[!03ozi] compares length of actual value with expected value." do
|
381
|
+
o1 = Oktest::JsonMatcher::Length.new(3)
|
382
|
+
assert_eq (o1 === "abc"), true
|
383
|
+
assert_eq (o1 === "abcd"), false
|
384
|
+
assert_eq (o1 === [1,2,3]), true
|
385
|
+
assert_eq (o1 === [1, 2]), false
|
386
|
+
o2 = Oktest::JsonMatcher::Length.new(1..3)
|
387
|
+
assert_eq (o2 === "a"), true
|
388
|
+
assert_eq (o2 === "abc"), true
|
389
|
+
assert_eq (o2 === ""), false
|
390
|
+
assert_eq (o2 === "abcd"), false
|
391
|
+
end
|
392
|
+
end
|
393
|
+
|
394
|
+
describe '#inspect()' do
|
395
|
+
it "[!nwv3e] returns 'Length(n)' string." do
|
396
|
+
o = Oktest::JsonMatcher::Length.new(1..3)
|
397
|
+
assert_eq o.inspect, "Length(1..3)"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
401
|
+
end
|
402
|
+
|
403
|
+
|
404
|
+
class Any_TC < TC
|
405
|
+
|
406
|
+
describe '#===' do
|
407
|
+
it "[!mzion] returns true in any case." do
|
408
|
+
o = Oktest::JsonMatcher::Any.new()
|
409
|
+
assert_eq (o === nil) , true
|
410
|
+
assert_eq (o === true) , true
|
411
|
+
assert_eq (o === false), true
|
412
|
+
assert_eq (o === 123) , true
|
413
|
+
assert_eq (o === "abc"), true
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe '#inspect()' do
|
418
|
+
it "[!6f0yv] returns 'Any()' string." do
|
419
|
+
o = Oktest::JsonMatcher::Any.new()
|
420
|
+
assert_eq o.inspect, "Any()"
|
421
|
+
end
|
422
|
+
end
|
423
|
+
|
424
|
+
end
|