rtype-legacy-java 0.0.2

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