rubybreaker 0.0.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.
- 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
|