rtype-native 0.6.0 → 0.6.3
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 +4 -4
- data/README.md +73 -35
- data/ext/rtype/c/rtype.h +1 -1
- data/spec/rtype_spec.rb +37 -3
- data/spec/spec_helper.rb +9 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d3834e0dd5989b21f8343ac28837056dee4fff3c
|
4
|
+
data.tar.gz: 41e52dec30cf0551784e062f4c618b34e641e0b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c16c235c06f6d139e8de3a8edf3b14814e0c8813ea789dc43db4c8a59719dcb56fd93bba7511866890e731f809939444dcc33d8156ff051cda345f3aa4fa2d4d
|
7
|
+
data.tar.gz: e9d9902c18d207a39e7311ba7c8e19ced9d003bcb6f692ba66435c8698585f4ce0db259920337a97e183df903aaca7ffe158e8a26e4e5b42822c7308a1611cce
|
data/README.md
CHANGED
@@ -32,9 +32,9 @@ Test::invert(state: 0)
|
|
32
32
|
## Requirements
|
33
33
|
- Ruby >= 2.1
|
34
34
|
- MRI
|
35
|
-
- If C native extension is used
|
36
|
-
- JRuby
|
37
|
-
- If Java extension is used
|
35
|
+
- If C native extension is used. otherwise it is not required
|
36
|
+
- JRuby (JRuby 9000+)
|
37
|
+
- If Java extension is used. otherwise it is not required
|
38
38
|
|
39
39
|
## Features
|
40
40
|
- Provides type checking for arguments and return
|
@@ -80,52 +80,58 @@ then, Rtype use it. (Do not `require 'rtype-java'`)
|
|
80
80
|
|
81
81
|
### Supported Type Behaviors
|
82
82
|
- `Module`
|
83
|
-
-
|
83
|
+
- A value must be an instance of the module/class or one of its superclasses (`is_a?`)
|
84
84
|
- `Any` : An alias for `BasicObject` (means Any Object)
|
85
85
|
- `Boolean` : `true` or `false`
|
86
86
|
- `Symbol`
|
87
|
-
-
|
87
|
+
- A value must have(respond to) a method with the name
|
88
88
|
- `Regexp`
|
89
|
-
-
|
89
|
+
- A value must match the regexp pattern
|
90
90
|
- `Range`
|
91
|
-
-
|
91
|
+
- A value must be included in the range
|
92
92
|
- `Array`
|
93
|
-
-
|
93
|
+
- A value can be any type in the array
|
94
94
|
- `Hash`
|
95
|
-
-
|
96
|
-
- Each of value’s elements must be valid
|
97
|
-
-
|
95
|
+
- A value must be a hash
|
96
|
+
- Each of the value’s elements must be valid
|
97
|
+
- The value's key list must be equal to the hash's key list
|
98
98
|
- **String** key is **different** from **symbol** key
|
99
|
-
- vs Keyword arguments (e.g.)
|
100
|
-
- `[{}]` is **not** hash type argument. it is keyword argument because its position is last
|
101
|
-
- `[{}, {}]` is empty hash type argument (first) and one empty keyword argument (second)
|
102
|
-
- `[{}, {}, {}]` is two empty hash type argument (first, second) and empty keyword argument (last)
|
99
|
+
- vs. Keyword arguments (e.g.)
|
100
|
+
- `[{}]` is **not** hash type argument. it is keyword argument, because its position is last
|
101
|
+
- `[{}, {}]` is empty hash type argument (first), and one empty keyword argument (second)
|
102
|
+
- `[{}, {}, {}]` is two empty hash type argument (first, second), and empty keyword argument (last)
|
103
103
|
- `{}` is keyword argument. non-keyword arguments must be in array.
|
104
104
|
- Of course, nested hash works
|
105
105
|
- Example: [Hash](#hash)
|
106
106
|
- `Proc`
|
107
|
-
-
|
107
|
+
- A value must return a truthy value for the proc
|
108
108
|
- `true`
|
109
|
-
-
|
109
|
+
- A value must be **truthy**
|
110
110
|
- `false`
|
111
|
-
-
|
111
|
+
- A value must be **falsy**
|
112
112
|
- `nil`
|
113
|
-
-
|
113
|
+
- A value must be nil
|
114
|
+
|
114
115
|
- Special Behaviors
|
115
|
-
- `Rtype::
|
116
|
+
- `Rtype::TypedArray` : Ensures a value is an array with the type (type signature)
|
117
|
+
- `Array::of(type)` (recommended)
|
118
|
+
- `Rtype::Behavior::TypedArray[type]`
|
119
|
+
- Example: [TypedArray](#typed-array)
|
120
|
+
|
121
|
+
- `Rtype::and(*types)` : Ensures a value is valid for all the types
|
116
122
|
- `Rtype::and(*types)`, `Rtype::Behavior::And[*types]`, `include Rtype::Behavior; And[...]`
|
117
123
|
- `Array#comb`
|
118
124
|
- `Object#and(*others)`
|
119
125
|
|
120
|
-
- `Rtype::xor(*types)` :
|
126
|
+
- `Rtype::xor(*types)` : Ensures a value is valid for only one of the types
|
121
127
|
- `Rtype::xor(*types)`, `Rtype::Behavior::Xor[*types]`, `include Rtype::Behavior; Xor[...]`
|
122
128
|
- `Object#xor(*others)`
|
123
129
|
|
124
|
-
- `Rtype::not(*types)` :
|
130
|
+
- `Rtype::not(*types)` : Ensures a value is not valid for all the types
|
125
131
|
- `Rtype::not(*types)`, `Rtype::Behavior::Not[*types]`, `include Rtype::Behavior; Not[...]`
|
126
132
|
- `Object#not`
|
127
133
|
|
128
|
-
- `Rtype::nilable(type)` :
|
134
|
+
- `Rtype::nilable(type)` : Ensures a value can be nil
|
129
135
|
- `Rtype::nilable(type)`, `Rtype::Behavior::Nilable[type]`, `include Rtype::Behavior; Nilable[...]`
|
130
136
|
- `Object#nilable`
|
131
137
|
- `Object#or_nil`
|
@@ -231,29 +237,29 @@ end
|
|
231
237
|
# last hash is keyword arguments
|
232
238
|
func({}, {})
|
233
239
|
# (Rtype::ArgumentTypeError) for 1st argument:
|
234
|
-
# Expected {} to be
|
240
|
+
# Expected {} to be a hash with 1 elements:
|
235
241
|
# - msg : Expected nil to be a String
|
236
242
|
|
237
243
|
func({msg: 123}, {})
|
238
244
|
# (Rtype::ArgumentTypeError) for 1st argument:
|
239
|
-
# Expected {:msg=>123} to be
|
245
|
+
# Expected {:msg=>123} to be a hash with 1 elements:
|
240
246
|
# - msg : Expected 123 to be a String
|
241
247
|
|
242
248
|
func({msg: "hello", key: 'value'}, {})
|
243
249
|
# (Rtype::ArgumentTypeError) for 1st argument:
|
244
|
-
# Expected {:msg=>"hello", :key=>"value"} to be
|
250
|
+
# Expected {:msg=>"hello", :key=>"value"} to be a hash with 1 elements:
|
245
251
|
# - msg : Expected "hello" to be a String
|
246
252
|
|
247
253
|
func({"msg" => "hello hash"}, {})
|
248
254
|
# (Rtype::ArgumentTypeError) for 1st argument:
|
249
|
-
# Expected {"msg"=>"hello hash"} to be
|
255
|
+
# Expected {"msg"=>"hello hash"} to be a hash with 1 elements:
|
250
256
|
# - msg : Expected nil to be a String
|
251
257
|
|
252
258
|
func({msg: "hello hash"}, {}) # hello hash
|
253
259
|
```
|
254
260
|
|
255
261
|
#### rtype with attr_accessor
|
256
|
-
`rtype_accessor` : calls `attr_accessor` if the accessor method(getter/setter) is not defined
|
262
|
+
`rtype_accessor` : calls `attr_accessor` if the accessor method(getter/setter) is not defined. and makes it typed
|
257
263
|
|
258
264
|
You can use `rtype_accessor_self` for static accessor.
|
259
265
|
|
@@ -277,6 +283,38 @@ Example.new.value
|
|
277
283
|
# Expected 456 to be a String
|
278
284
|
```
|
279
285
|
|
286
|
+
#### Typed Array
|
287
|
+
```ruby
|
288
|
+
### TEST 1 ###
|
289
|
+
class Test
|
290
|
+
rtype [Array.of(Integer)] => Any
|
291
|
+
def sum(args)
|
292
|
+
num = 0
|
293
|
+
args.each { |e| num += e }
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
sum([1, 2, 3]) # => 6
|
298
|
+
|
299
|
+
sum([1.0, 2, 3])
|
300
|
+
# (Rtype::ArgumentTypeError) for 1st argument:
|
301
|
+
# Expected [1.0, 2, 3] to be an array with type Integer"
|
302
|
+
```
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
### TEST 2 ###
|
306
|
+
class Test
|
307
|
+
rtype [ Array.of([Integer, Float]) ] => Any
|
308
|
+
def sum(args)
|
309
|
+
num = 0
|
310
|
+
args.each { |e| num += e }
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
sum([1, 2, 3]) # => 6
|
315
|
+
sum([1.0, 2, 3]) # => 6.0
|
316
|
+
```
|
317
|
+
|
280
318
|
#### Combined type
|
281
319
|
```ruby
|
282
320
|
### TEST 1 ###
|
@@ -342,7 +380,7 @@ Game::Player.new.attacks Game::Slime.new
|
|
342
380
|
# Player attacks 'Powerful Slime' (level 123)!
|
343
381
|
```
|
344
382
|
|
345
|
-
#### Position of `rtype` && (
|
383
|
+
#### Position of `rtype` && (specifying method name || annotation mode) && (symbol || string)
|
346
384
|
```ruby
|
347
385
|
require 'rtype'
|
348
386
|
|
@@ -371,7 +409,7 @@ class Example
|
|
371
409
|
puts "Hello? #{i} #{str}"
|
372
410
|
end
|
373
411
|
|
374
|
-
#
|
412
|
+
# Doesn't work. `rtype` works for following (next) method
|
375
413
|
def hello_world_four(i, str)
|
376
414
|
puts "Hello? #{i} #{str}"
|
377
415
|
end
|
@@ -380,7 +418,7 @@ end
|
|
380
418
|
```
|
381
419
|
|
382
420
|
#### Outside of module (root)
|
383
|
-
|
421
|
+
In the outside of module, annotation mode don't works. You must specify method name.
|
384
422
|
|
385
423
|
```ruby
|
386
424
|
rtype :say, [String] => Any
|
@@ -394,7 +432,7 @@ rtype [String] => Any
|
|
394
432
|
# (ArgumentError) Annotation mode not working out of module
|
395
433
|
```
|
396
434
|
|
397
|
-
####
|
435
|
+
#### Class method
|
398
436
|
rtype annotation mode works both instance and class method
|
399
437
|
|
400
438
|
```ruby
|
@@ -410,7 +448,7 @@ end
|
|
410
448
|
Example::say_ya(3) #say ya ya ya
|
411
449
|
```
|
412
450
|
|
413
|
-
|
451
|
+
if you specify method name, however, you must use `rtype_self` instead of `rtype`
|
414
452
|
|
415
453
|
```ruby
|
416
454
|
require 'rtype'
|
@@ -425,7 +463,7 @@ end
|
|
425
463
|
Example::say_ya(3) #say ya ya ya
|
426
464
|
```
|
427
465
|
|
428
|
-
####
|
466
|
+
#### Checking type information
|
429
467
|
This is just the 'information'
|
430
468
|
|
431
469
|
Any change of this doesn't affect type checking
|
@@ -524,7 +562,7 @@ Comparison:
|
|
524
562
|
## Rubype, Sig
|
525
563
|
Rtype is influenced by [Rubype](https://github.com/gogotanaka/Rubype) and [Sig](https://github.com/janlelis/sig).
|
526
564
|
|
527
|
-
If you don't like Rtype, You can use other
|
565
|
+
If you don't like Rtype, You can use other library such as Contracts, Rubype, Rtc, Typecheck, Sig.
|
528
566
|
|
529
567
|
## Author
|
530
568
|
Sputnik Gugja (sputnikgugja@gmail.com)
|
data/ext/rtype/c/rtype.h
CHANGED
data/spec/rtype_spec.rb
CHANGED
@@ -150,24 +150,30 @@ describe Rtype do
|
|
150
150
|
|
151
151
|
it 'Kernel#rtype_accessor' do
|
152
152
|
class TestClass
|
153
|
-
rtype_accessor :value, String
|
153
|
+
rtype_accessor :value, :value2, String
|
154
154
|
|
155
155
|
def initialize
|
156
156
|
@value = 123
|
157
|
+
@value2 = 123
|
157
158
|
end
|
158
159
|
end
|
159
160
|
expect {TestClass.new.value = 123}.to raise_error Rtype::ArgumentTypeError
|
160
161
|
expect {TestClass.new.value}.to raise_error Rtype::ReturnTypeError
|
162
|
+
expect {TestClass.new.value2 = 123}.to raise_error Rtype::ArgumentTypeError
|
163
|
+
expect {TestClass.new.value2}.to raise_error Rtype::ReturnTypeError
|
161
164
|
end
|
162
165
|
|
163
166
|
it 'Kernel#rtype_accessor_self' do
|
164
167
|
class TestClass
|
165
|
-
@@
|
168
|
+
@@value = 123
|
169
|
+
@@value2 = 123
|
166
170
|
|
167
|
-
rtype_accessor_self :value, String
|
171
|
+
rtype_accessor_self :value, :value2, String
|
168
172
|
end
|
169
173
|
expect {TestClass::value = 123}.to raise_error Rtype::ArgumentTypeError
|
170
174
|
expect {TestClass::value}.to raise_error Rtype::ReturnTypeError
|
175
|
+
expect {TestClass::value2 = 123}.to raise_error Rtype::ArgumentTypeError
|
176
|
+
expect {TestClass::value2}.to raise_error Rtype::ReturnTypeError
|
171
177
|
end
|
172
178
|
|
173
179
|
describe 'Test type behaviors' do
|
@@ -440,6 +446,34 @@ describe Rtype do
|
|
440
446
|
expect {instance.return_nil("abc")}.to raise_error Rtype::ArgumentTypeError
|
441
447
|
end
|
442
448
|
end
|
449
|
+
|
450
|
+
describe 'Rtype::Behavior::TypedArray' do
|
451
|
+
it 'class singleton [] method' do
|
452
|
+
klass.send :rtype, :return_nil, [ Rtype::Behavior::TypedArray[Integer] ] => nil
|
453
|
+
instance.return_nil([123])
|
454
|
+
expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
|
455
|
+
expect {instance.return_nil([1.0])}.to raise_error Rtype::ArgumentTypeError
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'core extension method (Array::of)' do
|
459
|
+
klass.send :rtype, :return_nil, [ Array.of(Integer) ] => nil
|
460
|
+
instance.return_nil([123])
|
461
|
+
expect {instance.return_nil(123)}.to raise_error Rtype::ArgumentTypeError
|
462
|
+
expect {instance.return_nil([1.0])}.to raise_error Rtype::ArgumentTypeError
|
463
|
+
end
|
464
|
+
|
465
|
+
it 'complicated type sig' do
|
466
|
+
klass.send :rtype, :return_nil, [ Array.of(:to_i.and(:chars)) ] => nil
|
467
|
+
instance.return_nil(["hello"])
|
468
|
+
expect {instance.return_nil("hello")}.to raise_error Rtype::ArgumentTypeError
|
469
|
+
expect {instance.return_nil([123])}.to raise_error Rtype::ArgumentTypeError
|
470
|
+
end
|
471
|
+
|
472
|
+
it 'allows empty array' do
|
473
|
+
klass.send :rtype, :return_nil, [ Array.of(Integer) ] => nil
|
474
|
+
instance.return_nil([])
|
475
|
+
end
|
476
|
+
end
|
443
477
|
end
|
444
478
|
end
|
445
479
|
|
data/spec/spec_helper.rb
CHANGED
@@ -2,4 +2,12 @@ require 'coveralls'
|
|
2
2
|
Coveralls.wear!
|
3
3
|
|
4
4
|
require 'rtype'
|
5
|
-
require 'rspec'
|
5
|
+
require 'rspec'
|
6
|
+
|
7
|
+
if !Rtype::NATIVE_EXT_VERSION.nil?
|
8
|
+
puts "Rtype with native extension"
|
9
|
+
elsif !Rtype::JAVA_EXT_VERSION.nil?
|
10
|
+
puts "Rtype with java extension"
|
11
|
+
else
|
12
|
+
puts "Rtype without native extension"
|
13
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rtype-native
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.3
|
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-
|
11
|
+
date: 2016-07-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rtype
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.6.
|
19
|
+
version: 0.6.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.6.
|
26
|
+
version: 0.6.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|