rubybreaker 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/AUTHORS +7 -0
  2. data/LICENSE +26 -0
  3. data/README.md +403 -0
  4. data/Rakefile +90 -0
  5. data/TODO +30 -0
  6. data/bin/gen_stub_rubylib +64 -0
  7. data/bin/rubybreaker +67 -0
  8. data/lib/rubybreaker/context.rb +122 -0
  9. data/lib/rubybreaker/debug.rb +48 -0
  10. data/lib/rubybreaker/error.rb +59 -0
  11. data/lib/rubybreaker/rubylib/core.rb +2316 -0
  12. data/lib/rubybreaker/rubylib.rb +3 -0
  13. data/lib/rubybreaker/runtime/inspector.rb +57 -0
  14. data/lib/rubybreaker/runtime/monitor.rb +235 -0
  15. data/lib/rubybreaker/runtime/object_wrapper.rb +77 -0
  16. data/lib/rubybreaker/runtime/overrides.rb +42 -0
  17. data/lib/rubybreaker/runtime/pluggable.rb +57 -0
  18. data/lib/rubybreaker/runtime/type_placeholder.rb +27 -0
  19. data/lib/rubybreaker/runtime/type_system.rb +228 -0
  20. data/lib/rubybreaker/runtime/typesig_parser.rb +45 -0
  21. data/lib/rubybreaker/runtime.rb +103 -0
  22. data/lib/rubybreaker/test/testcase.rb +39 -0
  23. data/lib/rubybreaker/test.rb +1 -0
  24. data/lib/rubybreaker/type/type.rb +241 -0
  25. data/lib/rubybreaker/type/type_comparer.rb +143 -0
  26. data/lib/rubybreaker/type/type_grammar.treetop +285 -0
  27. data/lib/rubybreaker/type/type_unparser.rb +142 -0
  28. data/lib/rubybreaker/type.rb +2 -0
  29. data/lib/rubybreaker/typing/rubytype.rb +47 -0
  30. data/lib/rubybreaker/typing/subtyping.rb +480 -0
  31. data/lib/rubybreaker/typing.rb +3 -0
  32. data/lib/rubybreaker/util.rb +31 -0
  33. data/lib/rubybreaker.rb +193 -0
  34. data/test/integrated/tc_method_missing.rb +30 -0
  35. data/test/integrated/tc_simple1.rb +77 -0
  36. data/test/runtime/tc_obj_wrapper.rb +73 -0
  37. data/test/runtime/tc_typesig_parser.rb +33 -0
  38. data/test/ts_integrated.rb +4 -0
  39. data/test/ts_runtime.rb +5 -0
  40. data/test/ts_type.rb +5 -0
  41. data/test/ts_typing.rb +4 -0
  42. data/test/type/tc_comparer.rb +211 -0
  43. data/test/type/tc_parser.rb +219 -0
  44. data/test/type/tc_unparser.rb +276 -0
  45. data/test/typing/tc_rubytype.rb +63 -0
  46. data/test/typing/tc_typing.rb +219 -0
  47. data/webpage/footer.html +5 -0
  48. data/webpage/generated_toc.js +319 -0
  49. data/webpage/header.html +14 -0
  50. data/webpage/images/logo.png +0 -0
  51. data/webpage/index.html +439 -0
  52. data/webpage/rubybreaker.css +53 -0
  53. 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
@@ -0,0 +1,4 @@
1
+
2
+ require "test/unit"
3
+ require_relative "integrated/tc_method_missing"
4
+ require_relative "integrated/tc_simple1"
@@ -0,0 +1,5 @@
1
+
2
+ require "test/unit"
3
+ require_relative "runtime/tc_obj_wrapper"
4
+ require_relative "runtime/tc_typesig_parser"
5
+
data/test/ts_type.rb ADDED
@@ -0,0 +1,5 @@
1
+
2
+ require "test/unit"
3
+ require_relative "type/tc_comparer"
4
+ require_relative "type/tc_parser"
5
+ require_relative "type/tc_unparser"
data/test/ts_typing.rb ADDED
@@ -0,0 +1,4 @@
1
+
2
+ require "test/unit"
3
+ require_relative "typing/tc_rubytype"
4
+ require_relative "typing/tc_typing"
@@ -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