rtype 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,408 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe Rtype do
4
+ let(:klass) do
5
+ Class.new do
6
+ def return_arg(obj)
7
+ obj
8
+ end
9
+
10
+ def return_nil(obj)
11
+ nil
12
+ end
13
+
14
+ def sum(a, b)
15
+ a + b
16
+ end
17
+
18
+ def kwarg(a:)
19
+ a
20
+ end
21
+
22
+ def sum_kwargs(a:, b:)
23
+ a + b
24
+ end
25
+
26
+ def arg_and_kwarg(a, b:)
27
+ end
28
+
29
+ def arg_and_kwargs(a, b:, c:)
30
+ end
31
+
32
+ def args_and_kwargs(a, b, c:, d:)
33
+ end
34
+
35
+ protected
36
+ def protected_func
37
+ end
38
+
39
+ private
40
+ def private_func
41
+ end
42
+ end
43
+ end
44
+
45
+ let(:instance) do
46
+ klass.new
47
+ end
48
+
49
+ describe 'Kernel#rtype' do
50
+ it "outside of module" do
51
+ rtype :test_args, [String] => Any
52
+ def test_args(str)
53
+ end
54
+
55
+ expect {test_args 123}.to raise_error Rtype::ArgumentTypeError
56
+
57
+ rtype :test_return, [] => String
58
+ def test_return
59
+ 369
60
+ end
61
+
62
+ expect {test_return}.to raise_error Rtype::ReturnTypeError
63
+ end
64
+
65
+ it "in module" do
66
+ class TestClass
67
+ rtype :test_args, [String] => Any
68
+ def test_args(str)
69
+ end
70
+ end
71
+
72
+ expect {TestClass.new.test_args 123}.to raise_error Rtype::ArgumentTypeError
73
+
74
+ class TestClass
75
+ rtype :test_return, [] => String
76
+ def test_return
77
+ 369
78
+ end
79
+ end
80
+
81
+ expect {TestClass.new.test_return}.to raise_error Rtype::ReturnTypeError
82
+ end
83
+ end
84
+
85
+ it "Kernel#rtype_self" do
86
+ class TestClass
87
+ rtype_self :static_test_args, [String] => Any
88
+ def self.static_test_args(str)
89
+ end
90
+ end
91
+
92
+ expect {TestClass::static_test_args 123}.to raise_error Rtype::ArgumentTypeError
93
+
94
+ class TestClass
95
+ rtype_self :static_test_return, [] => String
96
+ def self.static_test_return
97
+ 369
98
+ end
99
+ end
100
+
101
+ expect {TestClass::static_test_return}.to raise_error Rtype::ReturnTypeError
102
+ end
103
+
104
+ describe 'Test type behaviors' do
105
+ describe 'Module' do
106
+ it "is right" do
107
+ klass.send :rtype, :return_arg, [String] => Any
108
+ instance.return_arg("This is a string!")
109
+ end
110
+ it "is wrong" do
111
+ klass.send :rtype, :return_arg, [String] => Any
112
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
113
+ end
114
+ it "is wrong result" do
115
+ klass.send :rtype, :return_nil, [Any] => String
116
+ expect {instance.return_nil("This is a string!")}.to raise_error Rtype::ReturnTypeError
117
+ end
118
+ end
119
+
120
+ describe 'Symbol' do
121
+ it "is right" do
122
+ klass.send :rtype, :return_arg, [:to_i] => Any
123
+ instance.return_arg(123)
124
+ end
125
+ it "is wrong args" do
126
+ klass.send :rtype, :return_arg, [:to_i] => Any
127
+ expect {instance.return_arg(true)}.to raise_error Rtype::ArgumentTypeError
128
+ end
129
+ it "is wrong result" do
130
+ klass.send :rtype, :return_nil, [Any] => :odd?
131
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
132
+ end
133
+ end
134
+
135
+ describe 'Regexp' do
136
+ it "is right" do
137
+ klass.send :rtype, :return_arg, [/cuba/] => Any
138
+ instance.return_arg("cuba")
139
+ end
140
+ it "is wrong args" do
141
+ klass.send :rtype, :return_arg, [/cuba/] => Any
142
+ expect {instance.return_arg("brazil")}.to raise_error Rtype::ArgumentTypeError
143
+ end
144
+ it "is wrong result" do
145
+ klass.send :rtype, :return_nil, [Any] => /cuba/
146
+ expect {instance.return_nil("cuba")}.to raise_error Rtype::ReturnTypeError
147
+ end
148
+ end
149
+
150
+ describe 'Range' do
151
+ it "is right" do
152
+ klass.send :rtype, :return_arg, [1..10] => Any
153
+ instance.return_arg(5)
154
+ end
155
+ it "is wrong args" do
156
+ klass.send :rtype, :return_arg, [1..10] => Any
157
+ expect {instance.return_arg(1001)}.to raise_error Rtype::ArgumentTypeError
158
+ end
159
+ it "is wrong result" do
160
+ klass.send :rtype, :return_nil, [Any] => 1..10
161
+ expect {instance.return_nil(5)}.to raise_error Rtype::ReturnTypeError
162
+ end
163
+ end
164
+
165
+ describe 'Array' do
166
+ it "is right" do
167
+ klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
168
+ instance.return_arg([123, 456])
169
+ end
170
+ it "is wrong args" do
171
+ klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
172
+ expect {instance.return_arg([123, true])}.to raise_error Rtype::ArgumentTypeError
173
+ end
174
+ it "is wrong result" do
175
+ klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
176
+ expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
177
+ end
178
+ end
179
+
180
+ describe 'Proc' do
181
+ it "is right" do
182
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
183
+ instance.return_arg(123)
184
+ end
185
+ it "is wrong args" do
186
+ klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
187
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
188
+ end
189
+ it "is wrong result" do
190
+ klass.send :rtype, :return_nil, [Any] => ->(arg){!arg.nil?}
191
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
192
+ end
193
+ end
194
+
195
+ describe 'true' do
196
+ it "is right" do
197
+ klass.send :rtype, :return_arg, [true] => Any
198
+ instance.return_arg(123)
199
+ end
200
+ it "is wrong args" do
201
+ klass.send :rtype, :return_arg, [true] => Any
202
+ expect {instance.return_arg(nil)}.to raise_error Rtype::ArgumentTypeError
203
+ end
204
+ it "is wrong result" do
205
+ klass.send :rtype, :return_nil, [Any] => true
206
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
207
+ end
208
+ end
209
+
210
+ describe 'false' do
211
+ it "is right" do
212
+ klass.send :rtype, :return_arg, [false] => Any
213
+ instance.return_arg(nil)
214
+ end
215
+ it "is wrong args" do
216
+ klass.send :rtype, :return_arg, [false] => Any
217
+ expect {instance.return_arg(123)}.to raise_error Rtype::ArgumentTypeError
218
+ end
219
+ it "is wrong result" do
220
+ klass.send :rtype, :return_arg, [Any] => false
221
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
222
+ end
223
+ end
224
+
225
+ describe 'nil' do
226
+ it "is only for return" do
227
+ klass.send :rtype, :return_nil, [] => nil
228
+ instance.return_nil(123)
229
+
230
+ klass.send :rtype, :return_arg, [] => nil
231
+ expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
232
+ end
233
+ it "could not be used for args" do
234
+ expect {
235
+ klass.send :rtype, :return_arg, [nil] => Any
236
+ }.to raise_error Rtype::TypeSignatureError
237
+ end
238
+ end
239
+ end
240
+
241
+ describe 'Signature' do
242
+ describe 'check arguments' do
243
+ it 'nothing' do
244
+ klass.send :rtype, :sum, [] => Any
245
+ instance.sum(1, 2)
246
+ instance.sum(1, 2.0)
247
+ instance.sum(1.0, 2.0)
248
+ instance.sum("a", "b")
249
+ end
250
+
251
+ it 'two' do
252
+ klass.send :rtype, :sum, [Integer, Integer] => Any
253
+ expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
254
+ end
255
+
256
+ it 'one keyword argument' do
257
+ klass.send :rtype, :kwarg, {a: Float} => Any
258
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
259
+ end
260
+
261
+ it 'two keyword argument' do
262
+ klass.send :rtype, :sum_kwargs, {a: Integer, b: Float} => Any
263
+ expect {instance.sum_kwargs(a: 1, b: 2)}.to raise_error Rtype::ArgumentTypeError
264
+ end
265
+
266
+ it 'one with one keyword argument' do
267
+ klass.send :rtype, :arg_and_kwarg, [Integer, {b: Float}] => Any
268
+ expect {instance.arg_and_kwarg(1, b: 2)}.to raise_error Rtype::ArgumentTypeError
269
+ end
270
+
271
+ it 'one with two keyword argument' do
272
+ klass.send :rtype, :arg_and_kwargs, [Integer, {c: String, d: String}] => Any
273
+ expect {instance.arg_and_kwargs(1, b: 2, c: 3)}.to raise_error Rtype::ArgumentTypeError
274
+ end
275
+
276
+ it 'two with two keyword argument' do
277
+ klass.send :rtype, :args_and_kwargs, [Integer, Integer, {c: String, d: String}] => Any
278
+ expect {instance.args_and_kwargs(1, 2, c: 3, d: 4)}.to raise_error Rtype::ArgumentTypeError
279
+ end
280
+
281
+ it 'string key could not be used for keyword argument' do
282
+ expect {
283
+ klass.send :rtype, :kwarg, {'a' => Float} => Any
284
+ }.to raise_error Rtype::TypeSignatureError
285
+ end
286
+
287
+ it 'only symbol key is used for keyword argument' do
288
+ klass.send :rtype, :kwarg, {:a => Float} => Any
289
+ expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
290
+ expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
291
+ end
292
+ end
293
+
294
+ describe 'check return' do
295
+ it 'Any' do
296
+ klass.send :rtype, :return_arg, [] => Any
297
+ instance.return_arg("str")
298
+ end
299
+
300
+ it 'Array (tuple)' do
301
+ klass.send :rtype, :return_arg, [] => [Integer, Float]
302
+ expect {instance.return_arg([1, 2])}.to raise_error Rtype::ReturnTypeError
303
+ end
304
+ end
305
+
306
+ it 'check arguments and return value' do
307
+ klass.send :rtype, :return_nil, [Float] => nil
308
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
309
+ klass.send :rtype, :return_nil, [Integer] => Integer
310
+ expect {instance.return_nil(123)}.to raise_error Rtype::ReturnTypeError
311
+ end
312
+
313
+ describe 'wrong case' do
314
+ describe 'invalid signature form' do
315
+ it 'invalid argument signature' do
316
+ expect {
317
+ klass.send :rtype, :return_arg, Any => nil
318
+ }.to raise_error Rtype::TypeSignatureError
319
+ end
320
+ it 'invalid return signature' do
321
+ expect {
322
+ klass.send :rtype, :return_arg, [] => {}
323
+ }.to raise_error Rtype::TypeSignatureError
324
+ end
325
+
326
+ it 'invalid type behavior in arguments' do
327
+ expect {
328
+ klass.send :rtype, :sum_kwargs, [{a: Integer}, {b: Integer}] => Any
329
+ }.to raise_error Rtype::TypeSignatureError
330
+ expect {
331
+ klass.send :rtype, :return_arg, [123] => Any
332
+ }.to raise_error Rtype::TypeSignatureError
333
+ expect {
334
+ klass.send :rtype, :return_arg, ["abc"] => Any
335
+ }.to raise_error Rtype::TypeSignatureError
336
+ expect {
337
+ klass.send :rtype, :kwarg, {a: 123} => Any
338
+ }.to raise_error Rtype::TypeSignatureError
339
+ expect {
340
+ klass.send :rtype, :kwarg, {a: {b: Integer}} => Any
341
+ }.to raise_error Rtype::TypeSignatureError
342
+ expect {
343
+ klass.send :rtype, :kwarg, {Object.new => Integer} => Any
344
+ }.to raise_error Rtype::TypeSignatureError
345
+ end
346
+
347
+ it 'invalid type behavior in return' do
348
+ expect {
349
+ klass.send :rtype, :return_arg, [] => 123
350
+ }.to raise_error Rtype::TypeSignatureError
351
+ expect {
352
+ klass.send :rtype, :return_arg, [] => "abc"
353
+ }.to raise_error Rtype::TypeSignatureError
354
+ end
355
+ end
356
+ end
357
+ end
358
+
359
+ describe "Implementation" do
360
+ it 'can be called before method definition' do
361
+ class TestClass
362
+ rtype :method_def, [Integer] => Any
363
+ def method_def(i)
364
+ end
365
+ end
366
+ expect {
367
+ TestClass.new.method_def("abc")
368
+ }.to raise_error Rtype::ArgumentTypeError
369
+ end
370
+
371
+ it 'can be called after method definition' do
372
+ class TestClass
373
+ def method_def_2(i)
374
+ end
375
+ rtype :method_def_2, [Integer] => Any
376
+ end
377
+ expect {
378
+ TestClass.new.method_def_2("abc")
379
+ }.to raise_error Rtype::ArgumentTypeError
380
+ end
381
+
382
+ it 'method name can be both symbol and string' do
383
+ class TestClass
384
+ rtype 'method_def_3', [Integer] => Any
385
+ def method_def_3(i)
386
+ end
387
+ rtype :method_def_4, [Integer] => Any
388
+ def method_def_4(i)
389
+ end
390
+ end
391
+ expect {
392
+ TestClass.new.method_def_3("abc")
393
+ }.to raise_error Rtype::ArgumentTypeError
394
+ expect {
395
+ TestClass.new.method_def_4("abc")
396
+ }.to raise_error Rtype::ArgumentTypeError
397
+ end
398
+
399
+ describe 'method visibility works' do
400
+ it 'protected' do
401
+ expect {instance.protected_func}.to raise_error NoMethodError
402
+ end
403
+ it 'private' do
404
+ expect {instance.private_func}.to raise_error NoMethodError
405
+ end
406
+ end
407
+ end
408
+ end
@@ -0,0 +1,3 @@
1
+ # $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require_relative '../lib/rtype'
3
+ require 'rspec'
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rtype
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Sputnik Gugja
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '10.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Ruby with type
42
+ email:
43
+ - sputnikgugja@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - Gemfile
49
+ - LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - benchmark/benchmark.rb
53
+ - lib/rtype.rb
54
+ - lib/rtype/argument_type_error.rb
55
+ - lib/rtype/behavior.rb
56
+ - lib/rtype/behavior/and.rb
57
+ - lib/rtype/behavior/base.rb
58
+ - lib/rtype/behavior/nilable.rb
59
+ - lib/rtype/behavior/not.rb
60
+ - lib/rtype/behavior/or.rb
61
+ - lib/rtype/behavior/xor.rb
62
+ - lib/rtype/core_ext.rb
63
+ - lib/rtype/return_type_error.rb
64
+ - lib/rtype/type_signature.rb
65
+ - lib/rtype/type_signature_error.rb
66
+ - lib/rtype/version.rb
67
+ - spec/rtype_spec.rb
68
+ - spec/spec_helper.rb
69
+ homepage: https://github.com/sputnikgugja/rtype
70
+ licenses:
71
+ - MIT
72
+ metadata: {}
73
+ post_install_message:
74
+ rdoc_options: []
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '2.1'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ requirements: []
88
+ rubyforge_project:
89
+ rubygems_version: 2.4.8
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: Ruby with type
93
+ test_files:
94
+ - spec/rtype_spec.rb
95
+ - spec/spec_helper.rb