rtype-native 0.5.0 → 0.5.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.
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