rtype 0.6.8-java

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.
@@ -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