typecheck 0.1.0 → 0.1.1
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/.gitignore +1 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +2 -2
- data/lib/typecheck.rb +12 -7
- data/spec/integration/typecheck_spec.rb +54 -17
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f76e0be630cb566def0e4b2b83b427afc0e856d5
|
4
|
+
data.tar.gz: 26f08e776636a425f7834e2338ad68a3f169cdae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d29e6f557d66947c70949de7a006200484767f0614d58bc216174c335f88e6a0b847293efdebf2a46a23d75b08d1d3220680a7bf6797af341aadcf44542bf59
|
7
|
+
data.tar.gz: 435e26ef5a06df032b63dfa4bd1a1a3531b5f0e914b1711f51d1e31892ba622665dbf16351127374627f2861e38bd3ca12d1db23c0168a1952dc0b69585dd058
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
pkg
|
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
@@ -10,7 +10,7 @@ task :default => :mutant
|
|
10
10
|
|
11
11
|
task :mutant do
|
12
12
|
pattern = ENV.fetch('PATTERN', 'Typecheck*')
|
13
|
-
result = Mutant::CLI.run(%w[-Ilib -rtypecheck --use rspec --score
|
13
|
+
result = Mutant::CLI.run(%w[-Ilib -rtypecheck --use rspec --score 99] + [pattern])
|
14
14
|
fail unless result == Mutant::CLI::EXIT_SUCCESS
|
15
15
|
end
|
16
16
|
|
@@ -24,7 +24,7 @@ gem.define
|
|
24
24
|
|
25
25
|
desc "Push gem to rubygems.org"
|
26
26
|
task :push => :gem do
|
27
|
-
|
27
|
+
sh "git tag v#{Typecheck::VERSION}"
|
28
28
|
sh "git push --tags"
|
29
29
|
sh "gem push pkg/typecheck-#{Typecheck::VERSION}.gem"
|
30
30
|
end
|
data/lib/typecheck.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Typecheck
|
2
|
-
VERSION = '0.1.
|
2
|
+
VERSION = '0.1.1'
|
3
3
|
|
4
4
|
def typecheck(signature, method)
|
5
5
|
alias_method "#{method}_unchecked", method
|
@@ -57,9 +57,9 @@ module Typecheck
|
|
57
57
|
pred_and subtype.split(';').map(&:strip).map { |type|
|
58
58
|
case type
|
59
59
|
when /#(.*)/
|
60
|
-
method("#{check_or_raise}_respond_to").to_proc.curry.(
|
60
|
+
method("#{check_or_raise}_respond_to").to_proc.curry.(type[1..-1])
|
61
61
|
when /\[(.*)\]/
|
62
|
-
method("#{check_or_raise}_array").to_proc.curry.(eval(
|
62
|
+
method("#{check_or_raise}_array").to_proc.curry.(eval(type[1..-2]))
|
63
63
|
else
|
64
64
|
method("#{check_or_raise}_class").to_proc.curry.(eval(type))
|
65
65
|
end
|
@@ -67,11 +67,12 @@ module Typecheck
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def check_respond_to(method, value)
|
70
|
-
value.respond_to?
|
70
|
+
value.respond_to?(method)
|
71
71
|
end
|
72
72
|
|
73
73
|
def raise_respond_to(method, value)
|
74
|
-
raise "Expected #{value.inspect}, to respond_to #{method}" unless check_respond_to(method, value)
|
74
|
+
raise TypeError, "Expected #{value.inspect}, to respond_to #{method}" unless check_respond_to(method, value)
|
75
|
+
true
|
75
76
|
end
|
76
77
|
|
77
78
|
def check_array(type, array)
|
@@ -79,7 +80,8 @@ module Typecheck
|
|
79
80
|
end
|
80
81
|
|
81
82
|
def raise_array(type, array)
|
82
|
-
raise "Bad type: #{array
|
83
|
+
raise TypeError, "Bad type: expected #{array} to only contain #{type}" unless check_array(type, array)
|
84
|
+
true
|
83
85
|
end
|
84
86
|
|
85
87
|
def check_class(klz, value)
|
@@ -87,7 +89,10 @@ module Typecheck
|
|
87
89
|
end
|
88
90
|
|
89
91
|
def raise_class(klz, value)
|
90
|
-
raise "Bad type: #{value.inspect}, expected #{klz}" unless check_class(klz, value)
|
92
|
+
raise TypeError, "Bad type: #{value.inspect}, expected #{klz}" unless check_class(klz, value)
|
93
|
+
true
|
91
94
|
end
|
92
95
|
end
|
96
|
+
|
97
|
+
TypeError = Class.new(StandardError)
|
93
98
|
end
|
@@ -7,9 +7,9 @@ describe Typecheck do
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
shared_examples 'invalid' do |method, args|
|
10
|
+
shared_examples 'invalid' do |method, args, message = '', error = Typecheck::TypeError|
|
11
11
|
it 'should typecheck' do
|
12
|
-
expect{subject.send(method, *args)}.to
|
12
|
+
expect{subject.send(method, *args)}.to raise_error(error, message)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -40,12 +40,22 @@ describe Typecheck do
|
|
40
40
|
def multi(range)
|
41
41
|
('x' * range.end).chars.drop(range.begin).join.intern
|
42
42
|
end
|
43
|
-
typecheck '#begin
|
43
|
+
typecheck '#begin; #end -> Symbol', :multi
|
44
|
+
|
45
|
+
def multi2(comp_enum)
|
46
|
+
:foo
|
47
|
+
end
|
48
|
+
typecheck 'Comparable;Enumerable -> Symbol', :multi2
|
49
|
+
|
50
|
+
def multi3(comp_enum)
|
51
|
+
:foo
|
52
|
+
end
|
53
|
+
typecheck '[Fixnum];[String] -> Symbol', :multi3
|
44
54
|
|
45
55
|
def choice(x)
|
46
56
|
:foo
|
47
57
|
end
|
48
|
-
typecheck '#to_str|Fixnum ->
|
58
|
+
typecheck '#to_str | Fixnum -> Symbol', :choice
|
49
59
|
|
50
60
|
def arrays(nums, strings)
|
51
61
|
(nums + strings.map(&:length)).inject(:+)
|
@@ -55,39 +65,66 @@ describe Typecheck do
|
|
55
65
|
def optional(num, str = nil, sym = nil)
|
56
66
|
num
|
57
67
|
end
|
58
|
-
typecheck 'Fixnum,String,Symbol -> Numeric', :optional
|
68
|
+
typecheck 'Fixnum, String, Symbol -> Numeric', :optional
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
62
72
|
subject { checked_class.new }
|
73
|
+
comparable = Class.new { include Comparable }.new
|
63
74
|
|
64
75
|
include_examples 'valid', :double_me, [7], 14
|
65
|
-
include_examples 'invalid', :double_me, ['foo']
|
66
|
-
include_examples 'invalid', :double_me, []
|
76
|
+
include_examples 'invalid', :double_me, ['foo'], 'Bad type: "foo", expected Numeric'
|
77
|
+
include_examples 'invalid', :double_me, [], 'wrong number of arguments (0 for 1)', ArgumentError
|
67
78
|
|
68
|
-
include_examples 'invalid', :bad_out, [42]
|
79
|
+
include_examples 'invalid', :bad_out, [42], 'Bad type: :sym, expected Numeric'
|
69
80
|
|
70
81
|
include_examples 'valid', :strsym_num, ['foo', :bar], 3
|
71
|
-
include_examples 'invalid', :strsym_num, [:foo, 'bar']
|
82
|
+
include_examples 'invalid', :strsym_num, [:foo, 'bar'], 'Bad type: :foo, expected String'
|
72
83
|
|
73
84
|
include_examples 'valid', :duck, ['foo'], :FOO
|
74
|
-
include_examples 'invalid', :duck, [7]
|
85
|
+
include_examples 'invalid', :duck, [7], /to respond_to to_str/
|
75
86
|
|
76
87
|
include_examples 'valid', :multi, [3..5], :xx
|
77
|
-
include_examples 'invalid', :multi, [Class.new { def begin ; end }.new]
|
78
|
-
include_examples 'invalid', :multi, [7]
|
88
|
+
include_examples 'invalid', :multi, [Class.new { def begin ; end }.new], /to respond_to end/
|
89
|
+
include_examples 'invalid', :multi, [7], /to respond_to begin/
|
90
|
+
include_examples 'invalid', :multi, ["foo"], /Expected "foo", to respond_to begin/
|
91
|
+
|
92
|
+
include_examples 'invalid', :multi2, [3..6], /Bad type.* expected Comparable/
|
93
|
+
include_examples 'invalid', :multi2, [comparable], /Bad type.* expected Enumerable/
|
94
|
+
|
95
|
+
include_examples 'invalid', :multi3, [[3.5]], 'Bad type: expected [3.5] to only contain Fixnum'
|
96
|
+
include_examples 'invalid', :multi3, [[3]], /to only contain String/
|
79
97
|
|
80
98
|
include_examples 'valid', :choice, ['foo'], :foo
|
81
99
|
include_examples 'valid', :choice, [9], :foo
|
82
|
-
include_examples 'invalid', :choice, [5..9]
|
83
|
-
include_examples 'invalid', :choice, [5.9]
|
100
|
+
include_examples 'invalid', :choice, [5..9], /Expected 5..9, to respond_to to_str/
|
101
|
+
include_examples 'invalid', :choice, [5.9], /Expected 5.9, to respond_to to_str/
|
84
102
|
|
85
103
|
include_examples 'valid', :arrays, [[1,2], ['x', 'y']], 5
|
86
|
-
include_examples 'invalid', :arrays, [[:foo], ['x']]
|
104
|
+
include_examples 'invalid', :arrays, [[:foo], ['x']], /\[:foo\] to only contain Fixnum/
|
87
105
|
|
88
106
|
include_examples 'valid', :optional, [1, 'x', :foo], 1
|
89
107
|
include_examples 'valid', :optional, [1, 'x'], 1
|
90
108
|
include_examples 'valid', :optional, [1], 1
|
91
|
-
include_examples 'invalid', :optional, [1, 'x', 'y'], 1
|
92
|
-
include_examples 'invalid', :optional, []
|
109
|
+
include_examples 'invalid', :optional, [1, 'x', 'y'], 1, 'Bad type: "y", expected Symbol'
|
110
|
+
include_examples 'invalid', :optional, [], /wrong number of arguments/, ArgumentError
|
111
|
+
|
112
|
+
it 'should make the original method available' do
|
113
|
+
expect(subject.double_me_unchecked('foo')).to eq 'foofoo'
|
114
|
+
end
|
115
|
+
|
116
|
+
describe Typecheck::SignatureCompiler do
|
117
|
+
describe '#parse_type' do
|
118
|
+
let(:compiler) { Typecheck::SignatureCompiler.new }
|
119
|
+
|
120
|
+
it 'should work with ; for "or"' do
|
121
|
+
x = Class.new { def begin ; end }.new
|
122
|
+
|
123
|
+
expect( compiler.parse_type('#begin;#end', :check).(x) ).to be false
|
124
|
+
expect{ compiler.raise_respond_to('end', x) }.to raise_error
|
125
|
+
expect{ compiler.parse_type('#begin;#end', :raise).(x) }.to raise_error
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
93
130
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typecheck
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arne Brasseur
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -61,6 +61,7 @@ extra_rdoc_files:
|
|
61
61
|
- README.md
|
62
62
|
- LICENSE
|
63
63
|
files:
|
64
|
+
- .gitignore
|
64
65
|
- Gemfile
|
65
66
|
- Gemfile.lock
|
66
67
|
- LICENSE
|