rtype 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/spec/rtype_spec.rb CHANGED
@@ -1,822 +1,822 @@
1
- require_relative 'spec_helper'
2
-
3
- describe Rtype do
4
- let(:klass) do
5
- Class.new do
6
- attr_accessor :value
7
-
8
- def initialize
9
- @value = 123
10
- end
11
-
12
- def return_arg(obj)
13
- obj
14
- end
15
-
16
- def two_args(a, b)
17
- end
18
-
19
- def three_args(a, b, c)
20
- end
21
-
22
- def three_kwargs(a:, b:, c:)
23
- end
24
-
25
- def return_nil(obj)
26
- nil
27
- end
28
-
29
- def sum(a, b)
30
- a + b
31
- end
32
-
33
- def kwarg(a:)
34
- a
35
- end
36
-
37
- def sum_kwargs(a:, b:)
38
- a + b
39
- end
40
-
41
- def arg_and_kwarg(a, b:)
42
- end
43
-
44
- def arg_and_kwargs(a, b:, c:)
45
- end
46
-
47
- def args_and_kwargs(a, b, c:, d:)
48
- end
49
-
50
- protected
51
- def protected_func
52
- end
53
-
54
- private
55
- def private_func
56
- end
57
- end
58
- end
59
-
60
- let(:instance) do
61
- klass.new
62
- end
63
-
64
- describe 'Kernel#rtype' do
65
- context "with annotation mode" do
66
- it "works with instance method" do
67
- class AnnotationTest
68
- rtype [String] => Any
69
- def test(str)
70
- end
71
- end
72
- expect {
73
- AnnotationTest.new.test(123)
74
- }.to raise_error Rtype::ArgumentTypeError
75
- end
76
- it "works with class method" do
77
- class AnnotationTest
78
- rtype [String] => Any
79
- def self.class_method_test(str)
80
- end
81
- end
82
- expect {
83
- AnnotationTest::class_method_test(123)
84
- }.to raise_error Rtype::ArgumentTypeError
85
- end
86
- context "outside of module" do
87
- it "doesn't works" do
88
- expect {
89
- rtype [String] => Any
90
- def annotation_test(str)
91
- end
92
- }.to raise_error ArgumentError
93
- end
94
- end
95
- end
96
-
97
- it "outside of module" do
98
- rtype :test_args, [String] => Any
99
- def test_args(str)
100
- end
101
-
102
- expect {test_args 123}.to raise_error Rtype::ArgumentTypeError
103
-
104
- rtype :test_return, [] => String
105
- def test_return
106
- 369
107
- end
108
-
109
- expect {test_return}.to raise_error Rtype::ReturnTypeError
110
- end
111
-
112
- it "in module" do
113
- class TestClass
114
- rtype :test_args, [String] => Any
115
- def test_args(str)
116
- end
117
- end
118
-
119
- expect {TestClass.new.test_args 123}.to raise_error Rtype::ArgumentTypeError
120
-
121
- class TestClass
122
- rtype :test_return, [] => String
123
- def test_return
124
- 369
125
- end
126
- end
127
-
128
- expect {TestClass.new.test_return}.to raise_error Rtype::ReturnTypeError
129
- end
130
- end
131
-
132
- it "Kernel#rtype_self" do
133
- class TestClass
134
- rtype_self :static_test_args, [String] => Any
135
- def self.static_test_args(str)
136
- end
137
- end
138
-
139
- expect {TestClass::static_test_args 123}.to raise_error Rtype::ArgumentTypeError
140
-
141
- class TestClass
142
- rtype_self :static_test_return, [] => String
143
- def self.static_test_return
144
- 369
145
- end
146
- end
147
-
148
- expect {TestClass::static_test_return}.to raise_error Rtype::ReturnTypeError
149
- end
150
-
151
- it 'Kernel#rtype_accessor' do
152
- class TestClass
153
- rtype_accessor :value, String
154
-
155
- def initialize
156
- @value = 123
157
- end
158
- end
159
- expect {TestClass.new.value = 123}.to raise_error Rtype::ArgumentTypeError
160
- expect {TestClass.new.value}.to raise_error Rtype::ReturnTypeError
161
- end
162
-
163
- it 'Kernel#rtype_accessor_self' do
164
- class TestClass
165
- @@val = 123
166
-
167
- rtype_accessor_self :value, String
168
- end
169
- expect {TestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
170
- expect {TestClass::value}.to raise_error Rtype::ReturnTypeError
171
- end
172
-
173
- describe 'Test type behaviors' do
174
- describe 'Module' do
175
- it "is right" do
176
- klass.send :rtype, :return_arg, [String] => Any
177
- instance.return_arg("This is a string!")
178
- end
179
- it "is wrong" do
180
- klass.send :rtype, :return_arg, [String] => Any
181
- expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
182
- end
183
- it "is wrong result" do
184
- klass.send :rtype, :return_nil, [Any] => String
185
- expect {instance.return_nil("This is a string!")}.to raise_error Rtype::ReturnTypeError
186
- end
187
- end
188
-
189
- describe 'Symbol' do
190
- it "is right" do
191
- klass.send :rtype, :return_arg, [:to_i] => Any
192
- instance.return_arg(123)
193
- end
194
- it "is wrong args" do
195
- klass.send :rtype, :return_arg, [:to_i] => Any
196
- expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
197
- end
198
- it "is wrong result" do
199
- klass.send :rtype, :return_nil, [Any] => :odd?
200
- expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
201
- end
202
- end
203
-
204
- describe 'Regexp' do
205
- it "is right" do
206
- klass.send :rtype, :return_arg, [/cuba/] => Any
207
- instance.return_arg("cuba")
208
- end
209
- it "is wrong args" do
210
- klass.send :rtype, :return_arg, [/cuba/] => Any
211
- expect {instance.return_arg("brazil")}.to raise_error Rtype::ArgumentTypeError
212
- end
213
- it "is wrong result" do
214
- klass.send :rtype, :return_nil, [Any] => /cuba/
215
- expect {instance.return_nil("cuba")}.to raise_error Rtype::ReturnTypeError
216
- end
217
- end
218
-
219
- describe 'Range' do
220
- it "is right" do
221
- klass.send :rtype, :return_arg, [1..10] => Any
222
- instance.return_arg(5)
223
- end
224
- it "is wrong args" do
225
- klass.send :rtype, :return_arg, [1..10] => Any
226
- expect {
227
- instance.return_arg(1001)
228
- }.to raise_error Rtype::ArgumentTypeError
229
- end
230
- it "is wrong result" do
231
- klass.send :rtype, :return_nil, [Any] => 1..10
232
- expect {
233
- instance.return_nil(5)
234
- }.to raise_error Rtype::ReturnTypeError
235
- end
236
- end
237
-
238
- describe 'Array' do
239
- it "is right" do
240
- klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
241
- instance.return_arg([123, 456])
242
-
243
- klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
244
- instance.two_args([123], [456])
245
- end
246
- it "is wrong args" do
247
- klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
248
- expect {
249
- instance.return_arg([123, [true]])
250
- }.to raise_error Rtype::ArgumentTypeError
251
- expect {
252
- instance.return_arg([123, true])
253
- }.to raise_error Rtype::ArgumentTypeError
254
-
255
- klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
256
- expect {
257
- instance.two_args([123, 123], [123])
258
- }.to raise_error Rtype::ArgumentTypeError
259
- expect {
260
- instance.two_args([123], 123)
261
- }.to raise_error Rtype::ArgumentTypeError
262
- end
263
- it "is wrong result" do
264
- klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
265
- expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
266
- end
267
- end
268
-
269
- describe 'Hash' do
270
- it "is right" do
271
- klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
272
- instance.return_arg({k: 123}, {})
273
- end
274
- it "is wrong args" do
275
- klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
276
- expect {
277
- instance.return_arg({k: "str"}, {})
278
- }.to raise_error Rtype::ArgumentTypeError
279
- end
280
- it "is wrong result" do
281
- klass.send :rtype, :return_arg, [Any] => {k: Integer}
282
- expect { instance.return_arg({k: "str"}) }.to raise_error Rtype::ReturnTypeError
283
- end
284
- end
285
-
286
- describe 'Proc' do
287
- it "is right" do
288
- klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
289
- instance.return_arg(123)
290
- end
291
- it "is wrong args" do
292
- klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
293
- expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
294
- end
295
- it "is wrong result" do
296
- klass.send :rtype, :return_nil, [Any] => ->(arg){!arg.nil?}
297
- expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
298
- end
299
- end
300
-
301
- describe 'true' do
302
- it "is right" do
303
- klass.send :rtype, :return_arg, [true] => Any
304
- instance.return_arg(true)
305
- instance.return_arg(123)
306
- end
307
- it "is wrong args" do
308
- klass.send :rtype, :return_arg, [true] => Any
309
- expect {instance.return_arg(false)}.to raise_error Rtype::ArgumentTypeError
310
- expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
311
- end
312
- it "is wrong result" do
313
- klass.send :rtype, :return_arg, [Any] => true
314
- expect {instance.return_arg(false)}.to raise_error Rtype::ReturnTypeError
315
- expect {instance.return_arg(nil)}.to raise_error Rtype::ReturnTypeError
316
- end
317
- end
318
-
319
- describe 'false' do
320
- it "is right" do
321
- klass.send :rtype, :return_arg, [false] => Any
322
- instance.return_arg(false)
323
- instance.return_arg(nil)
324
- end
325
- it "is wrong args" do
326
- klass.send :rtype, :return_arg, [false] => Any
327
- expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
328
- expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
329
- end
330
- it "is wrong result" do
331
- klass.send :rtype, :return_arg, [Any] => false
332
- expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
333
- expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
334
- end
335
- end
336
-
337
- describe 'nil' do
338
- it "is only for return" do
339
- klass.send :rtype, :return_nil, [] => nil
340
- instance.return_nil(123)
341
-
342
- klass.send :rtype, :return_arg, [] => nil
343
- expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
344
- end
345
- it "could not be used for args" do
346
- expect {
347
- klass.send :rtype, :return_arg, [nil] => Any
348
- }.to raise_error Rtype::TypeSignatureError
349
- end
350
- end
351
-
352
- describe 'Special type behaviors' do
353
- describe 'Rtype::Behavior::And' do
354
- it 'module singleton method' do
355
- klass.send :rtype, :return_nil, [Rtype::and(:to_i, :chars)] => nil
356
- instance.return_nil("Hello")
357
- expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
358
- end
359
-
360
- it 'class singleton [] method' do
361
- klass.send :rtype, :return_nil, [ Rtype::Behavior::And[:to_i, :chars] ] => nil
362
- instance.return_nil("Hello")
363
- expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
364
- end
365
-
366
- it 'core extension method' do
367
- klass.send :rtype, :return_nil, [ :to_i.and(:chars) ] => nil
368
- instance.return_nil("Hello")
369
- expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
370
- end
371
- end
372
-
373
- describe 'Rtype::Behavior::Or' do
374
- it 'module singleton method' do
375
- klass.send :rtype, :return_nil, [Rtype::or(Integer, String)] => nil
376
- instance.return_nil(123)
377
- instance.return_nil("abc")
378
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
379
- end
380
-
381
- it 'class singleton [] method' do
382
- klass.send :rtype, :return_nil, [ Rtype::Behavior::Or[Integer, String] ] => nil
383
- instance.return_nil(123)
384
- instance.return_nil("abc")
385
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
386
- end
387
-
388
- it 'core extension method' do
389
- klass.send :rtype, :return_nil, [ Integer.or(String) ] => nil
390
- instance.return_nil(123)
391
- instance.return_nil("abc")
392
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
393
- end
394
- end
395
-
396
- describe 'Rtype::Behavior::Nilable' do
397
- it 'module singleton method' do
398
- klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
399
- instance.return_nil(nil)
400
- instance.return_nil(123)
401
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
402
- end
403
-
404
- it 'class singleton [] method' do
405
- klass.send :rtype, :return_nil, [ Rtype::Behavior::Nilable[Integer] ] => nil
406
- instance.return_nil(nil)
407
- instance.return_nil(123)
408
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
409
- end
410
-
411
- it 'core extension method :nilable' do
412
- klass.send :rtype, :return_nil, [Integer.nilable] => nil
413
- instance.return_nil(nil)
414
- instance.return_nil(123)
415
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
416
- end
417
-
418
- it 'core extension method :or_nil' do
419
- klass.send :rtype, :return_nil, [Integer.or_nil] => nil
420
- instance.return_nil(nil)
421
- instance.return_nil(123)
422
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
423
- end
424
- end
425
-
426
- describe 'Rtype::Behavior::Not' do
427
- it 'module singleton method' do
428
- klass.send :rtype, :return_nil, [Rtype::not(String)] => nil
429
- instance.return_nil(123)
430
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
431
- end
432
-
433
- it 'class singleton [] method' do
434
- klass.send :rtype, :return_nil, [ Rtype::Behavior::Not[String] ] => nil
435
- instance.return_nil(123)
436
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
437
- end
438
-
439
- it 'core extension method' do
440
- klass.send :rtype, :return_nil, [ String.not ] => nil
441
- instance.return_nil(123)
442
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
443
- end
444
- end
445
-
446
- describe 'Rtype::Behavior::Xor' do
447
- it 'module singleton method' do
448
- klass.send :rtype, :return_nil, [Rtype::xor(:to_i, String)] => nil
449
- instance.return_nil(123)
450
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
451
- end
452
-
453
- it 'class singleton [] method' do
454
- klass.send :rtype, :return_nil, [ Rtype::Behavior::Xor[:to_i, String] ] => nil
455
- instance.return_nil(123)
456
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
457
- end
458
-
459
- it 'core extension method' do
460
- klass.send :rtype, :return_nil, [ :to_i.xor(String) ] => nil
461
- instance.return_nil(123)
462
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
463
- end
464
- end
465
- end
466
- end
467
-
468
- describe 'Signature' do
469
- describe 'check arguments' do
470
- it 'nothing' do
471
- klass.send :rtype, :sum, [] => Any
472
- instance.sum(1, 2)
473
- instance.sum(1, 2.0)
474
- instance.sum(1.0, 2.0)
475
- instance.sum("a", "b")
476
- end
477
-
478
- it 'two' do
479
- klass.send :rtype, :sum, [Integer, Integer] => Any
480
- expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
481
- end
482
-
483
- it 'two array' do
484
- klass.send :rtype, :sum, [[Integer], [Integer]] => Any
485
- instance.sum([1], [2])
486
- expect {instance.sum([1], 2)}.to raise_error Rtype::ArgumentTypeError
487
- expect {instance.sum([1], ["str"])}.to raise_error Rtype::ArgumentTypeError
488
- end
489
-
490
- it 'two hash' do
491
- klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
492
- instance.two_args({k: 123}, {k: 456}, {})
493
- expect {
494
- instance.two_args({k: 123}, {}, {})
495
- }.to raise_error Rtype::ArgumentTypeError
496
- expect {
497
- instance.two_args({k: 123}, 456, {})
498
- }.to raise_error Rtype::ArgumentTypeError
499
- expect {
500
- instance.two_args({k: 123}, {k: "str"}, {})
501
- }.to raise_error Rtype::ArgumentTypeError
502
- end
503
-
504
- it 'one keyword argument' do
505
- klass.send :rtype, :kwarg, {a: Float} => Any
506
- expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
507
- end
508
-
509
- it 'two keyword argument' do
510
- klass.send :rtype, :sum_kwargs, {a: Integer, b: Float} => Any
511
- expect {instance.sum_kwargs(a: 1, b: 2)}.to raise_error Rtype::ArgumentTypeError
512
- end
513
-
514
- it 'one with one keyword argument' do
515
- klass.send :rtype, :arg_and_kwarg, [Integer, {b: Float}] => Any
516
- expect {instance.arg_and_kwarg(1, b: 2)}.to raise_error Rtype::ArgumentTypeError
517
- end
518
-
519
- it 'one with two keyword argument' do
520
- klass.send :rtype, :arg_and_kwargs, [Integer, {c: String, d: String}] => Any
521
- expect {instance.arg_and_kwargs(1, b: 2, c: 3)}.to raise_error Rtype::ArgumentTypeError
522
- end
523
-
524
- it 'two with two keyword argument' do
525
- klass.send :rtype, :args_and_kwargs, [Integer, Integer, {c: String, d: String}] => Any
526
- expect {instance.args_and_kwargs(1, 2, c: 3, d: 4)}.to raise_error Rtype::ArgumentTypeError
527
- end
528
-
529
- it 'string key could not be used for keyword argument' do
530
- expect {
531
- klass.send :rtype, :kwarg, {'a' => Float} => Any
532
- }.to raise_error Rtype::TypeSignatureError
533
- end
534
-
535
- it 'only symbol key is used for keyword argument' do
536
- klass.send :rtype, :kwarg, {:a => Float} => Any
537
- expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
538
- expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
539
- end
540
-
541
- context 'when hash is not last element' do
542
- it 'is hash-type argument, not keyword argument' do
543
- klass.send :rtype, :return_arg, [{a: String}, {}] => Any
544
- expect {
545
- instance.return_arg({a: 123}, {})
546
- }.to raise_error Rtype::ArgumentTypeError
547
- end
548
- end
549
-
550
- it 'hash-type argument and keyword argument' do
551
- klass.send :rtype, :arg_and_kwarg, [{a: String}, {b: String}] => Any
552
- expect {
553
- instance.arg_and_kwarg({a: 123}, b: "str")
554
- }.to raise_error Rtype::ArgumentTypeError
555
- expect {
556
- instance.arg_and_kwarg({a: "str"}, b: 123)
557
- }.to raise_error Rtype::ArgumentTypeError
558
- end
559
- end
560
-
561
- describe 'check return' do
562
- it 'Any' do
563
- klass.send :rtype, :return_arg, [] => Any
564
- instance.return_arg("str")
565
- end
566
-
567
- it 'Array (tuple)' do
568
- klass.send :rtype, :return_arg, [] => [Integer, Float]
569
- expect {instance.return_arg([1, 2])}.to raise_error Rtype::ReturnTypeError
570
- end
571
- end
572
-
573
- it 'check arguments and return value' do
574
- klass.send :rtype, :return_nil, [Float] => nil
575
- expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
576
- klass.send :rtype, :return_nil, [Integer] => Integer
577
- expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
578
- end
579
-
580
- describe 'wrong case' do
581
- describe 'invalid type signature' do
582
- it 'invalid arguments type signature' do
583
- expect {
584
- klass.send :rtype, :return_arg, Any => nil
585
- }.to raise_error Rtype::TypeSignatureError
586
- end
587
- it 'invalid return type signature' do
588
- expect {
589
- klass.send :rtype, :return_arg, [] => 123
590
- }.to raise_error Rtype::TypeSignatureError
591
- end
592
-
593
- it 'invalid type behavior in arguments' do
594
- expect {
595
- klass.send :rtype, :sum_kwargs, [{a: 123}, {b: Integer}] => Any
596
- }.to raise_error Rtype::TypeSignatureError
597
- expect {
598
- klass.send :rtype, :return_arg, [123] => Any
599
- }.to raise_error Rtype::TypeSignatureError
600
- expect {
601
- klass.send :rtype, :return_arg, ["abc"] => Any
602
- }.to raise_error Rtype::TypeSignatureError
603
- expect {
604
- klass.send :rtype, :kwarg, {a: 123} => Any
605
- }.to raise_error Rtype::TypeSignatureError
606
- expect {
607
- klass.send :rtype, :kwarg, {a: {b: 123}} => Any
608
- }.to raise_error Rtype::TypeSignatureError
609
- expect {
610
- klass.send :rtype, :kwarg, {Object.new => Integer} => Any
611
- }.to raise_error Rtype::TypeSignatureError
612
- end
613
-
614
- it 'invalid type behavior in return' do
615
- expect {
616
- klass.send :rtype, :return_arg, [] => 123
617
- }.to raise_error Rtype::TypeSignatureError
618
- expect {
619
- klass.send :rtype, :return_arg, [] => "abc"
620
- }.to raise_error Rtype::TypeSignatureError
621
- end
622
-
623
- context "with annotation mode" do
624
- it 'works' do
625
- expect {
626
- class AnnotationTest
627
- rtype [String, 123] => Any
628
- def invalid_test(arg)
629
- end
630
- end
631
- }.to raise_error Rtype::TypeSignatureError
632
- end
633
- end
634
- end
635
- end
636
- end
637
-
638
- describe "Implementation" do
639
- it 'can be called before method definition' do
640
- class TestClass
641
- rtype :method_def, [Integer] => Any
642
- def method_def(i)
643
- end
644
- end
645
- expect {
646
- TestClass.new.method_def("abc")
647
- }.to raise_error Rtype::ArgumentTypeError
648
- end
649
-
650
- it 'can be called after method definition' do
651
- class TestClass
652
- def method_def_2(i)
653
- end
654
- rtype :method_def_2, [Integer] => Any
655
- end
656
- expect {
657
- TestClass.new.method_def_2("abc")
658
- }.to raise_error Rtype::ArgumentTypeError
659
- end
660
-
661
- it 'method name can be both symbol and string' do
662
- class TestClass
663
- rtype 'method_def_3', [Integer] => Any
664
- def method_def_3(i)
665
- end
666
- rtype :method_def_4, [Integer] => Any
667
- def method_def_4(i)
668
- end
669
- end
670
- expect {
671
- TestClass.new.method_def_3("abc")
672
- }.to raise_error Rtype::ArgumentTypeError
673
- expect {
674
- TestClass.new.method_def_4("abc")
675
- }.to raise_error Rtype::ArgumentTypeError
676
- end
677
-
678
- describe 'method visibility works' do
679
- it 'protected' do
680
- expect {instance.protected_func}.to raise_error NoMethodError
681
- end
682
- it 'private' do
683
- expect {instance.private_func}.to raise_error NoMethodError
684
- end
685
- end
686
-
687
- context 'with empty argument signature' do
688
- it 'accept any arguments' do
689
- klass.send :rtype, :three_args, [] => Any
690
- instance.three_args("abc", 123, 456)
691
- end
692
- end
693
-
694
- context 'when args length is more than arg signature length' do
695
- it 'type checking ignore rest args' do
696
- klass.send :rtype, :three_args, [String] => Any
697
- instance.three_args("abc", 123, 456)
698
- end
699
- end
700
-
701
- context 'when keyword args contain a key not configured to rtype' do
702
- it 'type checking ignore the key' do
703
- klass.send :rtype, :three_kwargs, {a: String} => Any
704
- instance.three_kwargs(a: "abc", b: 123, c: 456)
705
- end
706
- end
707
-
708
- context 'when hash type argument contain a key not configured to rtype' do
709
- it 'raises error' do
710
- klass.send :rtype, :return_arg, [{a: String}, {}] => Any
711
- expect {
712
- instance.return_arg({a: "str", b: "str"}, {})
713
- }.to raise_error Rtype::ArgumentTypeError
714
- end
715
- end
716
-
717
- it "One rtype annotation affect only one method" do
718
- class AnnotationTest
719
- rtype [String] => Any
720
- def one(str)
721
- end
722
-
723
- def two(str)
724
- end
725
- end
726
- expect {
727
- AnnotationTest.new.one(123)
728
- }.to raise_error Rtype::ArgumentTypeError
729
- AnnotationTest.new.two(123)
730
- end
731
-
732
- it "One rtype annotation affect only one method, regardless of instance method or class method" do
733
- class AnnotationTest2
734
- rtype [String] => Any
735
- def self.static_one(str)
736
- end
737
-
738
- def inst_one(str)
739
- end
740
-
741
- def self.static_two(str)
742
- end
743
- end
744
- expect {
745
- AnnotationTest2::static_one(123)
746
- }.to raise_error Rtype::ArgumentTypeError
747
- AnnotationTest2.new.inst_one(123)
748
- AnnotationTest2::static_two(123)
749
- end
750
- end
751
-
752
- describe "Call Rtype`s static method directly" do
753
- it 'Rtype::define_typed_method' do
754
- Rtype::define_typed_method klass, :return_arg, [String] => Any
755
- expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
756
- end
757
-
758
- it 'Rtype::define_typed_accessor' do
759
- Rtype::define_typed_accessor klass, :value, String
760
- expect { instance.value = 123 }.to raise_error Rtype::ArgumentTypeError
761
- expect { instance.value }.to raise_error Rtype::ReturnTypeError
762
- end
763
-
764
- it 'Rtype::valid?' do
765
- expect(
766
- Rtype::valid?(String, "str")
767
- ).to be true
768
- expect(
769
- Rtype::valid?(Integer, "str")
770
- ).to be false
771
- expect {
772
- Rtype::valid?("Invalid type behavior", "Test Value")
773
- }.to raise_error Rtype::TypeSignatureError
774
- end
775
-
776
- it 'Rtype::assert_arguments_type' do
777
- expect {
778
- Rtype::assert_arguments_type([Integer, String], [123, 123])
779
- }.to raise_error Rtype::ArgumentTypeError
780
- end
781
-
782
- it 'Rtype::assert_arguments_type_with_keywords' do
783
- expect {
784
- Rtype::assert_arguments_type_with_keywords([Integer, String], [123, "abc"], {arg: String}, {arg: 123})
785
- }.to raise_error Rtype::ArgumentTypeError
786
- end
787
-
788
- it 'Rtype::assert_return_type' do
789
- expect {
790
- Rtype::assert_return_type nil, "No nil"
791
- }.to raise_error Rtype::ReturnTypeError
792
- end
793
-
794
- it 'Rtype::assert_valid_type_sig' do
795
- Rtype::assert_valid_type_sig([Integer, String] => Any)
796
- expect {
797
- Rtype::assert_valid_type_sig([Integer, String])
798
- }.to raise_error Rtype::TypeSignatureError
799
- end
800
-
801
- it 'Rtype::assert_valid_arguments_type_sig' do
802
- Rtype::assert_valid_arguments_type_sig([Integer, String])
803
- expect {
804
- Rtype::assert_valid_arguments_type_sig("[Integer, String]")
805
- }.to raise_error Rtype::TypeSignatureError
806
- end
807
-
808
- it 'Rtype::assert_valid_argument_type_sig_element' do
809
- Rtype::assert_valid_argument_type_sig_element(Integer)
810
- expect {
811
- Rtype::assert_valid_argument_type_sig_element("Integer")
812
- }.to raise_error Rtype::TypeSignatureError
813
- end
814
-
815
- it 'Rtype::assert_valid_return_type_sig' do
816
- Rtype::assert_valid_return_type_sig(Integer)
817
- expect {
818
- Rtype::assert_valid_return_type_sig("Integer")
819
- }.to raise_error Rtype::TypeSignatureError
820
- end
821
- end
822
- end
1
+ require_relative 'spec_helper'
2
+
3
+ describe Rtype do
4
+ let(:klass) do
5
+ Class.new do
6
+ attr_accessor :value
7
+
8
+ def initialize
9
+ @value = 123
10
+ end
11
+
12
+ def return_arg(obj)
13
+ obj
14
+ end
15
+
16
+ def two_args(a, b)
17
+ end
18
+
19
+ def three_args(a, b, c)
20
+ end
21
+
22
+ def three_kwargs(a:, b:, c:)
23
+ end
24
+
25
+ def return_nil(obj)
26
+ nil
27
+ end
28
+
29
+ def sum(a, b)
30
+ a + b
31
+ end
32
+
33
+ def kwarg(a:)
34
+ a
35
+ end
36
+
37
+ def sum_kwargs(a:, b:)
38
+ a + b
39
+ end
40
+
41
+ def arg_and_kwarg(a, b:)
42
+ end
43
+
44
+ def arg_and_kwargs(a, b:, c:)
45
+ end
46
+
47
+ def args_and_kwargs(a, b, c:, d:)
48
+ end
49
+
50
+ protected
51
+ def protected_func
52
+ end
53
+
54
+ private
55
+ def private_func
56
+ end
57
+ end
58
+ end
59
+
60
+ let(:instance) do
61
+ klass.new
62
+ end
63
+
64
+ describe 'Kernel#rtype' do
65
+ context "with annotation mode" do
66
+ it "works with instance method" do
67
+ class AnnotationTest
68
+ rtype [String] => Any
69
+ def test(str)
70
+ end
71
+ end
72
+ expect {
73
+ AnnotationTest.new.test(123)
74
+ }.to raise_error Rtype::ArgumentTypeError
75
+ end
76
+ it "works with class method" do
77
+ class AnnotationTest
78
+ rtype [String] => Any
79
+ def self.class_method_test(str)
80
+ end
81
+ end
82
+ expect {
83
+ AnnotationTest::class_method_test(123)
84
+ }.to raise_error Rtype::ArgumentTypeError
85
+ end
86
+ context "outside of module" do
87
+ it "doesn't works" do
88
+ expect {
89
+ rtype [String] => Any
90
+ def annotation_test(str)
91
+ end
92
+ }.to raise_error ArgumentError
93
+ end
94
+ end
95
+ end
96
+
97
+ it "outside of module" do
98
+ rtype :test_args, [String] => Any
99
+ def test_args(str)
100
+ end
101
+
102
+ expect {test_args 123}.to raise_error Rtype::ArgumentTypeError
103
+
104
+ rtype :test_return, [] => String
105
+ def test_return
106
+ 369
107
+ end
108
+
109
+ expect {test_return}.to raise_error Rtype::ReturnTypeError
110
+ end
111
+
112
+ it "in module" do
113
+ class TestClass
114
+ rtype :test_args, [String] => Any
115
+ def test_args(str)
116
+ end
117
+ end
118
+
119
+ expect {TestClass.new.test_args 123}.to raise_error Rtype::ArgumentTypeError
120
+
121
+ class TestClass
122
+ rtype :test_return, [] => String
123
+ def test_return
124
+ 369
125
+ end
126
+ end
127
+
128
+ expect {TestClass.new.test_return}.to raise_error Rtype::ReturnTypeError
129
+ end
130
+ end
131
+
132
+ it "Kernel#rtype_self" do
133
+ class TestClass
134
+ rtype_self :static_test_args, [String] => Any
135
+ def self.static_test_args(str)
136
+ end
137
+ end
138
+
139
+ expect {TestClass::static_test_args 123}.to raise_error Rtype::ArgumentTypeError
140
+
141
+ class TestClass
142
+ rtype_self :static_test_return, [] => String
143
+ def self.static_test_return
144
+ 369
145
+ end
146
+ end
147
+
148
+ expect {TestClass::static_test_return}.to raise_error Rtype::ReturnTypeError
149
+ end
150
+
151
+ it 'Kernel#rtype_accessor' do
152
+ class TestClass
153
+ rtype_accessor :value, String
154
+
155
+ def initialize
156
+ @value = 123
157
+ end
158
+ end
159
+ expect {TestClass.new.value = 123}.to raise_error Rtype::ArgumentTypeError
160
+ expect {TestClass.new.value}.to raise_error Rtype::ReturnTypeError
161
+ end
162
+
163
+ it 'Kernel#rtype_accessor_self' do
164
+ class TestClass
165
+ @@val = 123
166
+
167
+ rtype_accessor_self :value, String
168
+ end
169
+ expect {TestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
170
+ expect {TestClass::value}.to raise_error Rtype::ReturnTypeError
171
+ end
172
+
173
+ describe 'Test type behaviors' do
174
+ describe 'Module' do
175
+ it "is right" do
176
+ klass.send :rtype, :return_arg, [String] => Any
177
+ instance.return_arg("This is a string!")
178
+ end
179
+ it "is wrong" do
180
+ klass.send :rtype, :return_arg, [String] => Any
181
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
182
+ end
183
+ it "is wrong result" do
184
+ klass.send :rtype, :return_nil, [Any] => String
185
+ expect {instance.return_nil("This is a string!")}.to raise_error Rtype::ReturnTypeError
186
+ end
187
+ end
188
+
189
+ describe 'Symbol' do
190
+ it "is right" do
191
+ klass.send :rtype, :return_arg, [:to_i] => Any
192
+ instance.return_arg(123)
193
+ end
194
+ it "is wrong args" do
195
+ klass.send :rtype, :return_arg, [:to_i] => Any
196
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
197
+ end
198
+ it "is wrong result" do
199
+ klass.send :rtype, :return_nil, [Any] => :odd?
200
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
201
+ end
202
+ end
203
+
204
+ describe 'Regexp' do
205
+ it "is right" do
206
+ klass.send :rtype, :return_arg, [/cuba/] => Any
207
+ instance.return_arg("cuba")
208
+ end
209
+ it "is wrong args" do
210
+ klass.send :rtype, :return_arg, [/cuba/] => Any
211
+ expect {instance.return_arg("brazil")}.to raise_error Rtype::ArgumentTypeError
212
+ end
213
+ it "is wrong result" do
214
+ klass.send :rtype, :return_nil, [Any] => /cuba/
215
+ expect {instance.return_nil("cuba")}.to raise_error Rtype::ReturnTypeError
216
+ end
217
+ end
218
+
219
+ describe 'Range' do
220
+ it "is right" do
221
+ klass.send :rtype, :return_arg, [1..10] => Any
222
+ instance.return_arg(5)
223
+ end
224
+ it "is wrong args" do
225
+ klass.send :rtype, :return_arg, [1..10] => Any
226
+ expect {
227
+ instance.return_arg(1001)
228
+ }.to raise_error Rtype::ArgumentTypeError
229
+ end
230
+ it "is wrong result" do
231
+ klass.send :rtype, :return_nil, [Any] => 1..10
232
+ expect {
233
+ instance.return_nil(5)
234
+ }.to raise_error Rtype::ReturnTypeError
235
+ end
236
+ end
237
+
238
+ describe 'Array' do
239
+ it "is right" do
240
+ klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
241
+ instance.return_arg([123, 456])
242
+
243
+ klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
244
+ instance.two_args([123], [456])
245
+ end
246
+ it "is wrong args" do
247
+ klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
248
+ expect {
249
+ instance.return_arg([123, [true]])
250
+ }.to raise_error Rtype::ArgumentTypeError
251
+ expect {
252
+ instance.return_arg([123, true])
253
+ }.to raise_error Rtype::ArgumentTypeError
254
+
255
+ klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
256
+ expect {
257
+ instance.two_args([123, 123], [123])
258
+ }.to raise_error Rtype::ArgumentTypeError
259
+ expect {
260
+ instance.two_args([123], 123)
261
+ }.to raise_error Rtype::ArgumentTypeError
262
+ end
263
+ it "is wrong result" do
264
+ klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
265
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
266
+ end
267
+ end
268
+
269
+ describe 'Hash' do
270
+ it "is right" do
271
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
272
+ instance.return_arg({k: 123}, {})
273
+ end
274
+ it "is wrong args" do
275
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
276
+ expect {
277
+ instance.return_arg({k: "str"}, {})
278
+ }.to raise_error Rtype::ArgumentTypeError
279
+ end
280
+ it "is wrong result" do
281
+ klass.send :rtype, :return_arg, [Any] => {k: Integer}
282
+ expect { instance.return_arg({k: "str"}) }.to raise_error Rtype::ReturnTypeError
283
+ end
284
+ end
285
+
286
+ describe 'Proc' do
287
+ it "is right" do
288
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
289
+ instance.return_arg(123)
290
+ end
291
+ it "is wrong args" do
292
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
293
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
294
+ end
295
+ it "is wrong result" do
296
+ klass.send :rtype, :return_nil, [Any] => ->(arg){!arg.nil?}
297
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
298
+ end
299
+ end
300
+
301
+ describe 'true' do
302
+ it "is right" do
303
+ klass.send :rtype, :return_arg, [true] => Any
304
+ instance.return_arg(true)
305
+ instance.return_arg(123)
306
+ end
307
+ it "is wrong args" do
308
+ klass.send :rtype, :return_arg, [true] => Any
309
+ expect {instance.return_arg(false)}.to raise_error Rtype::ArgumentTypeError
310
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
311
+ end
312
+ it "is wrong result" do
313
+ klass.send :rtype, :return_arg, [Any] => true
314
+ expect {instance.return_arg(false)}.to raise_error Rtype::ReturnTypeError
315
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ReturnTypeError
316
+ end
317
+ end
318
+
319
+ describe 'false' do
320
+ it "is right" do
321
+ klass.send :rtype, :return_arg, [false] => Any
322
+ instance.return_arg(false)
323
+ instance.return_arg(nil)
324
+ end
325
+ it "is wrong args" do
326
+ klass.send :rtype, :return_arg, [false] => Any
327
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
328
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
329
+ end
330
+ it "is wrong result" do
331
+ klass.send :rtype, :return_arg, [Any] => false
332
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
333
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
334
+ end
335
+ end
336
+
337
+ describe 'nil' do
338
+ it "is only for return" do
339
+ klass.send :rtype, :return_nil, [] => nil
340
+ instance.return_nil(123)
341
+
342
+ klass.send :rtype, :return_arg, [] => nil
343
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
344
+ end
345
+ it "could not be used for args" do
346
+ expect {
347
+ klass.send :rtype, :return_arg, [nil] => Any
348
+ }.to raise_error Rtype::TypeSignatureError
349
+ end
350
+ end
351
+
352
+ describe 'Special type behaviors' do
353
+ describe 'Rtype::Behavior::And' do
354
+ it 'module singleton method' do
355
+ klass.send :rtype, :return_nil, [Rtype::and(:to_i, :chars)] => nil
356
+ instance.return_nil("Hello")
357
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
358
+ end
359
+
360
+ it 'class singleton [] method' do
361
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::And[:to_i, :chars] ] => nil
362
+ instance.return_nil("Hello")
363
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
364
+ end
365
+
366
+ it 'core extension method' do
367
+ klass.send :rtype, :return_nil, [ :to_i.and(:chars) ] => nil
368
+ instance.return_nil("Hello")
369
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
370
+ end
371
+ end
372
+
373
+ describe 'Rtype::Behavior::Or' do
374
+ it 'module singleton method' do
375
+ klass.send :rtype, :return_nil, [Rtype::or(Integer, String)] => nil
376
+ instance.return_nil(123)
377
+ instance.return_nil("abc")
378
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
379
+ end
380
+
381
+ it 'class singleton [] method' do
382
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Or[Integer, String] ] => nil
383
+ instance.return_nil(123)
384
+ instance.return_nil("abc")
385
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
386
+ end
387
+
388
+ it 'core extension method' do
389
+ klass.send :rtype, :return_nil, [ Integer.or(String) ] => nil
390
+ instance.return_nil(123)
391
+ instance.return_nil("abc")
392
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
393
+ end
394
+ end
395
+
396
+ describe 'Rtype::Behavior::Nilable' do
397
+ it 'module singleton method' do
398
+ klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
399
+ instance.return_nil(nil)
400
+ instance.return_nil(123)
401
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
402
+ end
403
+
404
+ it 'class singleton [] method' do
405
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Nilable[Integer] ] => nil
406
+ instance.return_nil(nil)
407
+ instance.return_nil(123)
408
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
409
+ end
410
+
411
+ it 'core extension method :nilable' do
412
+ klass.send :rtype, :return_nil, [Integer.nilable] => nil
413
+ instance.return_nil(nil)
414
+ instance.return_nil(123)
415
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
416
+ end
417
+
418
+ it 'core extension method :or_nil' do
419
+ klass.send :rtype, :return_nil, [Integer.or_nil] => nil
420
+ instance.return_nil(nil)
421
+ instance.return_nil(123)
422
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
423
+ end
424
+ end
425
+
426
+ describe 'Rtype::Behavior::Not' do
427
+ it 'module singleton method' do
428
+ klass.send :rtype, :return_nil, [Rtype::not(String)] => nil
429
+ instance.return_nil(123)
430
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
431
+ end
432
+
433
+ it 'class singleton [] method' do
434
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Not[String] ] => nil
435
+ instance.return_nil(123)
436
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
437
+ end
438
+
439
+ it 'core extension method' do
440
+ klass.send :rtype, :return_nil, [ String.not ] => nil
441
+ instance.return_nil(123)
442
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
443
+ end
444
+ end
445
+
446
+ describe 'Rtype::Behavior::Xor' do
447
+ it 'module singleton method' do
448
+ klass.send :rtype, :return_nil, [Rtype::xor(:to_i, String)] => nil
449
+ instance.return_nil(123)
450
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
451
+ end
452
+
453
+ it 'class singleton [] method' do
454
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Xor[:to_i, String] ] => nil
455
+ instance.return_nil(123)
456
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
457
+ end
458
+
459
+ it 'core extension method' do
460
+ klass.send :rtype, :return_nil, [ :to_i.xor(String) ] => nil
461
+ instance.return_nil(123)
462
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
463
+ end
464
+ end
465
+ end
466
+ end
467
+
468
+ describe 'Signature' do
469
+ describe 'check arguments' do
470
+ it 'nothing' do
471
+ klass.send :rtype, :sum, [] => Any
472
+ instance.sum(1, 2)
473
+ instance.sum(1, 2.0)
474
+ instance.sum(1.0, 2.0)
475
+ instance.sum("a", "b")
476
+ end
477
+
478
+ it 'two' do
479
+ klass.send :rtype, :sum, [Integer, Integer] => Any
480
+ expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
481
+ end
482
+
483
+ it 'two array' do
484
+ klass.send :rtype, :sum, [[Integer], [Integer]] => Any
485
+ instance.sum([1], [2])
486
+ expect {instance.sum([1], 2)}.to raise_error Rtype::ArgumentTypeError
487
+ expect {instance.sum([1], ["str"])}.to raise_error Rtype::ArgumentTypeError
488
+ end
489
+
490
+ it 'two hash' do
491
+ klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
492
+ instance.two_args({k: 123}, {k: 456}, {})
493
+ expect {
494
+ instance.two_args({k: 123}, {}, {})
495
+ }.to raise_error Rtype::ArgumentTypeError
496
+ expect {
497
+ instance.two_args({k: 123}, 456, {})
498
+ }.to raise_error Rtype::ArgumentTypeError
499
+ expect {
500
+ instance.two_args({k: 123}, {k: "str"}, {})
501
+ }.to raise_error Rtype::ArgumentTypeError
502
+ end
503
+
504
+ it 'one keyword argument' do
505
+ klass.send :rtype, :kwarg, {a: Float} => Any
506
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
507
+ end
508
+
509
+ it 'two keyword argument' do
510
+ klass.send :rtype, :sum_kwargs, {a: Integer, b: Float} => Any
511
+ expect {instance.sum_kwargs(a: 1, b: 2)}.to raise_error Rtype::ArgumentTypeError
512
+ end
513
+
514
+ it 'one with one keyword argument' do
515
+ klass.send :rtype, :arg_and_kwarg, [Integer, {b: Float}] => Any
516
+ expect {instance.arg_and_kwarg(1, b: 2)}.to raise_error Rtype::ArgumentTypeError
517
+ end
518
+
519
+ it 'one with two keyword argument' do
520
+ klass.send :rtype, :arg_and_kwargs, [Integer, {c: String, d: String}] => Any
521
+ expect {instance.arg_and_kwargs(1, b: 2, c: 3)}.to raise_error Rtype::ArgumentTypeError
522
+ end
523
+
524
+ it 'two with two keyword argument' do
525
+ klass.send :rtype, :args_and_kwargs, [Integer, Integer, {c: String, d: String}] => Any
526
+ expect {instance.args_and_kwargs(1, 2, c: 3, d: 4)}.to raise_error Rtype::ArgumentTypeError
527
+ end
528
+
529
+ it 'string key could not be used for keyword argument' do
530
+ expect {
531
+ klass.send :rtype, :kwarg, {'a' => Float} => Any
532
+ }.to raise_error Rtype::TypeSignatureError
533
+ end
534
+
535
+ it 'only symbol key is used for keyword argument' do
536
+ klass.send :rtype, :kwarg, {:a => Float} => Any
537
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
538
+ expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
539
+ end
540
+
541
+ context 'when hash is not last element' do
542
+ it 'is hash-type argument, not keyword argument' do
543
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
544
+ expect {
545
+ instance.return_arg({a: 123}, {})
546
+ }.to raise_error Rtype::ArgumentTypeError
547
+ end
548
+ end
549
+
550
+ it 'hash-type argument and keyword argument' do
551
+ klass.send :rtype, :arg_and_kwarg, [{a: String}, {b: String}] => Any
552
+ expect {
553
+ instance.arg_and_kwarg({a: 123}, b: "str")
554
+ }.to raise_error Rtype::ArgumentTypeError
555
+ expect {
556
+ instance.arg_and_kwarg({a: "str"}, b: 123)
557
+ }.to raise_error Rtype::ArgumentTypeError
558
+ end
559
+ end
560
+
561
+ describe 'check return' do
562
+ it 'Any' do
563
+ klass.send :rtype, :return_arg, [] => Any
564
+ instance.return_arg("str")
565
+ end
566
+
567
+ it 'Array (tuple)' do
568
+ klass.send :rtype, :return_arg, [] => [Integer, Float]
569
+ expect {instance.return_arg([1, 2])}.to raise_error Rtype::ReturnTypeError
570
+ end
571
+ end
572
+
573
+ it 'check arguments and return value' do
574
+ klass.send :rtype, :return_nil, [Float] => nil
575
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
576
+ klass.send :rtype, :return_nil, [Integer] => Integer
577
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
578
+ end
579
+
580
+ describe 'wrong case' do
581
+ describe 'invalid type signature' do
582
+ it 'invalid arguments type signature' do
583
+ expect {
584
+ klass.send :rtype, :return_arg, Any => nil
585
+ }.to raise_error Rtype::TypeSignatureError
586
+ end
587
+ it 'invalid return type signature' do
588
+ expect {
589
+ klass.send :rtype, :return_arg, [] => 123
590
+ }.to raise_error Rtype::TypeSignatureError
591
+ end
592
+
593
+ it 'invalid type behavior in arguments' do
594
+ expect {
595
+ klass.send :rtype, :sum_kwargs, [{a: 123}, {b: Integer}] => Any
596
+ }.to raise_error Rtype::TypeSignatureError
597
+ expect {
598
+ klass.send :rtype, :return_arg, [123] => Any
599
+ }.to raise_error Rtype::TypeSignatureError
600
+ expect {
601
+ klass.send :rtype, :return_arg, ["abc"] => Any
602
+ }.to raise_error Rtype::TypeSignatureError
603
+ expect {
604
+ klass.send :rtype, :kwarg, {a: 123} => Any
605
+ }.to raise_error Rtype::TypeSignatureError
606
+ expect {
607
+ klass.send :rtype, :kwarg, {a: {b: 123}} => Any
608
+ }.to raise_error Rtype::TypeSignatureError
609
+ expect {
610
+ klass.send :rtype, :kwarg, {Object.new => Integer} => Any
611
+ }.to raise_error Rtype::TypeSignatureError
612
+ end
613
+
614
+ it 'invalid type behavior in return' do
615
+ expect {
616
+ klass.send :rtype, :return_arg, [] => 123
617
+ }.to raise_error Rtype::TypeSignatureError
618
+ expect {
619
+ klass.send :rtype, :return_arg, [] => "abc"
620
+ }.to raise_error Rtype::TypeSignatureError
621
+ end
622
+
623
+ context "with annotation mode" do
624
+ it 'works' do
625
+ expect {
626
+ class AnnotationTest
627
+ rtype [String, 123] => Any
628
+ def invalid_test(arg)
629
+ end
630
+ end
631
+ }.to raise_error Rtype::TypeSignatureError
632
+ end
633
+ end
634
+ end
635
+ end
636
+ end
637
+
638
+ describe "Implementation" do
639
+ it 'can be called before method definition' do
640
+ class TestClass
641
+ rtype :method_def, [Integer] => Any
642
+ def method_def(i)
643
+ end
644
+ end
645
+ expect {
646
+ TestClass.new.method_def("abc")
647
+ }.to raise_error Rtype::ArgumentTypeError
648
+ end
649
+
650
+ it 'can be called after method definition' do
651
+ class TestClass
652
+ def method_def_2(i)
653
+ end
654
+ rtype :method_def_2, [Integer] => Any
655
+ end
656
+ expect {
657
+ TestClass.new.method_def_2("abc")
658
+ }.to raise_error Rtype::ArgumentTypeError
659
+ end
660
+
661
+ it 'method name can be both symbol and string' do
662
+ class TestClass
663
+ rtype 'method_def_3', [Integer] => Any
664
+ def method_def_3(i)
665
+ end
666
+ rtype :method_def_4, [Integer] => Any
667
+ def method_def_4(i)
668
+ end
669
+ end
670
+ expect {
671
+ TestClass.new.method_def_3("abc")
672
+ }.to raise_error Rtype::ArgumentTypeError
673
+ expect {
674
+ TestClass.new.method_def_4("abc")
675
+ }.to raise_error Rtype::ArgumentTypeError
676
+ end
677
+
678
+ describe 'method visibility works' do
679
+ it 'protected' do
680
+ expect {instance.protected_func}.to raise_error NoMethodError
681
+ end
682
+ it 'private' do
683
+ expect {instance.private_func}.to raise_error NoMethodError
684
+ end
685
+ end
686
+
687
+ context 'with empty argument signature' do
688
+ it 'accept any arguments' do
689
+ klass.send :rtype, :three_args, [] => Any
690
+ instance.three_args("abc", 123, 456)
691
+ end
692
+ end
693
+
694
+ context 'when args length is more than arg signature length' do
695
+ it 'type checking ignore rest args' do
696
+ klass.send :rtype, :three_args, [String] => Any
697
+ instance.three_args("abc", 123, 456)
698
+ end
699
+ end
700
+
701
+ context 'when keyword args contain a key not configured to rtype' do
702
+ it 'type checking ignore the key' do
703
+ klass.send :rtype, :three_kwargs, {a: String} => Any
704
+ instance.three_kwargs(a: "abc", b: 123, c: 456)
705
+ end
706
+ end
707
+
708
+ context 'when hash type argument contain a key not configured to rtype' do
709
+ it 'raises error' do
710
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
711
+ expect {
712
+ instance.return_arg({a: "str", b: "str"}, {})
713
+ }.to raise_error Rtype::ArgumentTypeError
714
+ end
715
+ end
716
+
717
+ it "One rtype annotation affect only one method" do
718
+ class AnnotationTest
719
+ rtype [String] => Any
720
+ def one(str)
721
+ end
722
+
723
+ def two(str)
724
+ end
725
+ end
726
+ expect {
727
+ AnnotationTest.new.one(123)
728
+ }.to raise_error Rtype::ArgumentTypeError
729
+ AnnotationTest.new.two(123)
730
+ end
731
+
732
+ it "One rtype annotation affect only one method, regardless of instance method or class method" do
733
+ class AnnotationTest2
734
+ rtype [String] => Any
735
+ def self.static_one(str)
736
+ end
737
+
738
+ def inst_one(str)
739
+ end
740
+
741
+ def self.static_two(str)
742
+ end
743
+ end
744
+ expect {
745
+ AnnotationTest2::static_one(123)
746
+ }.to raise_error Rtype::ArgumentTypeError
747
+ AnnotationTest2.new.inst_one(123)
748
+ AnnotationTest2::static_two(123)
749
+ end
750
+ end
751
+
752
+ describe "Call Rtype`s static method directly" do
753
+ it 'Rtype::define_typed_method' do
754
+ Rtype::define_typed_method klass, :return_arg, [String] => Any
755
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
756
+ end
757
+
758
+ it 'Rtype::define_typed_accessor' do
759
+ Rtype::define_typed_accessor klass, :value, String
760
+ expect { instance.value = 123 }.to raise_error Rtype::ArgumentTypeError
761
+ expect { instance.value }.to raise_error Rtype::ReturnTypeError
762
+ end
763
+
764
+ it 'Rtype::valid?' do
765
+ expect(
766
+ Rtype::valid?(String, "str")
767
+ ).to be true
768
+ expect(
769
+ Rtype::valid?(Integer, "str")
770
+ ).to be false
771
+ expect {
772
+ Rtype::valid?("Invalid type behavior", "Test Value")
773
+ }.to raise_error Rtype::TypeSignatureError
774
+ end
775
+
776
+ it 'Rtype::assert_arguments_type' do
777
+ expect {
778
+ Rtype::assert_arguments_type([Integer, String], [123, 123])
779
+ }.to raise_error Rtype::ArgumentTypeError
780
+ end
781
+
782
+ it 'Rtype::assert_arguments_type_with_keywords' do
783
+ expect {
784
+ Rtype::assert_arguments_type_with_keywords([Integer, String], [123, "abc"], {arg: String}, {arg: 123})
785
+ }.to raise_error Rtype::ArgumentTypeError
786
+ end
787
+
788
+ it 'Rtype::assert_return_type' do
789
+ expect {
790
+ Rtype::assert_return_type nil, "No nil"
791
+ }.to raise_error Rtype::ReturnTypeError
792
+ end
793
+
794
+ it 'Rtype::assert_valid_type_sig' do
795
+ Rtype::assert_valid_type_sig([Integer, String] => Any)
796
+ expect {
797
+ Rtype::assert_valid_type_sig([Integer, String])
798
+ }.to raise_error Rtype::TypeSignatureError
799
+ end
800
+
801
+ it 'Rtype::assert_valid_arguments_type_sig' do
802
+ Rtype::assert_valid_arguments_type_sig([Integer, String])
803
+ expect {
804
+ Rtype::assert_valid_arguments_type_sig("[Integer, String]")
805
+ }.to raise_error Rtype::TypeSignatureError
806
+ end
807
+
808
+ it 'Rtype::assert_valid_argument_type_sig_element' do
809
+ Rtype::assert_valid_argument_type_sig_element(Integer)
810
+ expect {
811
+ Rtype::assert_valid_argument_type_sig_element("Integer")
812
+ }.to raise_error Rtype::TypeSignatureError
813
+ end
814
+
815
+ it 'Rtype::assert_valid_return_type_sig' do
816
+ Rtype::assert_valid_return_type_sig(Integer)
817
+ expect {
818
+ Rtype::assert_valid_return_type_sig("Integer")
819
+ }.to raise_error Rtype::TypeSignatureError
820
+ end
821
+ end
822
+ end