typecheck 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +83 -0
- data/LICENSE +9 -0
- data/README.md +71 -0
- data/Rakefile +30 -0
- data/lib/typecheck.rb +93 -0
- data/spec/integration/typecheck_spec.rb +93 -0
- data/spec/spec_helper.rb +3 -0
- data/typecheck.gemspec +23 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a7fc2715192b042a94bf221a43234bb59c613c3f
|
4
|
+
data.tar.gz: 1115a334c7936dd145fb090c6ba1675e5e92a470
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ccd6d3916e84953acc37f4b78d929e633f75790ccf0ecb803c1f08f1188e3e8a4e36e371a1eb885b96c20700a5a67864c52923dfbafa34d347af161f6c7864ea
|
7
|
+
data.tar.gz: ae6bcf095e29626885089680b6ed9464cf5bf2378a5f2b14e03c0eed8f5da3d0d76f3723958274023793116be1677b945bbf8f224ccd0f4a984d33b8b4ddee27
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
typecheck (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
abstract_type (0.0.7)
|
10
|
+
adamantium (0.2.0)
|
11
|
+
ice_nine (~> 0.11.0)
|
12
|
+
memoizable (~> 0.4.0)
|
13
|
+
anima (0.2.0)
|
14
|
+
abstract_type (~> 0.0.7)
|
15
|
+
adamantium (~> 0.1)
|
16
|
+
equalizer (~> 0.0.8)
|
17
|
+
ast (1.1.0)
|
18
|
+
concord (0.1.5)
|
19
|
+
adamantium (~> 0.2.0)
|
20
|
+
equalizer (~> 0.0.9)
|
21
|
+
diff-lcs (1.2.5)
|
22
|
+
equalizer (0.0.9)
|
23
|
+
ice_nine (0.11.0)
|
24
|
+
inflecto (0.0.2)
|
25
|
+
memoizable (0.4.2)
|
26
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
27
|
+
morpher (0.2.2)
|
28
|
+
abstract_type (~> 0.0.7)
|
29
|
+
adamantium (~> 0.2.0)
|
30
|
+
anima (~> 0.2.0)
|
31
|
+
ast (~> 1.1.0)
|
32
|
+
concord (~> 0.1.4)
|
33
|
+
equalizer (~> 0.0.9)
|
34
|
+
ice_nine (~> 0.11.0)
|
35
|
+
procto (~> 0.0.2)
|
36
|
+
mutant (0.5.10)
|
37
|
+
abstract_type (~> 0.0.7)
|
38
|
+
adamantium (~> 0.2.0)
|
39
|
+
anima (~> 0.2.0)
|
40
|
+
concord (~> 0.1.4)
|
41
|
+
diff-lcs (~> 1.2)
|
42
|
+
equalizer (~> 0.0.9)
|
43
|
+
ice_nine (~> 0.11.0)
|
44
|
+
inflecto (~> 0.0.2)
|
45
|
+
memoizable (~> 0.4.2)
|
46
|
+
morpher (~> 0.2.1)
|
47
|
+
parser (~> 2.1)
|
48
|
+
procto (~> 0.0.2)
|
49
|
+
unparser (~> 0.1.10)
|
50
|
+
mutant-rspec (0.5.10)
|
51
|
+
mutant (~> 0.5.10)
|
52
|
+
rspec-core (>= 2.14.1, <= 3.0.0.beta2)
|
53
|
+
parser (2.1.8)
|
54
|
+
ast (~> 1.1)
|
55
|
+
slop (~> 3.4, >= 3.4.5)
|
56
|
+
procto (0.0.2)
|
57
|
+
rake (10.3.1)
|
58
|
+
rspec (2.14.1)
|
59
|
+
rspec-core (~> 2.14.0)
|
60
|
+
rspec-expectations (~> 2.14.0)
|
61
|
+
rspec-mocks (~> 2.14.0)
|
62
|
+
rspec-core (2.14.8)
|
63
|
+
rspec-expectations (2.14.5)
|
64
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
65
|
+
rspec-mocks (2.14.6)
|
66
|
+
slop (3.5.0)
|
67
|
+
thread_safe (0.3.3)
|
68
|
+
unparser (0.1.12)
|
69
|
+
abstract_type (~> 0.0.7)
|
70
|
+
adamantium (~> 0.2.0)
|
71
|
+
concord (~> 0.1.4)
|
72
|
+
equalizer (~> 0.0.9)
|
73
|
+
parser (~> 2.1)
|
74
|
+
procto (~> 0.0.2)
|
75
|
+
|
76
|
+
PLATFORMS
|
77
|
+
ruby
|
78
|
+
|
79
|
+
DEPENDENCIES
|
80
|
+
mutant-rspec (~> 0.5.10)
|
81
|
+
rake (~> 10.2)
|
82
|
+
rspec (~> 2.14)
|
83
|
+
typecheck!
|
data/LICENSE
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
Copyright (c) 2014 Arne Brasseur
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
6
|
+
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
8
|
+
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
[![Gem Version](https://badge.fury.io/rb/typecheck.png)][gem]
|
2
|
+
[![Build Status](https://secure.travis-ci.org/plexus/typecheck.png?branch=master)][travis]
|
3
|
+
[![Code Climate](https://codeclimate.com/github/plexus/typecheck.png)][codeclimate]
|
4
|
+
|
5
|
+
[gem]: https://rubygems.org/gems/typecheck
|
6
|
+
[travis]: https://travis-ci.org/plexus/typecheck
|
7
|
+
[codeclimate]: https://codeclimate.com/github/plexus/typecheck
|
8
|
+
|
9
|
+
# Typecheck
|
10
|
+
|
11
|
+
Type checking for Ruby methods.
|
12
|
+
|
13
|
+
Validate the arguments and return value of a function, based on a type signature. Supports duck-type checking.
|
14
|
+
|
15
|
+
Example below is for Ruby 2.1, for 2.0 and earlier pass the function name explicitly :
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
def foo(..)
|
19
|
+
end
|
20
|
+
typecheck '...', :foo
|
21
|
+
```
|
22
|
+
|
23
|
+
Features by example:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'typecheck'
|
27
|
+
|
28
|
+
class Checked
|
29
|
+
extend Typecheck
|
30
|
+
|
31
|
+
typecheck 'Numeric -> Numeric',
|
32
|
+
def double_me(num)
|
33
|
+
num + num
|
34
|
+
end
|
35
|
+
|
36
|
+
typecheck 'String, Symbol -> Fixnum',
|
37
|
+
def strsym_num(str, sym)
|
38
|
+
str.length
|
39
|
+
end
|
40
|
+
|
41
|
+
# Duck typing FTW!
|
42
|
+
typecheck '#to_str -> Symbol',
|
43
|
+
def duck(str)
|
44
|
+
str.to_str.upcase.intern
|
45
|
+
end
|
46
|
+
|
47
|
+
typecheck '#begin;#end -> Symbol',
|
48
|
+
def multi(range)
|
49
|
+
('x' * range.end).chars.drop(range.begin).join.intern
|
50
|
+
end
|
51
|
+
|
52
|
+
typecheck '#to_str|Fixnum -> Symbol',
|
53
|
+
def choice(x)
|
54
|
+
:foo
|
55
|
+
end
|
56
|
+
|
57
|
+
typecheck '[Fixnum],[String] -> Numeric',
|
58
|
+
def arrays(nums, strings)
|
59
|
+
(nums + strings.map(&:length)).inject(:+)
|
60
|
+
end
|
61
|
+
|
62
|
+
typecheck 'Fixnum,String,Symbol -> Numeric',
|
63
|
+
def optional(num, str = nil, sym = nil)
|
64
|
+
num
|
65
|
+
end
|
66
|
+
end
|
67
|
+
```
|
68
|
+
|
69
|
+
## LICENSE
|
70
|
+
|
71
|
+
Copyright (c) 2014 Arne Brasseur, MIT License. See LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
########################################
|
2
|
+
# Testing
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
require 'mutant'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default => :mutant
|
10
|
+
|
11
|
+
task :mutant do
|
12
|
+
pattern = ENV.fetch('PATTERN', 'Typecheck*')
|
13
|
+
result = Mutant::CLI.run(%w[-Ilib -rtypecheck --use rspec --score 100] + [pattern])
|
14
|
+
fail unless result == Mutant::CLI::EXIT_SUCCESS
|
15
|
+
end
|
16
|
+
|
17
|
+
########################################
|
18
|
+
# Packaging
|
19
|
+
|
20
|
+
require 'rubygems/package_task'
|
21
|
+
spec = Gem::Specification.load(File.expand_path('../typecheck.gemspec', __FILE__))
|
22
|
+
gem = Gem::PackageTask.new(spec)
|
23
|
+
gem.define
|
24
|
+
|
25
|
+
desc "Push gem to rubygems.org"
|
26
|
+
task :push => :gem do
|
27
|
+
# sh "git tag v#{Typecheck::VERSION}"
|
28
|
+
sh "git push --tags"
|
29
|
+
sh "gem push pkg/typecheck-#{Typecheck::VERSION}.gem"
|
30
|
+
end
|
data/lib/typecheck.rb
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
module Typecheck
|
2
|
+
VERSION = '0.1.0'
|
3
|
+
|
4
|
+
def typecheck(signature, method)
|
5
|
+
alias_method "#{method}_unchecked", method
|
6
|
+
define_method method, &SignatureCompiler.new.call(signature, method)
|
7
|
+
end
|
8
|
+
|
9
|
+
class SignatureCompiler
|
10
|
+
def call(signature, method)
|
11
|
+
unchecked_method = "#{method}_unchecked"
|
12
|
+
check_args, check_out = parse_sig(signature)
|
13
|
+
->(*args) do
|
14
|
+
check_args.(*args)
|
15
|
+
send(unchecked_method, *args).tap do |result|
|
16
|
+
check_out.(result)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_sig(sig)
|
22
|
+
in_t, out_t = sig.split('->').map(&:strip)
|
23
|
+
in_ts = in_t.split(',').map(&:strip)
|
24
|
+
|
25
|
+
in_checks = in_ts.map(&method(:parse_type_list))
|
26
|
+
out_check = parse_type_list(out_t)
|
27
|
+
|
28
|
+
args_checker = ->(*args) {
|
29
|
+
args.each.with_index do |arg, idx|
|
30
|
+
in_checks[idx].(arg)
|
31
|
+
end
|
32
|
+
}
|
33
|
+
[args_checker, out_check]
|
34
|
+
end
|
35
|
+
|
36
|
+
def pred_or(preds)
|
37
|
+
->(value) { preds.any?{|pred| pred.(value) } }
|
38
|
+
end
|
39
|
+
|
40
|
+
def pred_and(preds)
|
41
|
+
->(value) { preds.all?{|pred| pred.(value) } }
|
42
|
+
end
|
43
|
+
|
44
|
+
def parse_type_list(choices)
|
45
|
+
types = choices.split('|').map(&:strip)
|
46
|
+
pred_or [
|
47
|
+
pred_or(types.map {|choice|
|
48
|
+
parse_type(choice, :check)
|
49
|
+
}),
|
50
|
+
pred_or(types.map {|choice|
|
51
|
+
parse_type(choice, :raise)
|
52
|
+
})
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
def parse_type(subtype, check_or_raise)
|
57
|
+
pred_and subtype.split(';').map(&:strip).map { |type|
|
58
|
+
case type
|
59
|
+
when /#(.*)/
|
60
|
+
method("#{check_or_raise}_respond_to").to_proc.curry.($1)
|
61
|
+
when /\[(.*)\]/
|
62
|
+
method("#{check_or_raise}_array").to_proc.curry.(eval($1))
|
63
|
+
else
|
64
|
+
method("#{check_or_raise}_class").to_proc.curry.(eval(type))
|
65
|
+
end
|
66
|
+
}
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_respond_to(method, value)
|
70
|
+
value.respond_to? method
|
71
|
+
end
|
72
|
+
|
73
|
+
def raise_respond_to(method, value)
|
74
|
+
raise "Expected #{value.inspect}, to respond_to #{method}" unless check_respond_to(method, value)
|
75
|
+
end
|
76
|
+
|
77
|
+
def check_array(type, array)
|
78
|
+
array.all? {|element| check_class(type, element) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def raise_array(type, array)
|
82
|
+
raise "Bad type: #{array.inspect} to only contain #{klz}" unless check_array(type, array)
|
83
|
+
end
|
84
|
+
|
85
|
+
def check_class(klz, value)
|
86
|
+
value.is_a? klz
|
87
|
+
end
|
88
|
+
|
89
|
+
def raise_class(klz, value)
|
90
|
+
raise "Bad type: #{value.inspect}, expected #{klz}" unless check_class(klz, value)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Typecheck do
|
4
|
+
shared_examples 'valid' do |method, args, result|
|
5
|
+
it 'should call the original method' do
|
6
|
+
expect(subject.send(method, *args)).to eq result
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
shared_examples 'invalid' do |method, args|
|
11
|
+
it 'should typecheck' do
|
12
|
+
expect{subject.send(method, *args)}.to raise_exception
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:checked_class) do
|
17
|
+
Class.new do
|
18
|
+
extend Typecheck
|
19
|
+
|
20
|
+
def double_me(num)
|
21
|
+
num + num
|
22
|
+
end
|
23
|
+
typecheck 'Numeric -> Numeric', :double_me
|
24
|
+
|
25
|
+
def bad_out(num)
|
26
|
+
:sym
|
27
|
+
end
|
28
|
+
typecheck 'Numeric -> Numeric', :bad_out
|
29
|
+
|
30
|
+
def strsym_num(str, sym)
|
31
|
+
str.length
|
32
|
+
end
|
33
|
+
typecheck 'String, Symbol -> Fixnum', :strsym_num
|
34
|
+
|
35
|
+
def duck(str)
|
36
|
+
str.to_str.upcase.intern
|
37
|
+
end
|
38
|
+
typecheck '#to_str -> Symbol', :duck
|
39
|
+
|
40
|
+
def multi(range)
|
41
|
+
('x' * range.end).chars.drop(range.begin).join.intern
|
42
|
+
end
|
43
|
+
typecheck '#begin;#end -> Symbol', :multi
|
44
|
+
|
45
|
+
def choice(x)
|
46
|
+
:foo
|
47
|
+
end
|
48
|
+
typecheck '#to_str|Fixnum -> Symbol', :choice
|
49
|
+
|
50
|
+
def arrays(nums, strings)
|
51
|
+
(nums + strings.map(&:length)).inject(:+)
|
52
|
+
end
|
53
|
+
typecheck '[Fixnum],[String] -> Numeric', :arrays
|
54
|
+
|
55
|
+
def optional(num, str = nil, sym = nil)
|
56
|
+
num
|
57
|
+
end
|
58
|
+
typecheck 'Fixnum,String,Symbol -> Numeric', :optional
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
subject { checked_class.new }
|
63
|
+
|
64
|
+
include_examples 'valid', :double_me, [7], 14
|
65
|
+
include_examples 'invalid', :double_me, ['foo']
|
66
|
+
include_examples 'invalid', :double_me, []
|
67
|
+
|
68
|
+
include_examples 'invalid', :bad_out, [42]
|
69
|
+
|
70
|
+
include_examples 'valid', :strsym_num, ['foo', :bar], 3
|
71
|
+
include_examples 'invalid', :strsym_num, [:foo, 'bar']
|
72
|
+
|
73
|
+
include_examples 'valid', :duck, ['foo'], :FOO
|
74
|
+
include_examples 'invalid', :duck, [7]
|
75
|
+
|
76
|
+
include_examples 'valid', :multi, [3..5], :xx
|
77
|
+
include_examples 'invalid', :multi, [Class.new { def begin ; end }.new]
|
78
|
+
include_examples 'invalid', :multi, [7]
|
79
|
+
|
80
|
+
include_examples 'valid', :choice, ['foo'], :foo
|
81
|
+
include_examples 'valid', :choice, [9], :foo
|
82
|
+
include_examples 'invalid', :choice, [5..9]
|
83
|
+
include_examples 'invalid', :choice, [5.9]
|
84
|
+
|
85
|
+
include_examples 'valid', :arrays, [[1,2], ['x', 'y']], 5
|
86
|
+
include_examples 'invalid', :arrays, [[:foo], ['x']]
|
87
|
+
|
88
|
+
include_examples 'valid', :optional, [1, 'x', :foo], 1
|
89
|
+
include_examples 'valid', :optional, [1, 'x'], 1
|
90
|
+
include_examples 'valid', :optional, [1], 1
|
91
|
+
include_examples 'invalid', :optional, [1, 'x', 'y'], 1
|
92
|
+
include_examples 'invalid', :optional, []
|
93
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/typecheck.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path('../lib/typecheck', __FILE__)
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'typecheck'
|
7
|
+
gem.version = Typecheck::VERSION
|
8
|
+
gem.authors = [ 'Arne Brasseur' ]
|
9
|
+
gem.email = [ 'arne@arnebrasseur.net' ]
|
10
|
+
gem.description = 'Type checking for Ruby methods.'
|
11
|
+
gem.summary = gem.description
|
12
|
+
gem.homepage = 'https://github.com/plexus/typecheck'
|
13
|
+
gem.license = 'MIT'
|
14
|
+
|
15
|
+
gem.require_paths = %w[lib]
|
16
|
+
gem.files = `git ls-files`.split($/)
|
17
|
+
gem.test_files = `git ls-files -- spec`.split($/)
|
18
|
+
gem.extra_rdoc_files = %w[README.md LICENSE]
|
19
|
+
|
20
|
+
gem.add_development_dependency 'rake' , '~> 10.2'
|
21
|
+
gem.add_development_dependency 'rspec' , '~> 2.14'
|
22
|
+
gem.add_development_dependency 'mutant-rspec' , '~> 0.5.10'
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: typecheck
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arne Brasseur
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-25 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.2'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '10.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mutant-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.5.10
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.5.10
|
55
|
+
description: Type checking for Ruby methods.
|
56
|
+
email:
|
57
|
+
- arne@arnebrasseur.net
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files:
|
61
|
+
- README.md
|
62
|
+
- LICENSE
|
63
|
+
files:
|
64
|
+
- Gemfile
|
65
|
+
- Gemfile.lock
|
66
|
+
- LICENSE
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- lib/typecheck.rb
|
70
|
+
- spec/integration/typecheck_spec.rb
|
71
|
+
- spec/spec_helper.rb
|
72
|
+
- typecheck.gemspec
|
73
|
+
homepage: https://github.com/plexus/typecheck
|
74
|
+
licenses:
|
75
|
+
- MIT
|
76
|
+
metadata: {}
|
77
|
+
post_install_message:
|
78
|
+
rdoc_options: []
|
79
|
+
require_paths:
|
80
|
+
- lib
|
81
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 2.0.14
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Type checking for Ruby methods.
|
97
|
+
test_files:
|
98
|
+
- spec/integration/typecheck_spec.rb
|
99
|
+
- spec/spec_helper.rb
|