rtype 0.3.0 → 0.4.0

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