rubybreaker 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +7 -0
- data/LICENSE +26 -0
- data/README.md +403 -0
- data/Rakefile +90 -0
- data/TODO +30 -0
- data/bin/gen_stub_rubylib +64 -0
- data/bin/rubybreaker +67 -0
- data/lib/rubybreaker/context.rb +122 -0
- data/lib/rubybreaker/debug.rb +48 -0
- data/lib/rubybreaker/error.rb +59 -0
- data/lib/rubybreaker/rubylib/core.rb +2316 -0
- data/lib/rubybreaker/rubylib.rb +3 -0
- data/lib/rubybreaker/runtime/inspector.rb +57 -0
- data/lib/rubybreaker/runtime/monitor.rb +235 -0
- data/lib/rubybreaker/runtime/object_wrapper.rb +77 -0
- data/lib/rubybreaker/runtime/overrides.rb +42 -0
- data/lib/rubybreaker/runtime/pluggable.rb +57 -0
- data/lib/rubybreaker/runtime/type_placeholder.rb +27 -0
- data/lib/rubybreaker/runtime/type_system.rb +228 -0
- data/lib/rubybreaker/runtime/typesig_parser.rb +45 -0
- data/lib/rubybreaker/runtime.rb +103 -0
- data/lib/rubybreaker/test/testcase.rb +39 -0
- data/lib/rubybreaker/test.rb +1 -0
- data/lib/rubybreaker/type/type.rb +241 -0
- data/lib/rubybreaker/type/type_comparer.rb +143 -0
- data/lib/rubybreaker/type/type_grammar.treetop +285 -0
- data/lib/rubybreaker/type/type_unparser.rb +142 -0
- data/lib/rubybreaker/type.rb +2 -0
- data/lib/rubybreaker/typing/rubytype.rb +47 -0
- data/lib/rubybreaker/typing/subtyping.rb +480 -0
- data/lib/rubybreaker/typing.rb +3 -0
- data/lib/rubybreaker/util.rb +31 -0
- data/lib/rubybreaker.rb +193 -0
- data/test/integrated/tc_method_missing.rb +30 -0
- data/test/integrated/tc_simple1.rb +77 -0
- data/test/runtime/tc_obj_wrapper.rb +73 -0
- data/test/runtime/tc_typesig_parser.rb +33 -0
- data/test/ts_integrated.rb +4 -0
- data/test/ts_runtime.rb +5 -0
- data/test/ts_type.rb +5 -0
- data/test/ts_typing.rb +4 -0
- data/test/type/tc_comparer.rb +211 -0
- data/test/type/tc_parser.rb +219 -0
- data/test/type/tc_unparser.rb +276 -0
- data/test/typing/tc_rubytype.rb +63 -0
- data/test/typing/tc_typing.rb +219 -0
- data/webpage/footer.html +5 -0
- data/webpage/generated_toc.js +319 -0
- data/webpage/header.html +14 -0
- data/webpage/images/logo.png +0 -0
- data/webpage/index.html +439 -0
- data/webpage/rubybreaker.css +53 -0
- metadata +119 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "../../lib/rubybreaker"
|
3
|
+
|
4
|
+
class IntegratedMethodMissingTest < Test::Unit::TestCase
|
5
|
+
include RubyBreaker
|
6
|
+
include RubyBreaker::TestCase
|
7
|
+
|
8
|
+
class A
|
9
|
+
include RubyBreaker::Breakable
|
10
|
+
|
11
|
+
def method_missing(mname, *args, &blk)
|
12
|
+
method_name = mname.to_s
|
13
|
+
return method_name + "_" + args.join("_")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# TODO: This must be fixed once variable length argument type is supported
|
19
|
+
# in auto-documentation.
|
20
|
+
def test_a_foo
|
21
|
+
a = A.new
|
22
|
+
a.foo(1,2)
|
23
|
+
meth_type = Runtime::Inspector.inspect_meth(A, :method_missing)
|
24
|
+
str = RubyBreaker::TypeUnparser.unparse(meth_type)
|
25
|
+
# puts str
|
26
|
+
assert_equal("method_missing(symbol[to_s], fixnum[to_s], fixnum[to_s]) -> string", str, "A#foo failed.")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "../../lib/rubybreaker"
|
3
|
+
|
4
|
+
class IntegratedSimpleTest < Test::Unit::TestCase
|
5
|
+
include RubyBreaker
|
6
|
+
include RubyBreaker::TestCase
|
7
|
+
|
8
|
+
class A
|
9
|
+
include RubyBreaker::Breakable
|
10
|
+
|
11
|
+
def foo(x)
|
12
|
+
x.to_s
|
13
|
+
end
|
14
|
+
|
15
|
+
def bar(x,y)
|
16
|
+
x.to_s
|
17
|
+
x.size
|
18
|
+
y.size
|
19
|
+
end
|
20
|
+
|
21
|
+
def baz(x,b)
|
22
|
+
if b
|
23
|
+
x.size
|
24
|
+
else
|
25
|
+
x.to_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def bazz()
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
class B
|
36
|
+
include RubyBreaker::Broken
|
37
|
+
typesig("baz(string[size], true_class) -> fixnum")
|
38
|
+
typesig("baz(string[to_s], false_class) -> string")
|
39
|
+
def baz(x,b); end
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_simple1_a_foo
|
43
|
+
a = A.new
|
44
|
+
a.foo("test_simple1 >> string")
|
45
|
+
meth_type = Runtime::Inspector.inspect_meth(A, :foo)
|
46
|
+
str = RubyBreaker::TypeUnparser.unparse(meth_type)
|
47
|
+
# puts str
|
48
|
+
assert_equal("foo(string[to_s]) -> string", str, "A#foo failed.")
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_simple1_a_bar
|
52
|
+
a = A.new
|
53
|
+
a.bar("str1","str2")
|
54
|
+
meth_type = Runtime::Inspector.inspect_meth(A, :bar)
|
55
|
+
str = RubyBreaker::TypeUnparser.unparse(meth_type)
|
56
|
+
# puts str
|
57
|
+
assert_equal("bar(string[size, to_s], string[size]) -> fixnum", str,
|
58
|
+
"A#bar failed.")
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_simple1_a_baz
|
62
|
+
a = A.new
|
63
|
+
a.baz("str1",true)
|
64
|
+
a.baz("str2",false)
|
65
|
+
a_meth_type = Runtime::Inspector.inspect_meth(A, :baz)
|
66
|
+
b_meth_type = Runtime::Inspector.inspect_meth(B, :baz)
|
67
|
+
assert(RubyBreaker::Typing.subtype_rel?(a_meth_type, b_meth_type))
|
68
|
+
assert(RubyBreaker::Typing.subtype_rel?(b_meth_type, a_meth_type))
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_simple1_a_bazz
|
72
|
+
a = A.new
|
73
|
+
a.bazz()
|
74
|
+
a_meth_type = Runtime::Inspector.inspect_meth(A, :bazz)
|
75
|
+
assert(a_meth_type.ret_type.eql?(SelfType.new()))
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
dir = File.dirname(__FILE__)
|
2
|
+
require "test/unit"
|
3
|
+
require "#{dir}/../../lib/rubybreaker/runtime"
|
4
|
+
|
5
|
+
class ObjectWrapperTest < Test::Unit::TestCase
|
6
|
+
include RubyBreaker
|
7
|
+
|
8
|
+
def foo(x)
|
9
|
+
x.to_s
|
10
|
+
x.to_f
|
11
|
+
end
|
12
|
+
|
13
|
+
def bar(x)
|
14
|
+
x.to_s
|
15
|
+
x.to_s
|
16
|
+
x.to_f
|
17
|
+
x.to_s
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_empty()
|
21
|
+
x = 42
|
22
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
23
|
+
type = wrapped_x.__rubybreaker_type()
|
24
|
+
str = TypeUnparser.unparse(type)
|
25
|
+
assert_equal("fixnum[]",str)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_simple_foo()
|
29
|
+
x = 42
|
30
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
31
|
+
Runtime::GLOBAL_MONITOR_SWITCH.turn_on()
|
32
|
+
foo(wrapped_x)
|
33
|
+
Runtime::GLOBAL_MONITOR_SWITCH.turn_off()
|
34
|
+
type = wrapped_x.__rubybreaker_type()
|
35
|
+
str = TypeUnparser.unparse(type)
|
36
|
+
assert_equal("fixnum[to_f, to_s]",str)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_simple_bar()
|
40
|
+
x = 42
|
41
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
42
|
+
Runtime::GLOBAL_MONITOR_SWITCH.turn_on()
|
43
|
+
bar(wrapped_x)
|
44
|
+
Runtime::GLOBAL_MONITOR_SWITCH.turn_off()
|
45
|
+
type = wrapped_x.__rubybreaker_type()
|
46
|
+
str = TypeUnparser.unparse(type)
|
47
|
+
assert_equal("fixnum[to_f, to_s]",str)
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_object_id()
|
51
|
+
x = 42
|
52
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
53
|
+
bar(wrapped_x)
|
54
|
+
assert_equal(x.object_id, wrapped_x.object_id)
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_equal()
|
58
|
+
x = 42
|
59
|
+
wrapped_x = Runtime::ObjectWrapper.new(x)
|
60
|
+
assert(wrapped_x == wrapped_x)
|
61
|
+
assert(wrapped_x.equal?(wrapped_x))
|
62
|
+
assert(wrapped_x.eql?(wrapped_x))
|
63
|
+
assert(42 == wrapped_x)
|
64
|
+
assert(wrapped_x == 42)
|
65
|
+
assert(42.equal?(wrapped_x))
|
66
|
+
assert(wrapped_x.equal?(42))
|
67
|
+
assert(42.eql?(wrapped_x))
|
68
|
+
assert(wrapped_x.eql?(42))
|
69
|
+
assert_equal(42, wrapped_x)
|
70
|
+
assert_equal(42, wrapped_x)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# This test verifies type signature parser for RubyBreaker.
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
require "test/unit"
|
6
|
+
require "#{dir}/../../lib/rubybreaker/runtime"
|
7
|
+
|
8
|
+
class TypeSigTest < Test::Unit::TestCase
|
9
|
+
include RubyBreaker
|
10
|
+
|
11
|
+
class A
|
12
|
+
include RubyBreaker::Broken
|
13
|
+
typesig("foo(fixnum) -> fixnum")
|
14
|
+
typesig("bar(fixnum) -> self")
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_typesig_a_foo
|
18
|
+
foo_type = Runtime::Inspector.inspect_meth(TypeSigTest::A,:foo)
|
19
|
+
foo_type_str = TypeUnparser.unparse(foo_type)
|
20
|
+
assert_equal("foo(fixnum) -> fixnum", foo_type_str,
|
21
|
+
"foo(fixnum) -> fixnum failed")
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_typesig_a_bar
|
25
|
+
bar_type = Runtime::Inspector.inspect_meth(TypeSigTest::A,:bar)
|
26
|
+
bar_type_str = TypeUnparser.unparse(bar_type)
|
27
|
+
assert_equal(A, bar_type.ret_type.mod)
|
28
|
+
assert_equal("bar(fixnum) -> self", bar_type_str,
|
29
|
+
"bar(fixnum) -> self failed")
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
end
|
data/test/ts_runtime.rb
ADDED
data/test/ts_type.rb
ADDED
data/test/ts_typing.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# This test verifies type signature parser for RubyBreaker.
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
require "test/unit"
|
6
|
+
require "#{dir}/../../lib/rubybreaker/type"
|
7
|
+
|
8
|
+
class ComparerTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
include RubyBreaker
|
11
|
+
|
12
|
+
# This function is a helper to compose an error message for comparison
|
13
|
+
# test.
|
14
|
+
def msg(lhs,rhs,should_fail=false)
|
15
|
+
subtype = TypeUnparser.unparse(lhs)
|
16
|
+
supertype = TypeUnparser.unparse(rhs)
|
17
|
+
str = "#{subtype} = #{supertype}"
|
18
|
+
if should_fail
|
19
|
+
str = str + " did not fail"
|
20
|
+
else
|
21
|
+
str = str + " failed"
|
22
|
+
end
|
23
|
+
return str
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_nil_any
|
27
|
+
t1 = NilType.new()
|
28
|
+
t2 = AnyType.new()
|
29
|
+
t3 = NilType.new()
|
30
|
+
assert(!t1.eql?(t2), msg(t1,t2,true))
|
31
|
+
assert(!t2.eql?(t1), msg(t2,t1,true))
|
32
|
+
assert(t1.eql?(t3), msg(t1,t3))
|
33
|
+
assert(t3.eql?(t1), msg(t3,t1))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_nominal
|
37
|
+
t1 = NominalType.new(Fixnum)
|
38
|
+
t2 = NominalType.new(Numeric)
|
39
|
+
t3 = NominalType.new(String)
|
40
|
+
t4 = NominalType.new(String)
|
41
|
+
assert(!t1.eql?(t2), msg(t1, t2, true))
|
42
|
+
assert(!t1.eql?(t3), msg(t1, t3, true))
|
43
|
+
assert(!t2.eql?(t3), msg(t2, t3, true))
|
44
|
+
assert(t3.eql?(t4), msg(t3, t4))
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_optional_varlength
|
48
|
+
t1 = NominalType.new(Fixnum)
|
49
|
+
t2 = NominalType.new(Numeric)
|
50
|
+
t3 = NominalType.new(String)
|
51
|
+
t4 = OptionalType.new(t1)
|
52
|
+
t5 = OptionalType.new(t1)
|
53
|
+
t6 = OptionalType.new(t2)
|
54
|
+
t7 = OptionalType.new(t3)
|
55
|
+
t8 = VarLengthType.new(t1)
|
56
|
+
t9 = VarLengthType.new(t1)
|
57
|
+
t10 = VarLengthType.new(t2)
|
58
|
+
t11 = VarLengthType.new(t3)
|
59
|
+
assert(t4.eql?(t5), msg(t4, t5))
|
60
|
+
assert(!t4.eql?(t6), msg(t4, t6, true))
|
61
|
+
assert(t8.eql?(t9), msg(t8, t9))
|
62
|
+
assert(!t8.eql?(t10), msg(t8, t10, true))
|
63
|
+
assert(!t7.eql?(t11), msg(t7, t11, true))
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_self
|
67
|
+
t1 = SelfType.new()
|
68
|
+
t2 = SelfType.new()
|
69
|
+
t3 = NominalType.new(Fixnum)
|
70
|
+
assert(t1.eql?(t2), msg(t1, t2))
|
71
|
+
assert(!t1.eql?(t3), msg(t1, t3, true))
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_duck
|
75
|
+
t1 = DuckType.new([:foo, :bar])
|
76
|
+
t2 = DuckType.new([:bar, :foo])
|
77
|
+
t3 = DuckType.new([:foo, :bar, :baz])
|
78
|
+
t4 = DuckType.new([:bar])
|
79
|
+
assert(t1.eql?(t2), msg(t1, t2))
|
80
|
+
assert(!t1.eql?(t3), msg(t1, t3, true))
|
81
|
+
assert(!t1.eql?(t4), msg(t1, t4, true))
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_fusion
|
85
|
+
t1 = FusionType.new(NominalType.new(Fixnum), [:to_s, :to_f])
|
86
|
+
t2 = FusionType.new(NominalType.new(Fixnum), [:to_f, :to_s])
|
87
|
+
t3 = FusionType.new(NominalType.new(String), [:to_s, :to_f])
|
88
|
+
t4 = DuckType.new([:to_s, :to_f])
|
89
|
+
t5 = NominalType.new(Fixnum)
|
90
|
+
assert(t1.eql?(t2), msg(t1, t2))
|
91
|
+
assert(!t1.eql?(t3), msg(t1, t3, true))
|
92
|
+
assert(!t1.eql?(t4), msg(t1, t4, true))
|
93
|
+
assert(!t1.eql?(t5), msg(t1, t5, true))
|
94
|
+
end
|
95
|
+
|
96
|
+
def test_block_no_arg
|
97
|
+
t1 = NominalType.new(String)
|
98
|
+
t2 = NominalType.new(String)
|
99
|
+
t3 = NominalType.new(Fixnum)
|
100
|
+
t4 = BlockType.new([],nil,t1)
|
101
|
+
t5 = BlockType.new([],nil,t2)
|
102
|
+
t6 = BlockType.new([],nil,t3)
|
103
|
+
assert(t4.eql?(t5), msg(t4, t5))
|
104
|
+
assert(!t4.eql?(t6), msg(t4, t6, true))
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_block_one_arg
|
108
|
+
t1 = NominalType.new(String)
|
109
|
+
t2 = NominalType.new(String)
|
110
|
+
t3 = NominalType.new(Fixnum)
|
111
|
+
t4 = BlockType.new([t1],nil,t3)
|
112
|
+
t5 = BlockType.new([t2],nil,t3)
|
113
|
+
t6 = BlockType.new([],nil,t3)
|
114
|
+
assert(t4.eql?(t5), msg(t4, t5))
|
115
|
+
assert(!t4.eql?(t6), msg(t4, t6, true))
|
116
|
+
end
|
117
|
+
|
118
|
+
def test_block_more_args
|
119
|
+
t1 = NominalType.new(String)
|
120
|
+
t2 = NominalType.new(String)
|
121
|
+
t3 = NominalType.new(Fixnum)
|
122
|
+
t4 = OptionalType.new(NominalType.new(Object))
|
123
|
+
t5 = VarLengthType.new(NominalType.new(String))
|
124
|
+
t6 = NominalType.new(BasicObject)
|
125
|
+
t7 = BlockType.new([t1,t4,t5],nil,t3)
|
126
|
+
t8 = BlockType.new([t2,t4,t5],nil,t3)
|
127
|
+
t9 = BlockType.new([t1,t5,t4],nil,t3)
|
128
|
+
t10 = BlockType.new([t1,t4],nil,t3)
|
129
|
+
t11 = BlockType.new([],nil,t3)
|
130
|
+
t12 = BlockType.new([t1,t4,t5],BlockType.new([t1,t4,t5],nil,t3),t3)
|
131
|
+
assert(t7.eql?(t8), msg(t7, t8))
|
132
|
+
assert(!t7.eql?(t9), msg(t7, t9, true))
|
133
|
+
assert(!t7.eql?(t10), msg(t7, t10, true))
|
134
|
+
assert(!t7.eql?(t11), msg(t7, t11, true))
|
135
|
+
assert(!t7.eql?(t12), msg(t7, t12, true))
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_method_no_arg
|
139
|
+
t1 = NominalType.new(String)
|
140
|
+
t2 = NominalType.new(String)
|
141
|
+
t3 = NominalType.new(Fixnum)
|
142
|
+
t4 = MethodType.new(:foo,[],nil,t1)
|
143
|
+
t5 = MethodType.new(:foo,[],nil,t2)
|
144
|
+
t6 = MethodType.new(:bar,[],nil,t2)
|
145
|
+
t7 = MethodType.new(:foo,[],nil,t3)
|
146
|
+
assert(t4.eql?(t5), msg(t4, t5))
|
147
|
+
assert(!t4.eql?(t6), msg(t4, t6, true))
|
148
|
+
assert(!t4.eql?(t7), msg(t4, t7, true))
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_method_one_arg
|
152
|
+
t1 = NominalType.new(String)
|
153
|
+
t2 = NominalType.new(String)
|
154
|
+
t3 = NominalType.new(Fixnum)
|
155
|
+
t4 = MethodType.new(:foo, [t1],nil,t3)
|
156
|
+
t5 = MethodType.new(:foo, [t2],nil,t3)
|
157
|
+
t6 = MethodType.new(:foo, [],nil,t3)
|
158
|
+
assert(t4.eql?(t5), msg(t4, t5))
|
159
|
+
assert(!t4.eql?(t6), msg(t4, t6, true))
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_method_one_arg_with_blk
|
163
|
+
t1 = NominalType.new(String)
|
164
|
+
t2 = NominalType.new(String)
|
165
|
+
t3 = NominalType.new(Fixnum)
|
166
|
+
t4 = BlockType.new([t1],nil,t3)
|
167
|
+
t5 = BlockType.new([t2],nil,t3)
|
168
|
+
t6 = BlockType.new([],nil,t3)
|
169
|
+
t7 = MethodType.new(:foo, [t1], t4, t3)
|
170
|
+
t8 = MethodType.new(:foo, [t2], t5, t3)
|
171
|
+
t9 = MethodType.new(:bar, [t1], t4, t3)
|
172
|
+
t10 = MethodType.new(:foo, [t1], t6, t3)
|
173
|
+
assert(t7.eql?(t8), msg(t7, t8))
|
174
|
+
assert(!t7.eql?(t9), msg(t7, t9, true))
|
175
|
+
assert(!t7.eql?(t10), msg(t7, t10, true))
|
176
|
+
end
|
177
|
+
|
178
|
+
def test_method_more_args
|
179
|
+
t1 = NominalType.new(String)
|
180
|
+
t2 = NominalType.new(String)
|
181
|
+
t3 = NominalType.new(Fixnum)
|
182
|
+
t4 = OptionalType.new(NominalType.new(Object))
|
183
|
+
t5 = VarLengthType.new(NominalType.new(String))
|
184
|
+
t6 = NominalType.new(BasicObject)
|
185
|
+
t7 = MethodType.new(:foo, [t1,t4,t5],nil,t3)
|
186
|
+
t8 = MethodType.new(:foo, [t2,t4,t5],nil,t3)
|
187
|
+
t9 = MethodType.new(:foo, [t1,t5,t4],nil,t3)
|
188
|
+
t10 = MethodType.new(:foo, [t1,t4],nil,t3)
|
189
|
+
t11 = MethodType.new(:foo, [],nil,t3)
|
190
|
+
t12 = MethodType.new(:foo, [t1,t4,t5],BlockType.new([t1,t4,t5],nil,t3),t3)
|
191
|
+
assert(t7.eql?(t8), msg(t7, t8))
|
192
|
+
assert(!t7.eql?(t9), msg(t7, t9, true))
|
193
|
+
assert(!t7.eql?(t10), msg(t7, t10, true))
|
194
|
+
assert(!t7.eql?(t11), msg(t7, t11, true))
|
195
|
+
assert(!t7.eql?(t12), msg(t7, t12, true))
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_method_lists
|
199
|
+
t1 = NominalType.new(String)
|
200
|
+
t2 = NominalType.new(String)
|
201
|
+
t3 = NominalType.new(Fixnum)
|
202
|
+
t4 = MethodType.new(:foo,[],nil,t1)
|
203
|
+
t5 = MethodType.new(:foo,[],nil,t2)
|
204
|
+
t6 = MethodType.new(:bar,[],nil,t2)
|
205
|
+
t7 = MethodType.new(:foo,[],nil,t3)
|
206
|
+
t8 = MethodListType.new([t4,t6])
|
207
|
+
t9 = MethodListType.new([t5,t7])
|
208
|
+
assert(!t8.eql?(t9), msg(t8, t9, true))
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# This test verifies type signature parser for RubyBreaker.
|
2
|
+
|
3
|
+
dir = File.dirname(__FILE__)
|
4
|
+
|
5
|
+
require "test/unit"
|
6
|
+
require "#{dir}/../../lib/rubybreaker/type"
|
7
|
+
|
8
|
+
class GrammarTest < Test::Unit::TestCase
|
9
|
+
|
10
|
+
include RubyBreaker
|
11
|
+
|
12
|
+
def setup
|
13
|
+
@parser = Runtime::TypeSigParser::PARSER
|
14
|
+
end
|
15
|
+
|
16
|
+
def teardown
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_symbol_method_names
|
20
|
+
meth_names = [:"===", :"<=>", :"[]=",
|
21
|
+
:"==", :"!=", :"<<", :">>", :"[]", :"**",
|
22
|
+
:"<=", :">=", :"-@", :"=~",
|
23
|
+
:"<", :">", :"&", :"|", :"*", :"/",
|
24
|
+
:"%", :"+", :"-", :"^"]
|
25
|
+
meth_names.each do |meth_name|
|
26
|
+
type = @parser.parse("#{meth_name}() -> basic_object").value
|
27
|
+
str = TypeUnparser.unparse(type)
|
28
|
+
assert_equal("#{meth_name}() -> basic_object", str)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_method_type_no_arg_no_blk
|
33
|
+
type = @parser.parse("foo() -> basic_object").value
|
34
|
+
str = TypeUnparser.unparse(type)
|
35
|
+
#puts str
|
36
|
+
assert_equal("foo() -> basic_object", str)
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_method_type_nil_ret
|
40
|
+
type = @parser.parse("foo() -> nil").value
|
41
|
+
str = TypeUnparser.unparse(type)
|
42
|
+
#puts str
|
43
|
+
assert_equal("foo() -> nil", str)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_method_type_self_ret
|
47
|
+
type = @parser.parse("foo() -> self").value
|
48
|
+
str = TypeUnparser.unparse(type)
|
49
|
+
#puts str
|
50
|
+
assert_equal("foo() -> self", str)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_method_type_any_type1
|
54
|
+
type = @parser.parse("foo() -> ?").value
|
55
|
+
str = TypeUnparser.unparse(type)
|
56
|
+
#puts str
|
57
|
+
assert_equal("foo() -> ?", str)
|
58
|
+
end
|
59
|
+
|
60
|
+
# def test_method_type_any_type2
|
61
|
+
# type = @parser.parse("foo() -> []").value
|
62
|
+
# str = TypeUnparser.unparse(type)
|
63
|
+
# #puts str
|
64
|
+
# assert_equal("foo() -> ?", str)
|
65
|
+
# end
|
66
|
+
|
67
|
+
def test_method_type_one_arg_no_blk
|
68
|
+
type = @parser.parse("foo(fixnum) -> fixnum").value
|
69
|
+
str = TypeUnparser.unparse(type)
|
70
|
+
#puts str
|
71
|
+
assert_equal("foo(fixnum) -> fixnum",str)
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_method_type_two_args_no_blk
|
75
|
+
type = @parser.parse("foo(fixnum,string) -> fixnum").value
|
76
|
+
str = TypeUnparser.unparse(type)
|
77
|
+
#puts str
|
78
|
+
assert_equal("foo(fixnum, string) -> fixnum",str)
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_method_type_or_args_no_blk
|
82
|
+
type = @parser.parse("foo(fixnum || string) -> fixnum").value
|
83
|
+
str = TypeUnparser.unparse(type)
|
84
|
+
#puts str
|
85
|
+
assert_equal("foo(fixnum || string) -> fixnum",str)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_method_type_one_arg_empty_blk
|
89
|
+
type = @parser.parse("foo(fixnum) { } -> fixnum").value
|
90
|
+
str = TypeUnparser.unparse(type)
|
91
|
+
#puts str
|
92
|
+
assert_equal("foo(fixnum) -> fixnum",str)
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_method_type_opt_arg_empty_blk
|
96
|
+
type = @parser.parse("foo(fixnum?) { } -> fixnum").value
|
97
|
+
str = TypeUnparser.unparse(type)
|
98
|
+
assert_equal("foo(fixnum?) -> fixnum",str)
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_method_type_opt_or_arg_empty_blk
|
102
|
+
type = @parser.parse("foo((fixnum || string)?) { } -> fixnum").value
|
103
|
+
str = TypeUnparser.unparse(type)
|
104
|
+
assert_equal("foo((fixnum || string)?) -> fixnum",str)
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_method_type_varlen_or_arg_empty_blk
|
108
|
+
type = @parser.parse("foo((fixnum || string)*) { } -> fixnum").value
|
109
|
+
str = TypeUnparser.unparse(type)
|
110
|
+
assert_equal("foo((fixnum || string)*) -> fixnum",str)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_method_type_opt_args_empty_blk
|
114
|
+
type = @parser.parse("foo(string, symbol?, fixnum?) { } -> fixnum").value
|
115
|
+
str = TypeUnparser.unparse(type)
|
116
|
+
assert_equal("foo(string, symbol?, fixnum?) -> fixnum",str)
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_method_type_varlen_arg_empty_blk
|
120
|
+
type = @parser.parse("foo(fixnum*) { } -> fixnum").value
|
121
|
+
str = TypeUnparser.unparse(type)
|
122
|
+
assert_equal("foo(fixnum*) -> fixnum",str)
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_method_type_opt_args_varlen_arg_empty_blk
|
126
|
+
sig = "foo(string, symbol?, fixnum?, string*) { } -> fixnum"
|
127
|
+
type = @parser.parse(sig).value
|
128
|
+
str = TypeUnparser.unparse(type)
|
129
|
+
assert_equal("foo(string, symbol?, fixnum?, string*) -> fixnum",str)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_method_type_one_arg_blk
|
133
|
+
type = @parser.parse("foo(fixnum) {|fixnum| -> string} -> fixnum").value
|
134
|
+
str = TypeUnparser.unparse(type)
|
135
|
+
#puts str
|
136
|
+
assert_equal("foo(fixnum) {|fixnum| -> string} -> fixnum",str)
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_method_type_blk_two_args
|
140
|
+
sig = "foo() {|fixnum,string| -> string} -> fixnum"
|
141
|
+
type = @parser.parse(sig).value
|
142
|
+
str = TypeUnparser.unparse(type)
|
143
|
+
#puts str
|
144
|
+
assert_equal("foo() {|fixnum, string| -> string} -> fixnum",str)
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_method_blk_two_args
|
148
|
+
sig = "foo(fixnum) {|fixnum,float| -> string} -> fixnum"
|
149
|
+
type = @parser.parse(sig).value
|
150
|
+
str = TypeUnparser.unparse(type)
|
151
|
+
#puts str
|
152
|
+
assert_equal("foo(fixnum) {|fixnum, float| -> string} -> fixnum",str)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_method_type_blk_three_args_opt_args
|
156
|
+
sig = "foo() {|fixnum,string?, float?| -> string} -> fixnum"
|
157
|
+
type = @parser.parse(sig).value
|
158
|
+
str = TypeUnparser.unparse(type)
|
159
|
+
#puts str
|
160
|
+
assert_equal("foo() {|fixnum, string?, float?| -> string} -> fixnum",str)
|
161
|
+
end
|
162
|
+
|
163
|
+
def test_method_type_blk_three_args_varlen_arg
|
164
|
+
sig = "foo() {|fixnum,string, float*| -> string} -> fixnum"
|
165
|
+
type = @parser.parse(sig).value
|
166
|
+
str = TypeUnparser.unparse(type)
|
167
|
+
#puts str
|
168
|
+
assert_equal("foo() {|fixnum, string, float*| -> string} -> fixnum",str)
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_method_type_blk_three_args_opt_varlen_args
|
172
|
+
sig = "foo() {|fixnum,string?, float*| -> string} -> fixnum"
|
173
|
+
type = @parser.parse(sig).value
|
174
|
+
str = TypeUnparser.unparse(type)
|
175
|
+
#puts str
|
176
|
+
assert_equal("foo() {|fixnum, string?, float*| -> string} -> fixnum",str)
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_method_duck_arg
|
180
|
+
type = @parser.parse("foo([m1]) -> fixnum").value
|
181
|
+
str = TypeUnparser.unparse(type)
|
182
|
+
#puts str
|
183
|
+
assert_equal("foo([m1]) -> fixnum",str)
|
184
|
+
end
|
185
|
+
|
186
|
+
def test_method_duck_arg_more_methods
|
187
|
+
type = @parser.parse("foo([m1,m2,m3?]) -> fixnum").value
|
188
|
+
str = TypeUnparser.unparse(type)
|
189
|
+
#puts str
|
190
|
+
assert_equal("foo([m1, m2, m3?]) -> fixnum",str)
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_method_fusion_arg
|
194
|
+
type = @parser.parse("foo(fixnum[to_s]) -> fixnum").value
|
195
|
+
str = TypeUnparser.unparse(type)
|
196
|
+
#puts str
|
197
|
+
assert_equal("foo(fixnum[to_s]) -> fixnum",str)
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_method_fusion_arg_more_methods
|
201
|
+
type = @parser.parse("foo(fixnum[to_s,to_i]) -> fixnum").value
|
202
|
+
str = TypeUnparser.unparse(type)
|
203
|
+
#puts str
|
204
|
+
assert_equal("foo(fixnum[to_i, to_s]) -> fixnum",str)
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_space_around
|
208
|
+
type = @parser.parse(" foo() -> nil ").value
|
209
|
+
str = TypeUnparser.unparse(type)
|
210
|
+
#puts str
|
211
|
+
assert_equal("foo() -> nil", str)
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_parse_fail_no_methname
|
215
|
+
type = @parser.parse("() -> nil")
|
216
|
+
assert_equal(nil, type, "Type signature without a method name")
|
217
|
+
end
|
218
|
+
|
219
|
+
end
|