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