rtype 0.5.1 → 0.6.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: 705c8cfc434a65a0d0be00560f97a75380443e5b
4
- data.tar.gz: 8cb8cf5be58792d7b434f650abeb2c6022f2b1c5
3
+ metadata.gz: 545e8dc3a8ac3c44aa68d87126c6dbf8d57302bb
4
+ data.tar.gz: f3d34bb1fb2ecd9cb7f4b0a9315d14fa5a726940
5
5
  SHA512:
6
- metadata.gz: 0ed1a39880ce0949e075747d0fcd92c793add8fe09dbf227a5a188474ac8fa14f0da93c34391b350b26af451717de9b9a058a66d6d92890c24bbe4b7b1e7e46e
7
- data.tar.gz: 56bcb6c32091b30d918966f018c662595f699b4c87aee01a2291536d9b7c59111892deb52578c09958ae59f1fb7758454ca02a20d0b79c9790ddf9f47e0fd075
6
+ metadata.gz: e39262cd99fdf372ed953a2e4c09cafcc09b7d236946d66d3d37acd03f432e72a0de4f7aaf3cd7d74e0d8997ef0178846ba35c040e209acc08a4a60b4e43f7b5
7
+ data.tar.gz: e31ad200c1d08bb0077ef429cfa4d813bff2732f04f705eafc0ce4166c9dbbf0f82581a9e4655500fdb35ec09721cc22c3d29104fccf40c789fd2cdc7bd3f8b2
data/README.md CHANGED
@@ -37,9 +37,8 @@ Test::invert(state: 0)
37
37
  - If Java extension is used, otherwise it is not required
38
38
 
39
39
  ## Features
40
- - Provide type checking for arguments and return
41
- - Support type checking for [keyword argument](#keyword-argument)
42
- - [Type checking for array elements](#array)
40
+ - Provides type checking for arguments and return
41
+ - Supports type checking for [keyword argument](#keyword-argument)
43
42
  - [Type checking for hash elements](#hash)
44
43
  - [Duck typing](#duck-typing)
45
44
  - Custom type behavior
@@ -81,28 +80,23 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
81
80
 
82
81
  ### Supported Type Behaviors
83
82
  - `Module`
84
- - Value must be an instance of this module/class or one of its superclasses
83
+ - Value must be an instance of the module/class or one of its superclasses
85
84
  - `Any` : An alias for `BasicObject` (means Any Object)
86
85
  - `Boolean` : `true` or `false`
87
86
  - `Symbol`
88
- - Value must have(respond to) a method with this name
87
+ - Value must have(respond to) a method with the name
89
88
  - `Regexp`
90
- - Value must match this regexp pattern
89
+ - Value must match the regexp pattern
91
90
  - `Range`
92
- - Value must be included in this range
93
- - `Array` (tuple)
94
- - Value must be an array
95
- - Each of value's elements must be valid
96
- - Value's length must be equal to the array's length
97
- - Of course, nested array works
98
- - Example: [Array](#array)
99
- - This can be used as a tuple
91
+ - Value must be included in the range
92
+ - `Array`
93
+ - Value can be any type in the array
100
94
  - `Hash`
101
95
  - Value must be an hash
102
96
  - Each of value’s elements must be valid
103
97
  - Value's key list must be equal to the hash's key list
104
98
  - **String** key is **different** from **symbol** key
105
- - vs Keyword arguments
99
+ - vs Keyword arguments (e.g.)
106
100
  - `[{}]` is **not** hash type argument. it is keyword argument because its position is last
107
101
  - `[{}, {}]` is empty hash type argument (first) and one empty keyword argument (second)
108
102
  - `[{}, {}, {}]` is two empty hash type argument (first, second) and empty keyword argument (last)
@@ -110,44 +104,31 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
110
104
  - Of course, nested hash works
111
105
  - Example: [Hash](#hash)
112
106
  - `Proc`
113
- - Value must return a truthy value for this proc
107
+ - Value must return a truthy value for the proc
114
108
  - `true`
115
109
  - Value must be **truthy**
116
110
  - `false`
117
111
  - Value must be **falsy**
118
112
  - `nil`
119
- - Only available for **return type**. void return type in other languages
113
+ - Value must be nil
120
114
  - Special Behaviors
121
115
  - `Rtype::and(*types)` : Ensure value is valid for all the types
122
- - `Rtype::and(*types)`
123
- - `Rtype::Behavior::And[*types]`
124
- - `include Rtype::Behavior; And[...]`
125
- - `obj.and(*others)` (core extension)
126
-
127
- - `Rtype::or(*types)` : Ensure value is valid for at least one of the types
128
- - `Rtype::or(*types)`
129
- - `Rtype::Behavior::Or[*types]`
130
- - `include Rtype::Behavior; Or[...]`
131
- - `obj.or(*others)` (core extension)
132
-
116
+ - `Rtype::and(*types)`, `Rtype::Behavior::And[*types]`, `include Rtype::Behavior; And[...]`
117
+ - `Array#comb`
118
+ - `Object#and(*others)`
119
+
133
120
  - `Rtype::xor(*types)` : Ensure value is valid for only one of the types
134
- - `Rtype::xor(*types)`
135
- - `Rtype::Behavior::Xor[*types]`
136
- - `include Rtype::Behavior; Xor[...]`
137
- - `obj.xor(*others)` (core extension)
121
+ - `Rtype::xor(*types)`, `Rtype::Behavior::Xor[*types]`, `include Rtype::Behavior; Xor[...]`
122
+ - `Object#xor(*others)`
138
123
 
139
124
  - `Rtype::not(*types)` : Ensure value is not valid for all the types
140
- - `Rtype::not(*types)`
141
- - `Rtype::Behavior::Not[*types]`
142
- - `include Rtype::Behavior; Not[...]`
143
- - `obj.not` (core extension)
125
+ - `Rtype::not(*types)`, `Rtype::Behavior::Not[*types]`, `include Rtype::Behavior; Not[...]`
126
+ - `Object#not`
144
127
 
145
128
  - `Rtype::nilable(type)` : Ensure value can be nil
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)
129
+ - `Rtype::nilable(type)`, `Rtype::Behavior::Nilable[type]`, `include Rtype::Behavior; Nilable[...]`
130
+ - `Object#nilable`
131
+ - `Object#or_nil`
151
132
 
152
133
  - You can create custom behavior by extending `Rtype::Behavior::Base`
153
134
 
@@ -224,33 +205,19 @@ Duck.new.says("2") # duck: quack quack
224
205
  ```
225
206
 
226
207
  #### Array
227
- This can be used as a tuple.
228
-
229
208
  ```ruby
230
- rtype :func, [[Numeric, Numeric]] => Any
231
- def func(arr)
232
- puts "Your location is (#{arr[0]}, #{arr[1]}). I will look for you. I will find you"
209
+ rtype :ruby!, [[String, Integer]] => Any
210
+ def ruby!(arg)
211
+ puts "ruby!"
233
212
  end
234
213
 
235
- func [1, "str"]
236
- # (Rtype::ArgumentTypeError) for 1st argument:
237
- # Expected [1, "str"] to be an array with 2 elements:
238
- # - [0] index : Expected 1 to be a Numeric
239
- # - [1] index : Expected "str" to be a Numeric
240
-
241
- func [1, 2, 3]
242
- # (Rtype::ArgumentTypeError) for 1st argument:
243
- # Expected [1, 2, 3] to be an array with 2 elements:
244
- # - [0] index : Expected 1 to be a Numeric
245
- # - [1] index : Expected 2 to be a Numeric
214
+ func("str") # ruby!
215
+ func(123) # ruby!
246
216
 
247
- func [1]
217
+ func(nil)
248
218
  # (Rtype::ArgumentTypeError) for 1st argument:
249
- # Expected [1] to be an array with 2 elements:
250
- # - [0] index : Expected 1 to be a Numeric
251
- # - [1] index : Expected nil to be a Numeric
252
-
253
- func [1, 2] # Your location is (1, 2). I will look for you. I will find you
219
+ # Expected nil to be a String
220
+ # OR Expected nil to be a Integer
254
221
  ```
255
222
 
256
223
  #### Hash
@@ -316,7 +283,7 @@ Example.new.value
316
283
  require 'rtype'
317
284
 
318
285
  class Example
319
- rtype [String.and(:func)] => Any
286
+ rtype [[String, :func].comb] => Any
320
287
  # also works:
321
288
  # rtype [Rtype::and(String, :func)] => Any
322
289
  def and_test(arg)
@@ -349,12 +316,12 @@ module Game
349
316
  ENEMY = [
350
317
  :name,
351
318
  :level
352
- ]
319
+ ].comb
353
320
 
354
321
  class Player < Entity
355
322
  include Rtype::Behavior
356
323
 
357
- rtype [And[*ENEMY]] => Any
324
+ rtype [ENEMY] => Any
358
325
  def attacks(enemy)
359
326
  "Player attacks '#{enemy.name}' (level #{enemy.level})!"
360
327
  end
@@ -565,4 +532,4 @@ Sputnik Gugja (sputnikgugja@gmail.com)
565
532
  ## License
566
533
  MIT license (@ Sputnik Gugja)
567
534
 
568
- See `LICENSE` file.
535
+ See `LICENSE` file.
@@ -12,11 +12,7 @@ class Object
12
12
  ::Rtype::not(self)
13
13
  end
14
14
 
15
- def or(*others)
16
- ::Rtype::or(self, *others)
17
- end
18
-
19
15
  def xor(*others)
20
16
  ::Rtype::xor(self, *others)
21
17
  end
22
- end
18
+ end
@@ -4,9 +4,8 @@ module Rtype
4
4
  end
5
5
 
6
6
  require_relative 'behavior/base'
7
- require_relative 'behavior/or'
8
7
  require_relative 'behavior/and'
9
8
  require_relative 'behavior/xor'
10
9
  require_relative 'behavior/not'
11
10
  require_relative 'behavior/nilable'
12
- require_relative 'behavior/core_ext'
11
+ require_relative 'behavior/core_ext'
@@ -83,17 +83,8 @@ class Method
83
83
  end
84
84
  end
85
85
 
86
- class Fixnum
87
- def ordinalize
88
- if (11..13).include?(self % 100)
89
- "#{self}th"
90
- else
91
- case self % 10
92
- when 1; "#{self}st"
93
- when 2; "#{self}nd"
94
- when 3; "#{self}rd"
95
- else "#{self}th"
96
- end
97
- end
86
+ class Array
87
+ def comb
88
+ ::Rtype::Behavior::And[*self]
98
89
  end
99
- end
90
+ end
data/lib/rtype/version.rb CHANGED
@@ -1,3 +1,7 @@
1
1
  module Rtype
2
- VERSION = "0.5.1".freeze
2
+ VERSION = "0.6.0".freeze
3
+ # rtype java extension version. nil If the extension is not used
4
+ JAVA_EXT_VERSION = nil unless defined?(JAVA_EXT_VERSION)
5
+ # rtype c extension version. nil If the extension is not used
6
+ NATIVE_EXT_VERSION = nil unless defined?(NATIVE_EXT_VERSION)
3
7
  end
data/lib/rtype.rb CHANGED
@@ -98,14 +98,13 @@ module Rtype
98
98
  end
99
99
 
100
100
  def arg_message(idx)
101
- "for #{(idx+1).ordinalize} argument:"
101
+ "for #{ordinalize_number(idx+1)} argument:"
102
102
  end
103
103
 
104
104
  def kwarg_message(key)
105
105
  "for '#{key}' argument:"
106
106
  end
107
107
 
108
-
109
108
  def type_error_message(expected, value)
110
109
  case expected
111
110
  when Rtype::Behavior::Base
@@ -119,18 +118,8 @@ module Rtype
119
118
  when Range
120
119
  "Expected #{value.inspect} to be included in range #{expected.inspect}"
121
120
  when Array
122
- if value.is_a?(Array)
123
- arr = expected.map.with_index do |e, idx|
124
- if e.is_a?(Array) || e.is_a?(Hash)
125
- "- [#{idx}] index : {\n" + type_error_message(e, value[idx]) + "\n}"
126
- else
127
- "- [#{idx}] index : " + type_error_message(e, value[idx])
128
- end
129
- end
130
- "Expected #{value.inspect} to be an array with #{expected.length} elements:\n" + arr.join("\n")
131
- else
132
- "Expected #{value.inspect} to be an array"
133
- end
121
+ arr = expected.map { |e| type_error_message(e, value) }
122
+ arr.join("\nOR ")
134
123
  when Hash
135
124
  if value.is_a?(Hash)
136
125
  arr = []
@@ -208,13 +197,14 @@ module Rtype
208
197
  when Proc
209
198
  when true
210
199
  when false
200
+ when nil
211
201
  else
212
202
  raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{sig}"
213
203
  end
214
204
  end
215
205
 
216
206
  def assert_valid_return_type_sig(sig)
217
- assert_valid_argument_type_sig_element(sig) unless sig.nil?
207
+ assert_valid_argument_type_sig_element(sig)
218
208
  end
219
209
 
220
210
  private
@@ -233,7 +223,19 @@ private
233
223
  end
234
224
  nil
235
225
  end
236
-
226
+
227
+ def ordinalize_number(num)
228
+ if (11..13).include?(num % 100)
229
+ "#{num}th"
230
+ else
231
+ case num % 10
232
+ when 1; "#{num}st"
233
+ when 2; "#{num}nd"
234
+ when 3; "#{num}rd"
235
+ else "#{num}th"
236
+ end
237
+ end
238
+ end
237
239
  public
238
240
  unless respond_to?(:valid?)
239
241
  # validate argument type
@@ -252,10 +254,7 @@ public
252
254
  return false unless expected.keys == value.keys
253
255
  expected.all? { |k, v| valid?(v, value[k]) }
254
256
  when Array
255
- return false unless value.is_a?(Array)
256
- return false unless expected.length == value.length
257
- idx = -1
258
- expected.all? { |e| idx += 1; valid?(e, value[idx]) }
257
+ expected.any? { |e| valid?(e, value) }
259
258
  when Proc
260
259
  !!expected.call(value)
261
260
  when true
@@ -264,6 +263,8 @@ public
264
263
  !value
265
264
  when Rtype::Behavior::Base
266
265
  expected.valid? value
266
+ when nil
267
+ value.nil?
267
268
  else
268
269
  raise TypeSignatureError, "Invalid type signature: Unknown type behavior #{expected}"
269
270
  end
@@ -272,14 +273,14 @@ public
272
273
 
273
274
  unless respond_to?(:assert_arguments_type)
274
275
  def assert_arguments_type(expected_args, args)
276
+ e_len = expected_args.length
275
277
  # `length.times` is faster than `each_with_index`
276
278
  args.length.times do |i|
279
+ break if i >= e_len
277
280
  expected = expected_args[i]
278
281
  value = args[i]
279
- unless expected.nil?
280
- unless valid?(expected, value)
281
- raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
282
- end
282
+ unless valid?(expected, value)
283
+ raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
283
284
  end
284
285
  end
285
286
  end
@@ -287,19 +288,20 @@ public
287
288
 
288
289
  unless respond_to?(:assert_arguments_type_with_keywords)
289
290
  def assert_arguments_type_with_keywords(expected_args, args, expected_kwargs, kwargs)
291
+ e_len = expected_args.length
290
292
  # `length.times` is faster than `each_with_index`
291
293
  args.length.times do |i|
294
+ break if i >= e_len
292
295
  expected = expected_args[i]
293
296
  value = args[i]
294
- unless expected.nil?
295
- unless valid?(expected, value)
296
- raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
297
- end
297
+ unless valid?(expected, value)
298
+ raise ArgumentTypeError, "#{arg_message(i)}\n" + type_error_message(expected, value)
298
299
  end
299
300
  end
301
+
300
302
  kwargs.each do |key, value|
301
- expected = expected_kwargs[key]
302
- unless expected.nil?
303
+ if expected_kwargs.key?(key)
304
+ expected = expected_kwargs[key]
303
305
  unless valid?(expected, value)
304
306
  raise ArgumentTypeError, "#{kwarg_message(key)}\n" + type_error_message(expected, value)
305
307
  end
@@ -310,14 +312,8 @@ public
310
312
 
311
313
  unless respond_to?(:assert_return_type)
312
314
  def assert_return_type(expected, result)
313
- if expected.nil?
314
- unless result.nil?
315
- raise ReturnTypeError, "for return:\n" + type_error_message(expected, result)
316
- end
317
- else
318
- unless valid?(expected, result)
319
- raise ReturnTypeError, "for return:\n" + type_error_message(expected, result)
320
- end
315
+ unless valid?(expected, result)
316
+ raise ReturnTypeError, "for return:\n" + type_error_message(expected, result)
321
317
  end
322
318
  end
323
319
  end
data/spec/rtype_spec.rb CHANGED
@@ -237,31 +237,30 @@ describe Rtype do
237
237
 
238
238
  describe 'Array' do
239
239
  it "is right" do
240
- klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
241
- instance.return_arg([123, 456])
240
+ klass.send :rtype, :return_arg, [[:to_i]] => Any
241
+ instance.return_arg(123)
242
242
 
243
- klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
244
- instance.two_args([123], [456])
243
+ klass.send :rtype, :return_arg, [[String, Integer]] => Any
244
+ instance.return_arg("str")
245
+ instance.return_arg(123)
246
+
247
+ klass.send :rtype, :return_arg, [] => [String, Integer]
248
+ instance.return_arg("str")
249
+ instance.return_arg(123)
245
250
  end
246
251
  it "is wrong args" do
247
- klass.send :rtype, :return_arg, [[:to_i, :to_i]] => Any
248
- expect {
249
- instance.return_arg([123, [true]])
250
- }.to raise_error Rtype::ArgumentTypeError
252
+ klass.send :rtype, :return_arg, [[String, Integer]] => Any
251
253
  expect {
252
- instance.return_arg([123, true])
254
+ instance.return_arg(nil)
253
255
  }.to raise_error Rtype::ArgumentTypeError
254
256
 
255
- klass.send :rtype, :two_args, [[:to_i], [:to_i]] => Any
257
+ klass.send :rtype, :return_arg, [[String]] => Any
256
258
  expect {
257
- instance.two_args([123, 123], [123])
258
- }.to raise_error Rtype::ArgumentTypeError
259
- expect {
260
- instance.two_args([123], 123)
259
+ instance.return_arg(123)
261
260
  }.to raise_error Rtype::ArgumentTypeError
262
261
  end
263
262
  it "is wrong result" do
264
- klass.send :rtype, :return_arg, [Any] => [:to_i, :to_i]
263
+ klass.send :rtype, :return_arg, [Any] => [String, Integer]
265
264
  expect {instance.return_arg(true)}.to raise_error Rtype::ReturnTypeError
266
265
  end
267
266
  end
@@ -335,17 +334,19 @@ describe Rtype do
335
334
  end
336
335
 
337
336
  describe 'nil' do
338
- it "is only for return" do
337
+ it "for return" do
339
338
  klass.send :rtype, :return_nil, [] => nil
340
339
  instance.return_nil(123)
341
340
 
342
341
  klass.send :rtype, :return_arg, [] => nil
343
342
  expect {instance.return_arg(123)}.to raise_error Rtype::ReturnTypeError
344
343
  end
345
- it "could not be used for args" do
344
+ it "for args" do
345
+ klass.send :rtype, :return_arg, [nil] => Any
346
+ instance.return_arg(nil)
346
347
  expect {
347
- klass.send :rtype, :return_arg, [nil] => Any
348
- }.to raise_error Rtype::TypeSignatureError
348
+ instance.return_arg(123)
349
+ }.to raise_error Rtype::ArgumentTypeError
349
350
  end
350
351
  end
351
352
 
@@ -370,29 +371,6 @@ describe Rtype do
370
371
  end
371
372
  end
372
373
 
373
- describe 'Rtype::Behavior::Or' do
374
- it 'module singleton method' do
375
- klass.send :rtype, :return_nil, [Rtype::or(Integer, String)] => nil
376
- instance.return_nil(123)
377
- instance.return_nil("abc")
378
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
379
- end
380
-
381
- it 'class singleton [] method' do
382
- klass.send :rtype, :return_nil, [ Rtype::Behavior::Or[Integer, String] ] => nil
383
- instance.return_nil(123)
384
- instance.return_nil("abc")
385
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
386
- end
387
-
388
- it 'core extension method' do
389
- klass.send :rtype, :return_nil, [ Integer.or(String) ] => nil
390
- instance.return_nil(123)
391
- instance.return_nil("abc")
392
- expect {instance.return_nil(nil)}.to raise_error Rtype::ArgumentTypeError
393
- end
394
- end
395
-
396
374
  describe 'Rtype::Behavior::Nilable' do
397
375
  it 'module singleton method' do
398
376
  klass.send :rtype, :return_nil, [Rtype::nilable(Integer)] => nil
@@ -480,13 +458,6 @@ describe Rtype do
480
458
  expect {instance.sum(1, 2.0)}.to raise_error Rtype::ArgumentTypeError
481
459
  end
482
460
 
483
- it 'two array' do
484
- klass.send :rtype, :sum, [[Integer], [Integer]] => Any
485
- instance.sum([1], [2])
486
- expect {instance.sum([1], 2)}.to raise_error Rtype::ArgumentTypeError
487
- expect {instance.sum([1], ["str"])}.to raise_error Rtype::ArgumentTypeError
488
- end
489
-
490
461
  it 'two hash' do
491
462
  klass.send :rtype, :two_args, [{k: Integer}, {k: Integer}, {}] => Any
492
463
  instance.two_args({k: 123}, {k: 456}, {})
@@ -564,9 +535,9 @@ describe Rtype do
564
535
  instance.return_arg("str")
565
536
  end
566
537
 
567
- it 'Array (tuple)' do
538
+ it 'Array' do
568
539
  klass.send :rtype, :return_arg, [] => [Integer, Float]
569
- expect {instance.return_arg([1, 2])}.to raise_error Rtype::ReturnTypeError
540
+ expect {instance.return_arg("str")}.to raise_error Rtype::ReturnTypeError
570
541
  end
571
542
  end
572
543
 
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.5.1
4
+ version: 0.6.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-04-25 00:00:00.000000000 Z
11
+ date: 2016-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -72,7 +72,6 @@ files:
72
72
  - lib/rtype/behavior/core_ext.rb
73
73
  - lib/rtype/behavior/nilable.rb
74
74
  - lib/rtype/behavior/not.rb
75
- - lib/rtype/behavior/or.rb
76
75
  - lib/rtype/behavior/xor.rb
77
76
  - lib/rtype/core_ext.rb
78
77
  - lib/rtype/method_annotator.rb
@@ -1,24 +0,0 @@
1
- module Rtype
2
- module Behavior
3
- class Or < Base
4
- def initialize(*types)
5
- @types = types
6
- end
7
-
8
- def valid?(value)
9
- @types.any? do |e|
10
- Rtype::valid? e, value
11
- end
12
- end
13
-
14
- def error_message(value)
15
- arr = @types.map { |e| Rtype::type_error_message(e, value) }
16
- arr.join "\nOR "
17
- end
18
- end
19
- end
20
-
21
- def or(*args)
22
- Behavior::Or[*args]
23
- end
24
- end