rtype 0.6.8-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1070 @@
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
+ public
51
+ def public_func
52
+ end
53
+
54
+ protected
55
+ def protected_func
56
+ end
57
+
58
+ private
59
+ def private_func
60
+ end
61
+ end
62
+ end
63
+
64
+ let(:instance) do
65
+ klass.new
66
+ end
67
+
68
+ describe 'Kernel#rtype' do
69
+ context "with annotation mode" do
70
+ it "works with instance method" do
71
+ class AnnotationTest
72
+ rtype [String] => Any
73
+ def test(str)
74
+ end
75
+ end
76
+ expect {
77
+ AnnotationTest.new.test(123)
78
+ }.to raise_error Rtype::ArgumentTypeError
79
+ end
80
+ it "works with class method" do
81
+ class AnnotationTest
82
+ rtype [String] => Any
83
+ def self.class_method_test(str)
84
+ end
85
+ end
86
+ expect {
87
+ AnnotationTest::class_method_test(123)
88
+ }.to raise_error Rtype::ArgumentTypeError
89
+ end
90
+ context "outside of module" do
91
+ it "doesn't works" do
92
+ expect {
93
+ rtype [String] => Any
94
+ def annotation_test(str)
95
+ end
96
+ }.to raise_error ArgumentError
97
+ end
98
+ end
99
+ end
100
+
101
+ it "outside of module" do
102
+ rtype :test_args, [String] => Any
103
+ def test_args(str)
104
+ end
105
+
106
+ expect {test_args 123}.to raise_error Rtype::ArgumentTypeError
107
+
108
+ rtype :test_return, [] => String
109
+ def test_return
110
+ 369
111
+ end
112
+
113
+ expect {test_return}.to raise_error Rtype::ReturnTypeError
114
+ end
115
+
116
+ it "in module" do
117
+ class TestClass
118
+ rtype :test_args, [String] => Any
119
+ def test_args(str)
120
+ end
121
+ end
122
+
123
+ expect {TestClass.new.test_args 123}.to raise_error Rtype::ArgumentTypeError
124
+
125
+ class TestClass
126
+ rtype :test_return, [] => String
127
+ def test_return
128
+ 369
129
+ end
130
+ end
131
+
132
+ expect {TestClass.new.test_return}.to raise_error Rtype::ReturnTypeError
133
+ end
134
+ end
135
+
136
+ it "Kernel#rtype_self" do
137
+ class TestClass
138
+ rtype_self :static_test_args, [String] => Any
139
+ def self.static_test_args(str)
140
+ end
141
+ end
142
+
143
+ expect {TestClass::static_test_args 123}.to raise_error Rtype::ArgumentTypeError
144
+
145
+ class TestClass
146
+ rtype_self :static_test_return, [] => String
147
+ def self.static_test_return
148
+ 369
149
+ end
150
+ end
151
+
152
+ expect {TestClass::static_test_return}.to raise_error Rtype::ReturnTypeError
153
+ end
154
+
155
+ it 'Kernel#rtype_accessor' do
156
+ class AccessorTestClass
157
+ rtype_accessor :value, :value2, String
158
+
159
+ def initialize
160
+ @value = 123
161
+ @value2 = 123
162
+ end
163
+ end
164
+ expect {AccessorTestClass.new.value = 123}.to raise_error Rtype::ArgumentTypeError
165
+ expect {AccessorTestClass.new.value}.to raise_error Rtype::ReturnTypeError
166
+ expect {AccessorTestClass.new.value2 = 123}.to raise_error Rtype::ArgumentTypeError
167
+ expect {AccessorTestClass.new.value2}.to raise_error Rtype::ReturnTypeError
168
+ end
169
+
170
+ it 'Kernel#rtype_accessor_self' do
171
+ class AccessorTestClass
172
+ @@value = 123
173
+ @@value2 = 123
174
+ rtype_accessor_self :value, :value2, String
175
+ end
176
+ expect {AccessorTestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
177
+ expect {AccessorTestClass::value}.to raise_error Rtype::ReturnTypeError
178
+ expect {AccessorTestClass::value2 = 123}.to raise_error Rtype::ArgumentTypeError
179
+ expect {AccessorTestClass::value2}.to raise_error Rtype::ReturnTypeError
180
+ end
181
+
182
+ it 'Kernel#rtype_reader' do
183
+ class ReaderTestClass
184
+ rtype_reader :value, :value2, String
185
+
186
+ def initialize
187
+ @value = 123
188
+ @value2 = 123
189
+ end
190
+ end
191
+ expect {ReaderTestClass.new.value}.to raise_error Rtype::ReturnTypeError
192
+ expect {ReaderTestClass.new.value2}.to raise_error Rtype::ReturnTypeError
193
+ end
194
+
195
+ it 'Kernel#rtype_reader_self' do
196
+ class ReaderTestClass
197
+ @@value = 123
198
+ @@value2 = 123
199
+ rtype_reader_self :value, :value2, String
200
+ end
201
+ expect {ReaderTestClass::value}.to raise_error Rtype::ReturnTypeError
202
+ expect {ReaderTestClass::value2}.to raise_error Rtype::ReturnTypeError
203
+ end
204
+
205
+ it 'Kernel#rtype_writer' do
206
+ class WriterTestClass
207
+ rtype_writer :value, :value2, String
208
+
209
+ def initialize
210
+ @value = 123
211
+ @value2 = 123
212
+ end
213
+ end
214
+ expect {WriterTestClass.new.value = 123}.to raise_error Rtype::ArgumentTypeError
215
+ expect {WriterTestClass.new.value2 = 123}.to raise_error Rtype::ArgumentTypeError
216
+ end
217
+
218
+ it 'Kernel#rtype_writer_self' do
219
+ class WriterTestClass
220
+ @@value = 123
221
+ @@value2 = 123
222
+ rtype_writer_self :value, :value2, String
223
+ end
224
+ expect {WriterTestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
225
+ expect {WriterTestClass::value2 = 123}.to raise_error Rtype::ArgumentTypeError
226
+ end
227
+
228
+ it 'Kernel#float_accessor' do
229
+ class FloatAccessorTestClass
230
+ float_accessor :float, :int
231
+
232
+ def initialize
233
+ @float = 10.0
234
+ @int = 10
235
+ end
236
+ end
237
+
238
+ float_accessor_test = FloatAccessorTestClass.new
239
+
240
+ float_accessor_test.float
241
+ expect {float_accessor_test.int}.to raise_error Rtype::ReturnTypeError
242
+ float_accessor_test.float = 5.0
243
+ float_accessor_test.float = 5
244
+ expect(float_accessor_test.float).to eql(5.0) # be(expected) => passes if actual.eql?(expected)
245
+ expect(float_accessor_test.float).not_to eql(5)
246
+ end
247
+
248
+ it 'Kernel#bool_accessor' do
249
+ class BoolAccessorTestClass
250
+ bool_accessor :state, :invalid_var
251
+
252
+ def initialize
253
+ @state = false
254
+ @invalid_var = 123
255
+ end
256
+ end
257
+
258
+ bool_accessor_test = BoolAccessorTestClass.new
259
+
260
+ bool_accessor_test.state?
261
+ expect {bool_accessor_test.state}.to raise_error NoMethodError
262
+ expect(bool_accessor_test.state?).to eql(false)
263
+ bool_accessor_test.state = true
264
+ expect(bool_accessor_test.state?).to eql(true)
265
+ expect {bool_accessor_test.state = 123}.to raise_error Rtype::ArgumentTypeError
266
+ expect {bool_accessor_test.invalid_var?}.to raise_error Rtype::ReturnTypeError
267
+ end
268
+
269
+ describe 'Test type behaviors' do
270
+ describe 'Module' do
271
+ it "is right" do
272
+ klass.send :rtype, :return_arg, [String] => Any
273
+ instance.return_arg("This is a string!")
274
+ end
275
+ it "is wrong" do
276
+ klass.send :rtype, :return_arg, [String] => Any
277
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
278
+ end
279
+ it "is wrong result" do
280
+ klass.send :rtype, :return_nil, [Any] => String
281
+ expect {instance.return_nil("This is a string!")}.to raise_error Rtype::ReturnTypeError
282
+ end
283
+ end
284
+
285
+ describe 'Symbol' do
286
+ it "is right" do
287
+ klass.send :rtype, :return_arg, [:to_i] => Any
288
+ instance.return_arg(123)
289
+ end
290
+ it "is wrong args" do
291
+ klass.send :rtype, :return_arg, [:to_i] => Any
292
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
293
+ end
294
+ it "is wrong result" do
295
+ klass.send :rtype, :return_nil, [Any] => :odd?
296
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
297
+ end
298
+ end
299
+
300
+ describe 'Regexp' do
301
+ it "is right" do
302
+ klass.send :rtype, :return_arg, [/cuba/] => Any
303
+ instance.return_arg("cuba")
304
+ end
305
+ it "is wrong args" do
306
+ klass.send :rtype, :return_arg, [/cuba/] => Any
307
+ expect {instance.return_arg("brazil")}.to raise_error Rtype::ArgumentTypeError
308
+ end
309
+ it "is wrong result" do
310
+ klass.send :rtype, :return_nil, [Any] => /cuba/
311
+ expect {instance.return_nil("cuba")}.to raise_error Rtype::ReturnTypeError
312
+ end
313
+ end
314
+
315
+ describe 'Range' do
316
+ it "is right" do
317
+ klass.send :rtype, :return_arg, [1..10] => Any
318
+ instance.return_arg(5)
319
+ end
320
+ it "is wrong args" do
321
+ klass.send :rtype, :return_arg, [1..10] => Any
322
+ expect {
323
+ instance.return_arg(1001)
324
+ }.to raise_error Rtype::ArgumentTypeError
325
+ end
326
+ it "is wrong result" do
327
+ klass.send :rtype, :return_nil, [Any] => 1..10
328
+ expect {
329
+ instance.return_nil(5)
330
+ }.to raise_error Rtype::ReturnTypeError
331
+ end
332
+ end
333
+
334
+ describe 'Array' do
335
+ it "is right" do
336
+ klass.send :rtype, :return_arg, [[:to_i]] => Any
337
+ instance.return_arg(123)
338
+
339
+ klass.send :rtype, :return_arg, [[String, Integer]] => Any
340
+ instance.return_arg("str")
341
+ instance.return_arg(123)
342
+
343
+ klass.send :rtype, :return_arg, [] => [String, Integer]
344
+ instance.return_arg("str")
345
+ instance.return_arg(123)
346
+ end
347
+ it "is wrong args" do
348
+ klass.send :rtype, :return_arg, [[String, Integer]] => Any
349
+ expect {
350
+ instance.return_arg(nil)
351
+ }.to raise_error Rtype::ArgumentTypeError
352
+
353
+ klass.send :rtype, :return_arg, [[String]] => Any
354
+ expect {
355
+ instance.return_arg(123)
356
+ }.to raise_error Rtype::ArgumentTypeError
357
+ end
358
+ it "is wrong result" do
359
+ klass.send :rtype, :return_arg, [Any] => [String, Integer]
360
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
361
+ end
362
+ end
363
+
364
+ describe 'Hash' do
365
+ it "is right" do
366
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
367
+ instance.return_arg({k: 123})
368
+ end
369
+ it "is wrong args" do
370
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
371
+ expect {
372
+ instance.return_arg({k: "str"})
373
+ }.to raise_error Rtype::ArgumentTypeError
374
+ end
375
+ it "is wrong result" do
376
+ klass.send :rtype, :return_arg, [Any] => {k: Integer}
377
+ expect { instance.return_arg({k: "str"}) }.to raise_error Rtype::ReturnTypeError
378
+ end
379
+ end
380
+
381
+ describe 'Proc' do
382
+ it "is right" do
383
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
384
+ instance.return_arg(123)
385
+ end
386
+ it "is wrong args" do
387
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
388
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
389
+ end
390
+ it "is wrong result" do
391
+ klass.send :rtype, :return_nil, [Any] => ->(arg){!arg.nil?}
392
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
393
+ end
394
+ end
395
+
396
+ describe 'true' do
397
+ it "is right" do
398
+ klass.send :rtype, :return_arg, [true] => Any
399
+ instance.return_arg(true)
400
+ instance.return_arg(123)
401
+ end
402
+ it "is wrong args" do
403
+ klass.send :rtype, :return_arg, [true] => Any
404
+ expect {instance.return_arg(false)}.to raise_error Rtype::ArgumentTypeError
405
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
406
+ end
407
+ it "is wrong result" do
408
+ klass.send :rtype, :return_arg, [Any] => true
409
+ expect {instance.return_arg(false)}.to raise_error Rtype::ReturnTypeError
410
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ReturnTypeError
411
+ end
412
+ end
413
+
414
+ describe 'false' do
415
+ it "is right" do
416
+ klass.send :rtype, :return_arg, [false] => Any
417
+ instance.return_arg(false)
418
+ instance.return_arg(nil)
419
+ end
420
+ it "is wrong args" do
421
+ klass.send :rtype, :return_arg, [false] => Any
422
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
423
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
424
+ end
425
+ it "is wrong result" do
426
+ klass.send :rtype, :return_arg, [Any] => false
427
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
428
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
429
+ end
430
+ end
431
+
432
+ describe 'nil' do
433
+ it "for return" do
434
+ klass.send :rtype, :return_nil, [] => nil
435
+ instance.return_nil(123)
436
+
437
+ klass.send :rtype, :return_arg, [] => nil
438
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
439
+ end
440
+ it "for args" do
441
+ klass.send :rtype, :return_arg, [nil] => Any
442
+ instance.return_arg(nil)
443
+ expect {
444
+ instance.return_arg(123)
445
+ }.to raise_error Rtype::ArgumentTypeError
446
+ end
447
+ end
448
+
449
+ describe 'Special type behaviors' do
450
+ describe 'Rtype::Behavior::And' do
451
+ it 'module singleton method' do
452
+ klass.send :rtype, :return_nil, [Rtype::and(:to_i, :chars)] => nil
453
+ instance.return_nil("Hello")
454
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
455
+ end
456
+
457
+ it 'class singleton [] method' do
458
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::And[:to_i, :chars] ] => nil
459
+ instance.return_nil("Hello")
460
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
461
+ end
462
+
463
+ it 'core extension method' do
464
+ klass.send :rtype, :return_nil, [ :to_i.and(:chars) ] => nil
465
+ instance.return_nil("Hello")
466
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
467
+ end
468
+ end
469
+
470
+ describe 'Rtype::Behavior::Nilable' do
471
+ it 'module singleton method' do
472
+ klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
473
+ instance.return_nil(nil)
474
+ instance.return_nil(123)
475
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
476
+ end
477
+
478
+ it 'class singleton [] method' do
479
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Nilable[Integer] ] => nil
480
+ instance.return_nil(nil)
481
+ instance.return_nil(123)
482
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
483
+ end
484
+
485
+ it 'core extension method :nilable' do
486
+ klass.send :rtype, :return_nil, [Integer.nilable] => nil
487
+ instance.return_nil(nil)
488
+ instance.return_nil(123)
489
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
490
+ end
491
+
492
+ it 'core extension method :or_nil' do
493
+ klass.send :rtype, :return_nil, [Integer.or_nil] => nil
494
+ instance.return_nil(nil)
495
+ instance.return_nil(123)
496
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
497
+ end
498
+ end
499
+
500
+ describe 'Rtype::Behavior::Not' do
501
+ it 'module singleton method' do
502
+ klass.send :rtype, :return_nil, [Rtype::not(String)] => nil
503
+ instance.return_nil(123)
504
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
505
+ end
506
+
507
+ it 'class singleton [] method' do
508
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Not[String] ] => nil
509
+ instance.return_nil(123)
510
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
511
+ end
512
+
513
+ it 'core extension method' do
514
+ klass.send :rtype, :return_nil, [ String.not ] => nil
515
+ instance.return_nil(123)
516
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
517
+ end
518
+ end
519
+
520
+ describe 'Rtype::Behavior::Xor' do
521
+ it 'module singleton method' do
522
+ klass.send :rtype, :return_nil, [Rtype::xor(:to_i, String)] => nil
523
+ instance.return_nil(123)
524
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
525
+ end
526
+
527
+ it 'class singleton [] method' do
528
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Xor[:to_i, String] ] => nil
529
+ instance.return_nil(123)
530
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
531
+ end
532
+
533
+ it 'core extension method' do
534
+ klass.send :rtype, :return_nil, [ :to_i.xor(String) ] => nil
535
+ instance.return_nil(123)
536
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
537
+ end
538
+ end
539
+
540
+ describe 'Rtype::Behavior::TypedArray' do
541
+ it 'class singleton [] method' do
542
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::TypedArray[Integer] ] => nil
543
+ instance.return_nil([123])
544
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
545
+ expect {instance.return_nil([1.0])}.to raise_error Rtype::ArgumentTypeError
546
+ end
547
+
548
+ it 'core extension method (Array::of)' do
549
+ klass.send :rtype, :return_nil, [ Array.of(Integer) ] => nil
550
+ instance.return_nil([123])
551
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
552
+ expect {instance.return_nil([1.0])}.to raise_error Rtype::ArgumentTypeError
553
+ end
554
+
555
+ it 'complicated type sig' do
556
+ klass.send :rtype, :return_nil, [ Array.of(:to_i.and(:chars)) ] => nil
557
+ instance.return_nil(["hello"])
558
+ expect {instance.return_nil("hello")}.to raise_error Rtype::ArgumentTypeError
559
+ expect {instance.return_nil([123])}.to raise_error Rtype::ArgumentTypeError
560
+ end
561
+
562
+ it 'allows empty array' do
563
+ klass.send :rtype, :return_nil, [ Array.of(Integer) ] => nil
564
+ instance.return_nil([])
565
+ end
566
+ end
567
+
568
+ describe 'Rtype::Behavior::TypedSet' do
569
+ it 'class singleton [] method' do
570
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::TypedSet[Integer] ] => nil
571
+ instance.return_nil( Set.new([123]) )
572
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
573
+ expect { instance.return_nil(Set.new([1.0])) }.to raise_error Rtype::ArgumentTypeError
574
+ end
575
+
576
+ it 'core extension method (Set::of)' do
577
+ klass.send :rtype, :return_nil, [ Set.of(Integer) ] => nil
578
+ instance.return_nil( Set.new([123]) )
579
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
580
+ expect { instance.return_nil(Set.new([1.0])) }.to raise_error Rtype::ArgumentTypeError
581
+ end
582
+
583
+ it 'complicated type sig' do
584
+ klass.send :rtype, :return_nil, [ Set.of(:to_i.and(:chars)) ] => nil
585
+ instance.return_nil( Set.new(["hello"]) )
586
+ expect {instance.return_nil("hello")}.to raise_error Rtype::ArgumentTypeError
587
+ expect { instance.return_nil(Set.new([123])) }.to raise_error Rtype::ArgumentTypeError
588
+ end
589
+
590
+ it 'allows empty set' do
591
+ klass.send :rtype, :return_nil, [ Set.of(Integer) ] => nil
592
+ instance.return_nil(Set.new)
593
+ end
594
+ end
595
+
596
+ describe 'Rtype::Behavior::TypedHash' do
597
+ it 'class singleton [] method' do
598
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::TypedHash[Symbol, Integer] ] => nil
599
+ instance.return_nil( {key: 123} )
600
+ expect {instance.return_nil(:key)}.to raise_error Rtype::ArgumentTypeError
601
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
602
+ expect {instance.return_nil( {"key" => 123} )}.to raise_error Rtype::ArgumentTypeError
603
+ end
604
+
605
+ it 'core extension method (Hash::of)' do
606
+ klass.send :rtype, :return_nil, [ Hash.of(Symbol, Integer) ] => nil
607
+ instance.return_nil( {key: 123} )
608
+ expect {instance.return_nil(:key)}.to raise_error Rtype::ArgumentTypeError
609
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
610
+ expect {instance.return_nil( {"key" => 123} )}.to raise_error Rtype::ArgumentTypeError
611
+ end
612
+
613
+ it 'complicated type sig' do
614
+ klass.send :rtype, :return_nil, [ Hash.of(:to_i.and(:chars), :to_i.and(:chars)) ] => nil
615
+ instance.return_nil( {"key" => "val"} )
616
+ expect {instance.return_nil("hello")}.to raise_error Rtype::ArgumentTypeError
617
+ expect {instance.return_nil( {key: "val"} )}.to raise_error Rtype::ArgumentTypeError
618
+ expect {instance.return_nil( {"key" => :val} )}.to raise_error Rtype::ArgumentTypeError
619
+ end
620
+
621
+ it 'allows empty hash' do
622
+ klass.send :rtype, :return_nil, [ Hash.of(Symbol, Integer) ] => nil
623
+ instance.return_nil({})
624
+ end
625
+ end
626
+
627
+ describe 'Numeric check' do
628
+ it 'Num (Numeric)' do
629
+ klass.send :rtype, :return_nil, [Num >= 0] => Any
630
+ expect { instance.return_nil("hello") }.to raise_error Rtype::ArgumentTypeError
631
+ expect { instance.return_nil(-1) }.to raise_error Rtype::ArgumentTypeError
632
+ instance.return_nil(2)
633
+ instance.return_nil(2.0)
634
+
635
+ klass.send :rtype, :return_nil, [Num > 0] => Any
636
+ expect { instance.return_nil("non numeric") }.to raise_error Rtype::ArgumentTypeError
637
+ expect { instance.return_nil(0) }.to raise_error Rtype::ArgumentTypeError
638
+
639
+ klass.send :rtype, :return_nil, [Num < 0] => Any
640
+ expect { instance.return_nil("non numeric") }.to raise_error Rtype::ArgumentTypeError
641
+ expect { instance.return_nil(0) }.to raise_error Rtype::ArgumentTypeError
642
+
643
+ klass.send :rtype, :return_nil, [Num <= 0] => Any
644
+ expect { instance.return_nil("non numeric") }.to raise_error Rtype::ArgumentTypeError
645
+ expect { instance.return_nil(1) }.to raise_error Rtype::ArgumentTypeError
646
+ end
647
+
648
+ it 'Int (Integer)' do
649
+ klass.send :rtype, :return_nil, [Int >= 0] => Any
650
+ expect { instance.return_nil("hello") }.to raise_error Rtype::ArgumentTypeError
651
+ expect { instance.return_nil(1.0) }.to raise_error Rtype::ArgumentTypeError
652
+ expect { instance.return_nil(-1) }.to raise_error Rtype::ArgumentTypeError
653
+ instance.return_nil(2)
654
+
655
+ klass.send :rtype, :return_nil, [Int > 0] => Any
656
+ expect { instance.return_nil(1.0) }.to raise_error Rtype::ArgumentTypeError
657
+ expect { instance.return_nil(0) }.to raise_error Rtype::ArgumentTypeError
658
+
659
+ klass.send :rtype, :return_nil, [Int < 0] => Any
660
+ expect { instance.return_nil(-1.0) }.to raise_error Rtype::ArgumentTypeError
661
+ expect { instance.return_nil(0) }.to raise_error Rtype::ArgumentTypeError
662
+
663
+ klass.send :rtype, :return_nil, [Int <= 0] => Any
664
+ expect { instance.return_nil(0.0) }.to raise_error Rtype::ArgumentTypeError
665
+ expect { instance.return_nil(1) }.to raise_error Rtype::ArgumentTypeError
666
+ end
667
+
668
+ it 'Flo (Float)' do
669
+ klass.send :rtype, :return_nil, [Flo >= 0] => Any
670
+ expect { instance.return_nil("hello") }.to raise_error Rtype::ArgumentTypeError
671
+ expect { instance.return_nil(1) }.to raise_error Rtype::ArgumentTypeError
672
+ expect { instance.return_nil(-1.0) }.to raise_error Rtype::ArgumentTypeError
673
+ instance.return_nil(2.0)
674
+
675
+ klass.send :rtype, :return_nil, [Flo > 0] => Any
676
+ expect { instance.return_nil(1) }.to raise_error Rtype::ArgumentTypeError
677
+ expect { instance.return_nil(0.0) }.to raise_error Rtype::ArgumentTypeError
678
+
679
+ klass.send :rtype, :return_nil, [Flo < 0] => Any
680
+ expect { instance.return_nil(-1) }.to raise_error Rtype::ArgumentTypeError
681
+ expect { instance.return_nil(0.0) }.to raise_error Rtype::ArgumentTypeError
682
+
683
+ klass.send :rtype, :return_nil, [Flo <= 0] => Any
684
+ expect { instance.return_nil(0) }.to raise_error Rtype::ArgumentTypeError
685
+ expect { instance.return_nil(1.0) }.to raise_error Rtype::ArgumentTypeError
686
+ end
687
+ end
688
+ end
689
+ end
690
+
691
+ describe 'Signature' do
692
+ describe 'check arguments' do
693
+ it 'nothing' do
694
+ klass.send :rtype, :sum, [] => Any
695
+ instance.sum(1, 2)
696
+ instance.sum(1, 2.0)
697
+ instance.sum(1.0, 2.0)
698
+ instance.sum("a", "b")
699
+ end
700
+
701
+ it 'two' do
702
+ klass.send :rtype, :sum, [Integer, Integer] => Any
703
+ expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
704
+ end
705
+
706
+ it 'two hash' do
707
+ klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
708
+ instance.two_args({k: 123}, {k: 456})
709
+ expect {
710
+ instance.two_args({k: 123}, {})
711
+ }.to raise_error Rtype::ArgumentTypeError
712
+ expect {
713
+ instance.two_args({k: 123}, 456)
714
+ }.to raise_error Rtype::ArgumentTypeError
715
+ expect {
716
+ instance.two_args({k: 123}, {k: "str"})
717
+ }.to raise_error Rtype::ArgumentTypeError
718
+ end
719
+
720
+ it 'one keyword argument' do
721
+ klass.send :rtype, :kwarg, {a: Float} => Any
722
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
723
+ end
724
+
725
+ it 'two keyword argument' do
726
+ klass.send :rtype, :sum_kwargs, {a: Integer, b: Float} => Any
727
+ expect {instance.sum_kwargs(a: 1, b: 2)}.to raise_error Rtype::ArgumentTypeError
728
+ end
729
+
730
+ it 'one with one keyword argument' do
731
+ klass.send :rtype, :arg_and_kwarg, [Integer, {b: Float}] => Any
732
+ expect {instance.arg_and_kwarg(1, b: 2)}.to raise_error Rtype::ArgumentTypeError
733
+ end
734
+
735
+ it 'one with two keyword argument' do
736
+ klass.send :rtype, :arg_and_kwargs, [Integer, {c: String, d: String}] => Any
737
+ expect {instance.arg_and_kwargs(1, b: 2, c: 3)}.to raise_error Rtype::ArgumentTypeError
738
+ end
739
+
740
+ it 'two with two keyword argument' do
741
+ klass.send :rtype, :args_and_kwargs, [Integer, Integer, {c: String, d: String}] => Any
742
+ expect {instance.args_and_kwargs(1, 2, c: 3, d: 4)}.to raise_error Rtype::ArgumentTypeError
743
+ end
744
+
745
+ it 'string key could not be used for keyword argument' do
746
+ expect {
747
+ klass.send :rtype, :kwarg, {'a' => Float} => Any
748
+ }.to raise_error Rtype::TypeSignatureError
749
+ end
750
+
751
+ it 'only symbol key is used for keyword argument' do
752
+ klass.send :rtype, :kwarg, {:a => Float} => Any
753
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
754
+ expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
755
+ end
756
+
757
+ context 'when hash is not last element' do
758
+ it 'is hash-type argument, not keyword argument' do
759
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
760
+ expect {
761
+ instance.return_arg({a: 123})
762
+ }.to raise_error Rtype::ArgumentTypeError
763
+ end
764
+ end
765
+
766
+ it 'hash-type argument and keyword argument' do
767
+ klass.send :rtype, :arg_and_kwarg, [{a: String}, {b: String}] => Any
768
+ expect {
769
+ instance.arg_and_kwarg({a: 123}, b: "str")
770
+ }.to raise_error Rtype::ArgumentTypeError
771
+ expect {
772
+ instance.arg_and_kwarg({a: "str"}, b: 123)
773
+ }.to raise_error Rtype::ArgumentTypeError
774
+ end
775
+ end
776
+
777
+ describe 'check return' do
778
+ it 'Any' do
779
+ klass.send :rtype, :return_arg, [] => Any
780
+ instance.return_arg("str")
781
+ end
782
+
783
+ it 'Array' do
784
+ klass.send :rtype, :return_arg, [] => [Integer, Float]
785
+ expect {instance.return_arg("str")}.to raise_error Rtype::ReturnTypeError
786
+ end
787
+ end
788
+
789
+ it 'check arguments and return value' do
790
+ klass.send :rtype, :return_nil, [Float] => nil
791
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
792
+ klass.send :rtype, :return_nil, [Integer] => Integer
793
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
794
+ end
795
+
796
+ describe 'wrong case' do
797
+ describe 'invalid type signature' do
798
+ it 'invalid arguments type signature' do
799
+ expect {
800
+ klass.send :rtype, :return_arg, Any => nil
801
+ }.to raise_error Rtype::TypeSignatureError
802
+ end
803
+ it 'invalid return type signature' do
804
+ expect {
805
+ klass.send :rtype, :return_arg, [] => 123
806
+ }.to raise_error Rtype::TypeSignatureError
807
+ end
808
+
809
+ it 'invalid type behavior in arguments' do
810
+ expect {
811
+ klass.send :rtype, :sum_kwargs, [{a: 123}, {b: Integer}] => Any
812
+ }.to raise_error Rtype::TypeSignatureError
813
+ expect {
814
+ klass.send :rtype, :return_arg, [123] => Any
815
+ }.to raise_error Rtype::TypeSignatureError
816
+ expect {
817
+ klass.send :rtype, :return_arg, ["abc"] => Any
818
+ }.to raise_error Rtype::TypeSignatureError
819
+ expect {
820
+ klass.send :rtype, :kwarg, {a: 123} => Any
821
+ }.to raise_error Rtype::TypeSignatureError
822
+ expect {
823
+ klass.send :rtype, :kwarg, {a: {b: 123}} => Any
824
+ }.to raise_error Rtype::TypeSignatureError
825
+ expect {
826
+ klass.send :rtype, :kwarg, {Object.new => Integer} => Any
827
+ }.to raise_error Rtype::TypeSignatureError
828
+ end
829
+
830
+ it 'invalid type behavior in return' do
831
+ expect {
832
+ klass.send :rtype, :return_arg, [] => 123
833
+ }.to raise_error Rtype::TypeSignatureError
834
+ expect {
835
+ klass.send :rtype, :return_arg, [] => "abc"
836
+ }.to raise_error Rtype::TypeSignatureError
837
+ end
838
+
839
+ context "with annotation mode" do
840
+ it 'works' do
841
+ expect {
842
+ class AnnotationTest
843
+ rtype [String, 123] => Any
844
+ def invalid_test(arg)
845
+ end
846
+ end
847
+ }.to raise_error Rtype::TypeSignatureError
848
+ end
849
+ end
850
+ end
851
+ end
852
+ end
853
+
854
+ describe "Implementation" do
855
+ it 'can be called before method definition' do
856
+ class TestClass
857
+ rtype :method_def, [Integer] => Any
858
+ def method_def(i)
859
+ end
860
+ end
861
+ expect {
862
+ TestClass.new.method_def("abc")
863
+ }.to raise_error Rtype::ArgumentTypeError
864
+ end
865
+
866
+ it 'can be called after method definition' do
867
+ class TestClass
868
+ def method_def_2(i)
869
+ end
870
+ rtype :method_def_2, [Integer] => Any
871
+ end
872
+ expect {
873
+ TestClass.new.method_def_2("abc")
874
+ }.to raise_error Rtype::ArgumentTypeError
875
+ end
876
+
877
+ it 'method name can be both symbol and string' do
878
+ class TestClass
879
+ rtype 'method_def_3', [Integer] => Any
880
+ def method_def_3(i)
881
+ end
882
+ rtype :method_def_4, [Integer] => Any
883
+ def method_def_4(i)
884
+ end
885
+ end
886
+ expect {
887
+ TestClass.new.method_def_3("abc")
888
+ }.to raise_error Rtype::ArgumentTypeError
889
+ expect {
890
+ TestClass.new.method_def_4("abc")
891
+ }.to raise_error Rtype::ArgumentTypeError
892
+ end
893
+
894
+ describe 'method visibility works' do
895
+ it 'protected' do
896
+ klass.send :rtype, :protected_func, [] => Any
897
+ expect {instance.protected_func}.to raise_error NoMethodError
898
+ end
899
+ it 'private' do
900
+ klass.send :rtype, :private_func, [] => Any
901
+ expect {instance.private_func}.to raise_error NoMethodError
902
+ end
903
+ it 'public' do
904
+ klass.send :rtype, :public_func, [] => Any
905
+ instance.public_func
906
+ end
907
+ end
908
+
909
+ context 'with empty argument signature' do
910
+ it 'accept any arguments' do
911
+ klass.send :rtype, :three_args, [] => Any
912
+ instance.three_args("abc", 123, 456)
913
+ end
914
+ end
915
+
916
+ context 'when args length is more than arg signature length' do
917
+ it 'type checking ignore rest args' do
918
+ klass.send :rtype, :three_args, [String] => Any
919
+ instance.three_args("abc", 123, 456)
920
+ end
921
+ end
922
+
923
+ context 'when keyword args contain a key not configured to rtype' do
924
+ it 'type checking ignore the key' do
925
+ klass.send :rtype, :three_kwargs, {a: String} => Any
926
+ instance.three_kwargs(a: "abc", b: 123, c: 456)
927
+ end
928
+ end
929
+
930
+ context 'when hash type argument contain a key not configured to rtype' do
931
+ it 'raises error' do
932
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
933
+ expect {
934
+ instance.return_arg({a: "str", b: "str"})
935
+ }.to raise_error Rtype::ArgumentTypeError
936
+ end
937
+ end
938
+
939
+ it "One rtype annotation affect only one method" do
940
+ class AnnotationTest
941
+ rtype [String] => Any
942
+ def one(str)
943
+ end
944
+
945
+ def two(str)
946
+ end
947
+ end
948
+ expect {
949
+ AnnotationTest.new.one(123)
950
+ }.to raise_error Rtype::ArgumentTypeError
951
+ AnnotationTest.new.two(123)
952
+ end
953
+
954
+ it "One rtype annotation affect only one method, regardless of instance method or class method" do
955
+ class AnnotationTest2
956
+ rtype [String] => Any
957
+ def self.static_one(str)
958
+ end
959
+
960
+ def inst_one(str)
961
+ end
962
+
963
+ def self.static_two(str)
964
+ end
965
+ end
966
+ expect {
967
+ AnnotationTest2::static_one(123)
968
+ }.to raise_error Rtype::ArgumentTypeError
969
+ AnnotationTest2.new.inst_one(123)
970
+ AnnotationTest2::static_two(123)
971
+ end
972
+
973
+ context 'when rtype signature duplicated' do
974
+ it 'the latest have priority' do
975
+ class PriorityTest1
976
+ rtype :test_priority, [String] => Any
977
+ def test_priority(arg)
978
+ end
979
+ rtype :test_priority, [Integer] => Any
980
+ end
981
+
982
+ PriorityTest1.new.test_priority(1)
983
+ expect { PriorityTest1.new.test_priority("str") }.to raise_error Rtype::ArgumentTypeError
984
+ end
985
+
986
+ it 'annotation mode have priority in contemporaneous signatures' do
987
+ class PriorityTest2
988
+ rtype :test_priority, [String] => Any
989
+ rtype [Integer] => Any
990
+ def test_priority(arg)
991
+ end
992
+ end
993
+
994
+ PriorityTest2.new.test_priority(1)
995
+ expect { PriorityTest2.new.test_priority("str") }.to raise_error Rtype::ArgumentTypeError
996
+ end
997
+ end
998
+ end
999
+
1000
+ describe "Call Rtype`s static method directly" do
1001
+ it 'Rtype::define_typed_method' do
1002
+ Rtype::define_typed_method klass, :return_arg, [String] => Any
1003
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
1004
+ end
1005
+
1006
+ it 'Rtype::define_typed_accessor' do
1007
+ Rtype::define_typed_accessor klass, :value, String
1008
+ expect { instance.value = 123 }.to raise_error Rtype::ArgumentTypeError
1009
+ expect { instance.value }.to raise_error Rtype::ReturnTypeError
1010
+ end
1011
+
1012
+ it 'Rtype::valid?' do
1013
+ expect(
1014
+ Rtype::valid?(String, "str")
1015
+ ).to be true
1016
+ expect(
1017
+ Rtype::valid?(Integer, "str")
1018
+ ).to be false
1019
+ expect {
1020
+ Rtype::valid?("Invalid type behavior", "Test Value")
1021
+ }.to raise_error Rtype::TypeSignatureError
1022
+ end
1023
+
1024
+ it 'Rtype::assert_arguments_type' do
1025
+ expect {
1026
+ Rtype::assert_arguments_type([Integer, String], [123, 123])
1027
+ }.to raise_error Rtype::ArgumentTypeError
1028
+ end
1029
+
1030
+ it 'Rtype::assert_arguments_type_with_keywords' do
1031
+ expect {
1032
+ Rtype::assert_arguments_type_with_keywords([Integer, String], [123, "abc"], {arg: String}, {arg: 123})
1033
+ }.to raise_error Rtype::ArgumentTypeError
1034
+ end
1035
+
1036
+ it 'Rtype::assert_return_type' do
1037
+ expect {
1038
+ Rtype::assert_return_type nil, "No nil"
1039
+ }.to raise_error Rtype::ReturnTypeError
1040
+ end
1041
+
1042
+ it 'Rtype::assert_valid_type_sig' do
1043
+ Rtype::assert_valid_type_sig([Integer, String] => Any)
1044
+ expect {
1045
+ Rtype::assert_valid_type_sig([Integer, String])
1046
+ }.to raise_error Rtype::TypeSignatureError
1047
+ end
1048
+
1049
+ it 'Rtype::assert_valid_arguments_type_sig' do
1050
+ Rtype::assert_valid_arguments_type_sig([Integer, String])
1051
+ expect {
1052
+ Rtype::assert_valid_arguments_type_sig("[Integer, String]")
1053
+ }.to raise_error Rtype::TypeSignatureError
1054
+ end
1055
+
1056
+ it 'Rtype::assert_valid_argument_type_sig_element' do
1057
+ Rtype::assert_valid_argument_type_sig_element(Integer)
1058
+ expect {
1059
+ Rtype::assert_valid_argument_type_sig_element("Integer")
1060
+ }.to raise_error Rtype::TypeSignatureError
1061
+ end
1062
+
1063
+ it 'Rtype::assert_valid_return_type_sig' do
1064
+ Rtype::assert_valid_return_type_sig(Integer)
1065
+ expect {
1066
+ Rtype::assert_valid_return_type_sig("Integer")
1067
+ }.to raise_error Rtype::TypeSignatureError
1068
+ end
1069
+ end
1070
+ end