rtype 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 580a93433f2e77fc81b6a9abd7b14d390952f05d
4
- data.tar.gz: 78f18ddfed8634652bc9c0da161dec708db99293
3
+ metadata.gz: c4bad8e7cdc12a3c4a598e806553fd89c184c212
4
+ data.tar.gz: 67576b9e8839a9f1988ee4f561cb0474824ecb84
5
5
  SHA512:
6
- metadata.gz: e6df637fa65774fcf9addcf06dc4b8fc526587e1cfe448229644b8756f17129f603086a90a68d16422900f5b20020927bd67e403f8550ffb1823b4484d365d39
7
- data.tar.gz: 653c366459022762cf1e5ded44eac4452365b6549f23efad8c1f875eb785ed14d56788d72efe222d6a76906367f908b7594f22c6372707c931079d2af104a5bb
6
+ metadata.gz: 4b82873431c88b2811b9ee34bdd84a3f23e683cbf4baaba9c57da29954b34869a3739db623496f0e07af92b8eab5750d10d523b3e93c3cf91080a5a36c5dd5fb
7
+ data.tar.gz: 29a5f2356be7ed7637841a0a240689cd11f7d19f73ce5b5447c8ec99bb497ee931e2c48706048efacffe4d15c7a73619b184b49e53bbb9c920dfd328905e4954
data/README.md CHANGED
@@ -31,15 +31,16 @@ Test::invert(state: 0)
31
31
 
32
32
  ## Requirements
33
33
  - Ruby >= 2.1
34
- - MRI or RBX
34
+ - MRI
35
35
  - If C native extension is used, otherwise it is not required
36
36
  - JRuby
37
37
  - If Java extension is used, otherwise it is not required
38
38
 
39
39
  ## Features
40
- - Provide type checking for argument and return
40
+ - Provide type checking for arguments and return
41
41
  - Support type checking for [keyword argument](#keyword-argument)
42
42
  - [Type checking for array elements](#array)
43
+ - [Type checking for hash elements](#hash)
43
44
  - [Duck typing](#duck-typing)
44
45
  - Custom type behavior
45
46
 
@@ -54,7 +55,7 @@ require 'rtype'
54
55
  ### Native extension
55
56
  Rtype itself is pure-ruby gem. but you can make it more faster by using native extension.
56
57
 
57
- #### Native extension for MRI, RBX
58
+ #### Native extension for MRI
58
59
  Just run
59
60
  ```ruby
60
61
  gem install rtype-native
@@ -96,6 +97,18 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
96
97
  - Of course, nested array works
97
98
  - Example: [Array](#array)
98
99
  - This can be used as a tuple
100
+ - `Hash`
101
+ - Value must be an hash
102
+ - Each of value’s elements must be valid
103
+ - Value's key list must be equal to the hash's key list
104
+ - **String** key is **different** from **symbol** key
105
+ - The type signature could not be positioned at last index
106
+ - `[{}]` is **not** hash type argument. it is keyword argument because its position is last
107
+ - `[{}, {}]` is empty hash type argument (first) and one empty keyword argument (second)
108
+ - `[{}, {}, {}]` is two empty hash type argument (first, second) and empty keyword argument (last)
109
+ - `{}` is keyword argument. non-keyword arguments must be in array.
110
+ - Of course, nested hash works
111
+ - Example: [Hash](#hash)
99
112
  - `Proc`
100
113
  - Value must return a truthy value for this proc
101
114
  - `true`
@@ -106,15 +119,36 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
106
119
  - Only available for **return type**. void return type in other languages
107
120
  - Special Behaviors
108
121
  - `Rtype::and(*types)` : Ensure value is valid for all the types
109
- - It also can be used as `Rtype::Behavior::And[*types]` or `include Rtype::Behavior; And[...]`
122
+ - `Rtype::and(*types)`
123
+ - `Rtype::Behavior::And[*types]`
124
+ - `include Rtype::Behavior; And[...]`
125
+ - `obj.and(*others)` (core extension)
126
+
110
127
  - `Rtype::or(*types)` : Ensure value is valid for at least one of the types
111
- - It also can be used as `Rtype::Behavior::Or[*types]` or `include Rtype::Behavior; Or[...]`
128
+ - `Rtype::or(*types)`
129
+ - `Rtype::Behavior::Or[*types]`
130
+ - `include Rtype::Behavior; Or[...]`
131
+ - `obj.or(*others)` (core extension)
132
+
112
133
  - `Rtype::xor(*types)` : Ensure value is valid for only one of the types
113
- - It also can be used as `Rtype::Behavior::Xor[*types]` or `include Rtype::Behavior; Xor[...]`
134
+ - `Rtype::xor(*types)`
135
+ - `Rtype::Behavior::Xor[*types]`
136
+ - `include Rtype::Behavior; Xor[...]`
137
+ - `obj.xor(*others)` (core extension)
138
+
114
139
  - `Rtype::not(*types)` : Ensure value is not valid for all the types
115
- - It also can be used as `Rtype::Behavior::Not[*types]` or `include Rtype::Behavior; Not[...]`
140
+ - `Rtype::not(*types)`
141
+ - `Rtype::Behavior::Not[*types]`
142
+ - `include Rtype::Behavior; Not[...]`
143
+ - `obj.not` (core extension)
144
+
116
145
  - `Rtype::nilable(type)` : Ensure value can be nil
117
- - It also can be used as `Rtype::Behavior::Nilable[type]` or `include Rtype::Behavior; Nilable[...]`
146
+ - `Rtype::nilable(type)`
147
+ - `Rtype::Behavior::Nilable[type]`
148
+ - `include Rtype::Behavior; Nilable[...]`
149
+ - `obj.nilable` (core extension)
150
+ - `obj.or_nil` (core extension)
151
+
118
152
  - You can create custom behavior by extending `Rtype::Behavior::Base`
119
153
 
120
154
  ### Examples
@@ -219,6 +253,38 @@ func [1]
219
253
  func [1, 2] # Your location is (1, 2). I will look for you. I will find you
220
254
  ```
221
255
 
256
+ #### Hash
257
+ ```ruby
258
+ # last hash element is keyword arguments
259
+ rtype :func, [{msg: String}, {}] => Any
260
+ def func(hash)
261
+ puts hash[:msg]
262
+ end
263
+
264
+ # last hash is keyword arguments
265
+ func({}, {})
266
+ # (Rtype::ArgumentTypeError) for 1st argument:
267
+ # Expected {} to be an hash with 1 elements:
268
+ # - msg : Expected nil to be a String
269
+
270
+ func({msg: 123}, {})
271
+ # (Rtype::ArgumentTypeError) for 1st argument:
272
+ # Expected {:msg=>123} to be an hash with 1 elements:
273
+ # - msg : Expected 123 to be a String
274
+
275
+ func({msg: "hello", key: 'value'}, {})
276
+ # (Rtype::ArgumentTypeError) for 1st argument:
277
+ # Expected {:msg=>"hello", :key=>"value"} to be an hash with 1 elements:
278
+ # - msg : Expected "hello" to be a String
279
+
280
+ func({"msg" => "hello hash"}, {})
281
+ # (Rtype::ArgumentTypeError) for 1st argument:
282
+ # Expected {"msg"=>"hello hash"} to be an hash with 1 elements:
283
+ # - msg : Expected nil to be a String
284
+
285
+ func({msg: "hello hash"}, {}) # hello hash
286
+ ```
287
+
222
288
  #### rtype with attr_accessor
223
289
  `rtype_accessor`
224
290
 
@@ -250,7 +316,9 @@ Example.new.value
250
316
  require 'rtype'
251
317
 
252
318
  class Example
253
- rtype :and_test, [Rtype::and(String, :func)] => Any
319
+ rtype :and_test, [String.and(:func)] => Any
320
+ # also works:
321
+ # rtype :and_test, [Rtype::and(String, :func)] => Any
254
322
  def and_test(arg)
255
323
  end
256
324
  end
@@ -344,7 +412,7 @@ end
344
412
  say "Hello" # Hello
345
413
  ```
346
414
 
347
- #### Static method
415
+ #### Static(singleton) method
348
416
  Use `rtype_self`
349
417
 
350
418
  ```ruby
@@ -0,0 +1,22 @@
1
+ class Object
2
+ def and(*others)
3
+ ::Rtype::and(self, *others)
4
+ end
5
+
6
+ def nilable
7
+ ::Rtype::nilable(self)
8
+ end
9
+ alias_method :or_nil, :nilable
10
+
11
+ def not
12
+ ::Rtype::not(self)
13
+ end
14
+
15
+ def or(*others)
16
+ ::Rtype::or(self, *others)
17
+ end
18
+
19
+ def xor(*others)
20
+ ::Rtype::xor(self, *others)
21
+ end
22
+ end
@@ -15,7 +15,7 @@ module Rtype
15
15
  end
16
16
  end
17
17
 
18
- def self.nilable(*args)
18
+ def nilable(*args)
19
19
  Behavior::Nilable[*args]
20
20
  end
21
21
  end
@@ -18,7 +18,7 @@ module Rtype
18
18
  end
19
19
  end
20
20
 
21
- def self.not(*args)
21
+ def not(*args)
22
22
  Behavior::Not[*args]
23
23
  end
24
24
  end
@@ -18,7 +18,7 @@ module Rtype
18
18
  end
19
19
  end
20
20
 
21
- def self.or(*args)
21
+ def or(*args)
22
22
  Behavior::Or[*args]
23
23
  end
24
24
  end
@@ -19,7 +19,7 @@ module Rtype
19
19
  end
20
20
  end
21
21
 
22
- def self.xor(*args)
22
+ def xor(*args)
23
23
  Behavior::Xor[*args]
24
24
  end
25
25
  end
@@ -8,4 +8,5 @@ require_relative 'behavior/or'
8
8
  require_relative 'behavior/and'
9
9
  require_relative 'behavior/xor'
10
10
  require_relative 'behavior/not'
11
- require_relative 'behavior/nilable'
11
+ require_relative 'behavior/nilable'
12
+ require_relative 'behavior/core_ext'
data/lib/rtype/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Rtype
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.4.0".freeze
3
3
  end
data/lib/rtype.rb CHANGED
@@ -40,7 +40,7 @@ module Rtype
40
40
  return_sig = el[1]
41
41
 
42
42
  if arg_sig.is_a?(Array)
43
- expected_args = arg_sig
43
+ expected_args = arg_sig.dup
44
44
  if expected_args.last.is_a?(Hash)
45
45
  expected_kwargs = expected_args.pop
46
46
  else
@@ -51,12 +51,12 @@ module Rtype
51
51
  expected_kwargs = arg_sig
52
52
  end
53
53
 
54
- expected_args.each { |e| valid?(e, nil) }
54
+ expected_args.each { |e| check_valid_argument_type_sig(e) }
55
55
  if expected_kwargs.keys.any? { |e| !e.is_a?(Symbol) }
56
56
  raise TypeSignatureError, "Invalid type signature: keyword arguments contain non-symbol key"
57
57
  end
58
- expected_kwargs.each_value { |e| valid?(e, nil) }
59
- valid?(return_sig, nil) unless return_sig.nil?
58
+ expected_kwargs.each_value { |e| check_valid_argument_type_sig(e) }
59
+ check_valid_return_type_sig(return_sig)
60
60
 
61
61
  sig = TypeSignature.new
62
62
  sig.argument_type = arg_sig
@@ -123,7 +123,7 @@ module Rtype
123
123
  when Array
124
124
  if value.is_a?(Array)
125
125
  arr = expected.map.with_index do |e, idx|
126
- if e.is_a?(Array)
126
+ if e.is_a?(Array) || e.is_a?(Hash)
127
127
  "- [#{idx}] index : {\n" + type_error_message(e, value[idx]) + "\n}"
128
128
  else
129
129
  "- [#{idx}] index : " + type_error_message(e, value[idx])
@@ -133,6 +133,20 @@ module Rtype
133
133
  else
134
134
  "Expected #{value.inspect} to be an array"
135
135
  end
136
+ when Hash
137
+ if value.is_a?(Hash)
138
+ arr = []
139
+ expected.each do |k, v|
140
+ if v.is_a?(Array) || v.is_a?(Hash)
141
+ arr << "- #{k} : {\n" + type_error_message(v, value[k]) + "\n}"
142
+ else
143
+ arr << "- #{k} : " + type_error_message(v, value[k])
144
+ end
145
+ end
146
+ "Expected #{value.inspect} to be an hash with #{expected.length} elements:\n" + arr.join("\n")
147
+ else
148
+ "Expected #{value.inspect} to be an hash"
149
+ end
136
150
  when Proc
137
151
  "Expected #{value.inspect} to return a truthy value for proc #{expected}"
138
152
  when true
@@ -166,7 +180,34 @@ private
166
180
  end
167
181
  nil
168
182
  end
169
-
183
+
184
+ def check_valid_argument_type_sig(sig)
185
+ case sig
186
+ when Rtype::Behavior::Base
187
+ when Module
188
+ when Symbol
189
+ when Regexp
190
+ when Range
191
+ when Array
192
+ sig.each do |e|
193
+ check_valid_argument_type_sig(e)
194
+ end
195
+ when Hash
196
+ sig.each_value do |e|
197
+ check_valid_argument_type_sig(e)
198
+ end
199
+ when Proc
200
+ when true
201
+ when false
202
+ else
203
+ raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{sig}"
204
+ end
205
+ end
206
+
207
+ def check_valid_return_type_sig(sig)
208
+ check_valid_argument_type_sig(sig) unless sig.nil?
209
+ end
210
+
170
211
  public
171
212
  unless respond_to?(:valid?)
172
213
  # validate argument type
@@ -180,6 +221,10 @@ public
180
221
  !!(expected =~ value.to_s)
181
222
  when Range
182
223
  expected.include?(value)
224
+ when Hash
225
+ return false unless value.is_a?(Hash)
226
+ return false unless expected.keys == value.keys
227
+ expected.all? { |k, v| valid?(v, value[k]) }
183
228
  when Array
184
229
  return false unless value.is_a?(Array)
185
230
  return false unless expected.length == value.length
@@ -207,7 +252,7 @@ public
207
252
  value = args[i]
208
253
  unless expected.nil?
209
254
  unless valid?(expected, value)
210
- raise ArgumentTypeError, "for #{(i+1).ordinalize} argument:\n" + type_error_message(expected, value)
255
+ raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
211
256
  end
212
257
  end
213
258
  end
@@ -222,7 +267,7 @@ public
222
267
  value = args[i]
223
268
  unless expected.nil?
224
269
  unless valid?(expected, value)
225
- raise ArgumentTypeError, "#{arg_message(idx)}\n" + type_error_message(expected, value)
270
+ raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
226
271
  end
227
272
  end
228
273
  end
data/spec/rtype_spec.rb CHANGED
@@ -13,6 +13,9 @@ describe Rtype do
13
13
  obj
14
14
  end
15
15
 
16
+ def two_args(a, b)
17
+ end
18
+
16
19
  def three_args(a, b, c)
17
20
  end
18
21
 
@@ -207,10 +210,26 @@ describe Rtype do
207
210
  it "is right" do
208
211
  klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
209
212
  instance.return_arg([123, 456])
213
+
214
+ klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
215
+ instance.two_args([123], [456])
210
216
  end
211
217
  it "is wrong args" do
212
218
  klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
213
- expect {instance.return_arg([123, true])}.to raise_error Rtype::ArgumentTypeError
219
+ expect {
220
+ instance.return_arg([123, [true]])
221
+ }.to raise_error Rtype::ArgumentTypeError
222
+ expect {
223
+ instance.return_arg([123, true])
224
+ }.to raise_error Rtype::ArgumentTypeError
225
+
226
+ klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
227
+ expect {
228
+ instance.two_args([123, 123], [123])
229
+ }.to raise_error Rtype::ArgumentTypeError
230
+ expect {
231
+ instance.two_args([123], 123)
232
+ }.to raise_error Rtype::ArgumentTypeError
214
233
  end
215
234
  it "is wrong result" do
216
235
  klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
@@ -218,6 +237,23 @@ describe Rtype do
218
237
  end
219
238
  end
220
239
 
240
+ describe 'Hash' do
241
+ it "is right" do
242
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
243
+ instance.return_arg({k: 123}, {})
244
+ end
245
+ it "is wrong args" do
246
+ klass.send :rtype, :return_arg, [{k: Integer}, {}] => Any
247
+ expect {
248
+ instance.return_arg({k: "str"}, {})
249
+ }.to raise_error Rtype::ArgumentTypeError
250
+ end
251
+ it "is wrong result" do
252
+ klass.send :rtype, :return_arg, [Any] => {k: Integer}
253
+ expect { instance.return_arg({k: "str"}) }.to raise_error Rtype::ReturnTypeError
254
+ end
255
+ end
256
+
221
257
  describe 'Proc' do
222
258
  it "is right" do
223
259
  klass.send :rtype, :return_arg, [->(arg){!arg.nil?}] => Any
@@ -285,36 +321,117 @@ describe Rtype do
285
321
  end
286
322
 
287
323
  describe 'Special type behaviors' do
288
- it 'Rtype::Behavior::And' do
289
- klass.send :rtype, :return_nil, [Rtype.and(:to_i, :chars)] => nil
290
- instance.return_nil("Hello")
291
- expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
324
+ describe 'Rtype::Behavior::And' do
325
+ it 'module singleton method' do
326
+ klass.send :rtype, :return_nil, [Rtype::and(:to_i, :chars)] => nil
327
+ instance.return_nil("Hello")
328
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
329
+ end
330
+
331
+ it 'class singleton [] method' do
332
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::And[:to_i, :chars] ] => nil
333
+ instance.return_nil("Hello")
334
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
335
+ end
336
+
337
+ it 'core extension method' do
338
+ klass.send :rtype, :return_nil, [ :to_i.and(:chars) ] => nil
339
+ instance.return_nil("Hello")
340
+ expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
341
+ end
292
342
  end
293
343
 
294
- it 'Rtype::Behavior::Or' do
295
- klass.send :rtype, :return_nil, [Rtype.or(Integer, String)] => nil
296
- instance.return_nil(123)
297
- instance.return_nil("abc")
298
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
344
+ describe 'Rtype::Behavior::Or' do
345
+ it 'module singleton method' do
346
+ klass.send :rtype, :return_nil, [Rtype::or(Integer, String)] => nil
347
+ instance.return_nil(123)
348
+ instance.return_nil("abc")
349
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
350
+ end
351
+
352
+ it 'class singleton [] method' do
353
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Or[Integer, String] ] => nil
354
+ instance.return_nil(123)
355
+ instance.return_nil("abc")
356
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
357
+ end
358
+
359
+ it 'core extension method' do
360
+ klass.send :rtype, :return_nil, [ Integer.or(String) ] => nil
361
+ instance.return_nil(123)
362
+ instance.return_nil("abc")
363
+ expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
364
+ end
299
365
  end
300
366
 
301
- it 'Rtype::Behavior::Nilable' do
302
- klass.send :rtype, :return_nil, [Rtype.nilable(Integer)] => nil
303
- instance.return_nil(nil)
304
- instance.return_nil(123)
305
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
367
+ describe 'Rtype::Behavior::Nilable' do
368
+ it 'module singleton method' do
369
+ klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
370
+ instance.return_nil(nil)
371
+ instance.return_nil(123)
372
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
373
+ end
374
+
375
+ it 'class singleton [] method' do
376
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Nilable[Integer] ] => nil
377
+ instance.return_nil(nil)
378
+ instance.return_nil(123)
379
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
380
+ end
381
+
382
+ it 'core extension method :nilable' do
383
+ klass.send :rtype, :return_nil, [Integer.nilable] => nil
384
+ instance.return_nil(nil)
385
+ instance.return_nil(123)
386
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
387
+ end
388
+
389
+ it 'core extension method :or_nil' do
390
+ klass.send :rtype, :return_nil, [Integer.or_nil] => nil
391
+ instance.return_nil(nil)
392
+ instance.return_nil(123)
393
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
394
+ end
306
395
  end
307
396
 
308
- it 'Rtype::Behavior::Not' do
309
- klass.send :rtype, :return_nil, [Rtype.not(String)] => nil
310
- instance.return_nil(123)
311
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
397
+ describe 'Rtype::Behavior::Not' do
398
+ it 'module singleton method' do
399
+ klass.send :rtype, :return_nil, [Rtype::not(String)] => nil
400
+ instance.return_nil(123)
401
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
402
+ end
403
+
404
+ it 'class singleton [] method' do
405
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Not[String] ] => nil
406
+ instance.return_nil(123)
407
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
408
+ end
409
+
410
+ it 'core extension method' do
411
+ klass.send :rtype, :return_nil, [ String.not ] => nil
412
+ instance.return_nil(123)
413
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
414
+ end
312
415
  end
313
416
 
314
- it 'Rtype::Behavior::Xor' do
315
- klass.send :rtype, :return_nil, [Rtype.xor(:to_i, String)] => nil
316
- instance.return_nil(123)
317
- expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
417
+ describe 'Rtype::Behavior::Xor' do
418
+ it 'module singleton method' do
419
+ klass.send :rtype, :return_nil, [Rtype::xor(:to_i, String)] => nil
420
+ instance.return_nil(123)
421
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
422
+ end
423
+
424
+ it 'class singleton [] method' do
425
+ klass.send :rtype, :return_nil, [ Rtype::Behavior::Xor[:to_i, String] ] => nil
426
+ instance.return_nil(123)
427
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
428
+ end
429
+
430
+ it 'core extension method' do
431
+ klass.send :rtype, :return_nil, [ :to_i.xor(String) ] => nil
432
+ instance.return_nil(123)
433
+ expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
434
+ end
318
435
  end
319
436
  end
320
437
  end
@@ -334,6 +451,27 @@ describe Rtype do
334
451
  expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
335
452
  end
336
453
 
454
+ it 'two array' do
455
+ klass.send :rtype, :sum, [[Integer], [Integer]] => Any
456
+ instance.sum([1], [2])
457
+ expect {instance.sum([1], 2)}.to raise_error Rtype::ArgumentTypeError
458
+ expect {instance.sum([1], ["str"])}.to raise_error Rtype::ArgumentTypeError
459
+ end
460
+
461
+ it 'two hash' do
462
+ klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
463
+ instance.two_args({k: 123}, {k: 456}, {})
464
+ expect {
465
+ instance.two_args({k: 123}, {}, {})
466
+ }.to raise_error Rtype::ArgumentTypeError
467
+ expect {
468
+ instance.two_args({k: 123}, 456, {})
469
+ }.to raise_error Rtype::ArgumentTypeError
470
+ expect {
471
+ instance.two_args({k: 123}, {k: "str"}, {})
472
+ }.to raise_error Rtype::ArgumentTypeError
473
+ end
474
+
337
475
  it 'one keyword argument' do
338
476
  klass.send :rtype, :kwarg, {a: Float} => Any
339
477
  expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
@@ -370,6 +508,25 @@ describe Rtype do
370
508
  expect {instance.kwarg(a: 1)}.to raise_error Rtype::ArgumentTypeError
371
509
  expect {instance.kwarg(:a => 1)}.to raise_error Rtype::ArgumentTypeError
372
510
  end
511
+
512
+ context 'when hash is not last element' do
513
+ it 'is hash-type argument, not keyword argument' do
514
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
515
+ expect {
516
+ instance.return_arg({a: 123}, {})
517
+ }.to raise_error Rtype::ArgumentTypeError
518
+ end
519
+ end
520
+
521
+ it 'hash-type argument and keyword argument' do
522
+ klass.send :rtype, :arg_and_kwarg, [{a: String}, {b: String}] => Any
523
+ expect {
524
+ instance.arg_and_kwarg({a: 123}, b: "str")
525
+ }.to raise_error Rtype::ArgumentTypeError
526
+ expect {
527
+ instance.arg_and_kwarg({a: "str"}, b: 123)
528
+ }.to raise_error Rtype::ArgumentTypeError
529
+ end
373
530
  end
374
531
 
375
532
  describe 'check return' do
@@ -400,13 +557,13 @@ describe Rtype do
400
557
  end
401
558
  it 'invalid return signature' do
402
559
  expect {
403
- klass.send :rtype, :return_arg, [] => {}
560
+ klass.send :rtype, :return_arg, [] => 123
404
561
  }.to raise_error Rtype::TypeSignatureError
405
562
  end
406
563
 
407
564
  it 'invalid type behavior in arguments' do
408
565
  expect {
409
- klass.send :rtype, :sum_kwargs, [{a: Integer}, {b: Integer}] => Any
566
+ klass.send :rtype, :sum_kwargs, [{a: 123}, {b: Integer}] => Any
410
567
  }.to raise_error Rtype::TypeSignatureError
411
568
  expect {
412
569
  klass.send :rtype, :return_arg, [123] => Any
@@ -418,7 +575,7 @@ describe Rtype do
418
575
  klass.send :rtype, :kwarg, {a: 123} => Any
419
576
  }.to raise_error Rtype::TypeSignatureError
420
577
  expect {
421
- klass.send :rtype, :kwarg, {a: {b: Integer}} => Any
578
+ klass.send :rtype, :kwarg, {a: {b: 123}} => Any
422
579
  }.to raise_error Rtype::TypeSignatureError
423
580
  expect {
424
581
  klass.send :rtype, :kwarg, {Object.new => Integer} => Any
@@ -506,6 +663,15 @@ describe Rtype do
506
663
  instance.three_kwargs(a: "abc", b: 123, c: 456)
507
664
  end
508
665
  end
666
+
667
+ context 'when hash type argument contain a key not configured to rtype' do
668
+ it 'raises error' do
669
+ klass.send :rtype, :return_arg, [{a: String}, {}] => Any
670
+ expect {
671
+ instance.return_arg({a: "str", b: "str"}, {})
672
+ }.to raise_error Rtype::ArgumentTypeError
673
+ end
674
+ end
509
675
  end
510
676
 
511
677
  describe "Call Rtype`s static method directly" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtype
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sputnik Gugja
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-27 00:00:00.000000000 Z
11
+ date: 2016-04-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -52,7 +52,7 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
- description: Ruby with type
55
+ description: The fastest type checking gem
56
56
  email:
57
57
  - sputnikgugja@gmail.com
58
58
  executables: []
@@ -69,6 +69,7 @@ files:
69
69
  - lib/rtype/behavior.rb
70
70
  - lib/rtype/behavior/and.rb
71
71
  - lib/rtype/behavior/base.rb
72
+ - lib/rtype/behavior/core_ext.rb
72
73
  - lib/rtype/behavior/nilable.rb
73
74
  - lib/rtype/behavior/not.rb
74
75
  - lib/rtype/behavior/or.rb