rdl 1.0.0.rc3 → 1.0.0.rc4

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +44 -0
  3. data/.travis.yml +19 -0
  4. data/LICENSE +29 -0
  5. data/README.md +509 -0
  6. data/Rakefile +27 -0
  7. data/gemfiles/Gemfile.travis +5 -0
  8. data/lib/rdl/wrap.rb +1 -1
  9. data/lib/rdl_types.rb +4 -2
  10. data/rdl.gemspec +23 -0
  11. data/test/disabled_test_coverage.rb +156 -0
  12. data/test/disabled_test_rdoc.rb +116 -0
  13. data/test/test_alias.rb +66 -0
  14. data/test/test_contract.rb +70 -0
  15. data/test/test_dsl.rb +85 -0
  16. data/test/test_generic.rb +188 -0
  17. data/test/test_intersection.rb +41 -0
  18. data/test/test_le.rb +193 -0
  19. data/test/test_lib_types.rb +194 -0
  20. data/test/test_member.rb +148 -0
  21. data/test/test_parser.rb +196 -0
  22. data/test/test_rdl.rb +301 -0
  23. data/test/test_rdl_type.rb +70 -0
  24. data/test/test_type_contract.rb +187 -0
  25. data/test/test_types.rb +221 -0
  26. data/test/test_wrap.rb +46 -0
  27. data/types/{ruby-2.2.0 → ruby-2.x}/_aliases.rb +0 -0
  28. data/types/{ruby-2.2.0 → ruby-2.x}/abbrev.rb +2 -2
  29. data/types/{ruby-2.2.0 → ruby-2.x}/array.rb +2 -2
  30. data/types/{ruby-2.2.0 → ruby-2.x}/base64.rb +2 -2
  31. data/types/{ruby-2.2.0 → ruby-2.x}/basic_object.rb +2 -1
  32. data/types/{ruby-2.2.0 → ruby-2.x}/benchmark.rb +2 -2
  33. data/types/{ruby-2.2.0 → ruby-2.x}/bigdecimal.rb +4 -4
  34. data/types/{ruby-2.2.0 → ruby-2.x}/bigmath.rb +2 -2
  35. data/types/{ruby-2.2.0 → ruby-2.x}/class.rb +3 -3
  36. data/types/{ruby-2.2.0 → ruby-2.x}/complex.rb +2 -2
  37. data/types/{ruby-2.2.0 → ruby-2.x}/coverage.rb +2 -2
  38. data/types/{ruby-2.2.0 → ruby-2.x}/csv.rb +2 -2
  39. data/types/{ruby-2.2.0 → ruby-2.x}/date.rb +2 -2
  40. data/types/{ruby-2.2.0 → ruby-2.x}/dir.rb +3 -3
  41. data/types/{ruby-2.2.0 → ruby-2.x}/encoding.rb +2 -2
  42. data/types/{ruby-2.2.0 → ruby-2.x}/enumerable.rb +2 -2
  43. data/types/{ruby-2.2.0 → ruby-2.x}/enumerator.rb +1 -1
  44. data/types/{ruby-2.2.0 → ruby-2.x}/exception.rb +2 -0
  45. data/types/{ruby-2.2.0 → ruby-2.x}/file.rb +2 -2
  46. data/types/{ruby-2.2.0 → ruby-2.x}/fileutils.rb +1 -1
  47. data/types/{ruby-2.2.0 → ruby-2.x}/fixnum.rb +2 -2
  48. data/types/{ruby-2.2.0 → ruby-2.x}/float.rb +2 -2
  49. data/types/{ruby-2.2.0 → ruby-2.x}/gem.rb +3 -1
  50. data/types/{ruby-2.2.0 → ruby-2.x}/hash.rb +2 -2
  51. data/types/{ruby-2.2.0 → ruby-2.x}/integer.rb +2 -2
  52. data/types/{ruby-2.2.0 → ruby-2.x}/io.rb +1 -1
  53. data/types/{ruby-2.2.0 → ruby-2.x}/kernel.rb +1 -1
  54. data/types/{ruby-2.2.0 → ruby-2.x}/marshal.rb +2 -2
  55. data/types/{ruby-2.2.0 → ruby-2.x}/matchdata.rb +3 -3
  56. data/types/{ruby-2.2.0 → ruby-2.x}/math.rb +2 -2
  57. data/types/{ruby-2.2.0 → ruby-2.x}/numeric.rb +2 -2
  58. data/types/{ruby-2.2.0 → ruby-2.x}/object.rb +1 -1
  59. data/types/{ruby-2.2.0 → ruby-2.x}/pathname.rb +2 -2
  60. data/types/{ruby-2.2.0 → ruby-2.x}/process.rb +8 -8
  61. data/types/{ruby-2.2.0 → ruby-2.x}/random.rb +2 -2
  62. data/types/{ruby-2.2.0 → ruby-2.x}/range.rb +2 -2
  63. data/types/{ruby-2.2.0 → ruby-2.x}/rational.rb +2 -2
  64. data/types/{ruby-2.2.0 → ruby-2.x}/regexp.rb +2 -2
  65. data/types/{ruby-2.2.0 → ruby-2.x}/set.rb +2 -2
  66. data/types/{ruby-2.2.0 → ruby-2.x}/string.rb +1 -1
  67. data/types/{ruby-2.2.0 → ruby-2.x}/strscan.rb +3 -3
  68. data/types/{ruby-2.2.0 → ruby-2.x}/symbol.rb +2 -2
  69. data/types/{ruby-2.2.0 → ruby-2.x}/time.rb +2 -2
  70. data/types/ruby-2.x/uri.rb +20 -0
  71. data/types/{ruby-2.2.0 → ruby-2.x}/yaml.rb +3 -3
  72. metadata +70 -51
  73. data/lib/rdl/types/wild.rb +0 -26
  74. data/types/other/chronic.rb +0 -5
  75. data/types/other/paperclip_attachment.rb +0 -7
  76. data/types/other/securerandom.rb +0 -4
  77. data/types/ruby-2.2.0/uri.rb +0 -18
@@ -0,0 +1,194 @@
1
+ require 'set'
2
+ require 'abbrev'
3
+ require 'base64'
4
+ require 'benchmark'
5
+ require 'bigdecimal'
6
+ require 'bigdecimal/math'
7
+ require 'coverage.so'
8
+ require 'uri'
9
+
10
+ require 'minitest/autorun'
11
+ require_relative '../lib/rdl.rb'
12
+ require_relative '../lib/rdl_types.rb'
13
+
14
+ class Dummy
15
+ def self.each
16
+ end
17
+ def each
18
+ end
19
+ end
20
+
21
+ class TestStdlibTypes < Minitest::Test
22
+
23
+ def test_abbrev
24
+ skip "Skip when nowrap is enabled"
25
+ assert_raises(RDL::Type::TypeError) { s0 = Abbrev.abbrev 5}
26
+ # From the Ruby stdlib documentation
27
+ s1 = Abbrev.abbrev(['ruby']) # -> {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"}
28
+ ev = {"ruby"=>"ruby", "rub"=>"ruby", "ru"=>"ruby", "r"=>"ruby"}
29
+ assert_equal(s1,ev)
30
+ # Other tests
31
+ assert_raises(RDL::Type::TypeError) { s2 = Abbrev.abbrev Dummy.new }
32
+ end
33
+
34
+ def test_base64
35
+ skip "Skip when nowrap is enabled"
36
+ # From the Ruby stdlib documentation
37
+ e0 = Base64.encode64('Send reinforcements') # -> "U2VuZCByZWluZm9yY2VtZW50cw==\n"
38
+ d0 = Base64.decode64(e0) # -> "Send reinforcements"
39
+ #assert_equal(e0,d0)
40
+ e1 = Base64.strict_encode64('Send reinforcements')
41
+ d1 = Base64.strict_decode64(e1)
42
+ #assert_equal(e1,d1)
43
+ e2 = Base64.urlsafe_encode64('Send reinforcements')
44
+ d2 = Base64.urlsafe_decode64(e2)
45
+ #assert_equal(e2,d2)
46
+ end
47
+
48
+ def test_benchmark
49
+ skip "Skip these because they print to stdout"
50
+ # From the Ruby stdlib documentation
51
+ Benchmark.measure { "a"*1_000_000_000 }
52
+ n = 5000000
53
+ Benchmark.bm do |x|
54
+ x.report { for i in 1..n; a = "1"; end }
55
+ x.report { n.times do ; a = "1"; end }
56
+ x.report { 1.upto(n) do ; a = "1"; end }
57
+ end
58
+ Benchmark.bm(7) do |x|
59
+ x.report("for:") { for i in 1..n; a = "1"; end }
60
+ x.report("times:") { n.times do ; a = "1"; end }
61
+ x.report("upto:") { 1.upto(n) do ; a = "1"; end }
62
+ end
63
+ array = (1..1000000).map { rand }
64
+ Benchmark.bmbm do |x|
65
+ #x.report("sort!") { array.dup.sort! } # TODO this causes a hang
66
+ #x.report("sort") { array.dup.sort }
67
+ end
68
+ Benchmark.benchmark(Benchmark::CAPTION, 7, Benchmark::FORMAT, ">total:", ">avg:") do |x|
69
+ tf = x.report("for:") { for i in 1..n; a = "1"; end }
70
+ tt = x.report("times:") { n.times do ; a = "1"; end }
71
+ tu = x.report("upto:") { 1.upto(n) do ; a = "1"; end }
72
+ [tf+tt+tu, (tf+tt+tu)/3]
73
+ end
74
+ end
75
+
76
+ def test_bigdecimal
77
+ skip "Skip when nowrap is enabled"
78
+ # From the RUby stdlib documentation
79
+ BigDecimal.save_exception_mode do
80
+ BigDecimal.mode(BigDecimal::EXCEPTION_OVERFLOW, false)
81
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
82
+
83
+ BigDecimal.new(BigDecimal('Infinity'))
84
+ BigDecimal.new(BigDecimal('-Infinity'))
85
+ BigDecimal(BigDecimal.new('NaN'))
86
+ end
87
+ BigDecimal.save_limit do
88
+ BigDecimal.limit(200)
89
+ end
90
+ BigDecimal.save_rounding_mode do
91
+ BigDecimal.mode(BigDecimal::ROUND_MODE, :up)
92
+ end
93
+ # Additional test calls for coverage
94
+ BigDecimal.double_fig
95
+ BigDecimal.limit(5)
96
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, true)
97
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN, false)
98
+ BigDecimal.mode(BigDecimal::EXCEPTION_NaN)
99
+ BigDecimal.ver
100
+
101
+ # TODO
102
+ end
103
+
104
+ def test_bigmath
105
+ # From the Ruby stdlib documentation
106
+ BigMath.E(10)
107
+ BigMath.PI(10)
108
+ BigMath.atan(BigDecimal.new('-1'), 16)
109
+ BigMath.cos(BigMath.PI(4), 16)
110
+ BigMath.sin(BigMath.PI(5)/4, 5)
111
+ BigMath.sqrt(BigDecimal.new('2'), 16)
112
+ end
113
+
114
+ def test_class
115
+ Dummy.allocate
116
+ Dummy.new
117
+ Dummy.superclass
118
+ end
119
+
120
+ def test_coverage
121
+ skip "Skip when nowrap is enabled"
122
+ Coverage.start
123
+ Coverage.result
124
+ #Coverage.result # TODO This cannot be typechecked
125
+ end
126
+
127
+ def test_exception
128
+ e1 = Exception.new
129
+ e1 == 5
130
+ tmp = e1.backtrace
131
+ e1.backtrace_locations
132
+ e1.cause
133
+ e1.exception
134
+ e1.inspect
135
+ e1.message
136
+ e1.set_backtrace(tmp)
137
+ e1.to_s
138
+ end
139
+
140
+ def test_set
141
+ skip "Skip when nowrap is enabled"
142
+ assert_raises(RDL::Type::TypeError) { s6 = Set.new(1,2) }
143
+ # From the Ruby stdlib documentation
144
+ s1 = Set.new [1, 2] # -> #<Set: {1, 2}>
145
+ s2 = [1, 2].to_set # -> #<Set: {1, 2}>
146
+ s1 == s2 # -> true
147
+ s1.add("foo") # -> #<Set: {1, 2, "foo"}>
148
+ s1.merge([2, 6]) # -> #<Set: {1, 2, "foo", 6}>
149
+ s1.subset? s2 # -> false
150
+ s2.subset? s1 # -> true
151
+ Set[1, 2, 3].disjoint? Set[3, 4] # => false
152
+ Set[1, 2, 3].disjoint? Set[4, 5] # => true
153
+ numbers = Set[1, 3, 4, 6, 9, 10, 11]
154
+ set = numbers.divide { |i,j| (i - j).abs == 1 }
155
+ Set[1, 2, 3].intersect? Set[4, 5] # => false
156
+ Set[1, 2, 3].intersect? Set[3, 4] # => true
157
+ # Some more tests, just to make sure type checking doesn't cause crashes
158
+ s3 = s1 - s2
159
+ s1.proper_subset? s2
160
+ s1.superset? s2
161
+ s1 ^ s2
162
+ s1.add?("bar")
163
+ h = s1.classify { |x| x.size }
164
+ s2.clear
165
+ s4 = s1.map { |x| 42 }
166
+ s1.delete "foo"
167
+ s1.delete? "bar"
168
+ s1.delete_if { |x| false }
169
+ s1.each { |x| nil }
170
+ s1.empty?
171
+ s1.member? 42
172
+ s1.intersection [1,2,3]
173
+ s1.keep_if { |x| true }
174
+ s1.size
175
+ s1.difference [1,2,3]
176
+ s1.to_a
177
+ s5 = s1 + s2
178
+ end
179
+
180
+ def test_uri
181
+ URI.decode_www_form("a=1&a=2&b=3")
182
+ URI.encode_www_form([["q", "ruby"], ["lang", "en"]]) # Internally uses _component
183
+ URI.encode_www_form("q" => "ruby", "lang" => "en")
184
+ URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
185
+ URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
186
+ URI.extract("text here http://foo.example.org/bla and here mailto:test@example.com and here also.")
187
+ URI.join("http://example.com/","main.rbx")
188
+ URI.parse("http://www.ruby-lang.org/")
189
+ URI.scheme_list
190
+ URI.split("http://www.ruby-lang.org/")
191
+ enc_uri = URI.escape("http://example.com/?a=\11\15")
192
+ URI.unescape(enc_uri)
193
+ end
194
+ end
@@ -0,0 +1,148 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestMember < Minitest::Test
5
+ include RDL::Type
6
+
7
+ class A
8
+ end
9
+
10
+ class B < A
11
+ end
12
+
13
+ class C < B
14
+ end
15
+
16
+ def setup
17
+ @tnil = NilType.new
18
+ @ttop = TopType.new
19
+ @tstring = NominalType.new "String"
20
+ @tobject = NominalType.new "Object"
21
+ @tbasicobject = NominalType.new "BasicObject"
22
+ @tsymfoo = SingletonType.new :foo
23
+ @tsym = NominalType.new Symbol
24
+ @tarray = NominalType.new Array
25
+ @tarraystring = GenericType.new(@tarray, @tstring)
26
+ @tarrayobject = GenericType.new(@tarray, @tobject)
27
+ @tarrayarraystring = GenericType.new(@tarray, @tarraystring)
28
+ @tarrayarrayobject = GenericType.new(@tarray, @tarrayobject)
29
+ @thash = NominalType.new Hash
30
+ @thashstringstring = GenericType.new(@thash, @tstring, @tstring)
31
+ @thashobjectobject = GenericType.new(@thash, @tobject, @tobject)
32
+ @tstring_or_sym = UnionType.new(@tstring, @tsym)
33
+ @tstring_and_sym = IntersectionType.new(@tstring, @tsym)
34
+ @tobject_and_basicobject = IntersectionType.new(@tobject, @tbasicobject)
35
+ @ta = NominalType.new A
36
+ @tb = NominalType.new B
37
+ @tc = NominalType.new C
38
+ @tkernel = NominalType.new Kernel
39
+ @tarray = NominalType.new Array
40
+ @tarraystring = GenericType.new(@tarray, @tstring)
41
+ @tarrayobject = GenericType.new(@tarray, @tobject)
42
+ @tarrayarraystring = GenericType.new(@tarray, @tarraystring)
43
+ @tarrayarrayobject = GenericType.new(@tarray, @tarrayobject)
44
+ @thash = NominalType.new Hash
45
+ @thashsymstring = GenericType.new(@thash, @tsym, @tstring)
46
+ @thashobjectobject = GenericType.new(@thash, @tobject, @tobject)
47
+ @tavar = VarType.new :a
48
+ end
49
+
50
+ def test_nil
51
+ assert (@tnil.member? nil)
52
+ assert (not (@tnil.member? "foo"))
53
+ assert (not (@tnil.member? (Object.new)))
54
+ end
55
+
56
+ def test_top
57
+ assert (@ttop.member? nil)
58
+ assert (@ttop.member? "foo")
59
+ assert (@ttop.member? (Object.new))
60
+ end
61
+
62
+ def test_nominal
63
+ o = Object.new
64
+ assert (@tstring.member? "Foo")
65
+ assert (not (@tstring.member? :Foo))
66
+ assert (not (@tstring.member? o))
67
+
68
+ assert (@tobject.member? "Foo")
69
+ assert (@tobject.member? :Foo)
70
+ assert (@tobject.member? o)
71
+
72
+ assert (@tkernel.member? "Foo")
73
+ assert (@tkernel.member? :Foo)
74
+ assert (@tkernel.member? o)
75
+
76
+ a = A.new
77
+ b = B.new
78
+ c = C.new
79
+ assert (@ta.member? a)
80
+ assert (@ta.member? b)
81
+ assert (@ta.member? c)
82
+ assert (not (@tb.member? a))
83
+ assert (@tb.member? b)
84
+ assert (@tb.member? c)
85
+ assert (not (@tc.member? a))
86
+ assert (not (@tc.member? b))
87
+ assert (@tc.member? c)
88
+
89
+ assert (@tstring.member? nil)
90
+ assert (@tobject.member? nil)
91
+ end
92
+
93
+ def test_symbol
94
+ assert (@tsym.member? :foo)
95
+ assert (@tsym.member? :bar)
96
+ assert (not (@tsym.member? "foo"))
97
+ assert (@tsymfoo.member? :foo)
98
+ assert (not (@tsymfoo.member? :bar))
99
+ assert (not (@tsymfoo.member? "foo"))
100
+ assert (@tsymfoo.member? nil)
101
+ end
102
+
103
+ def test_union_intersection
104
+ o = Object.new
105
+
106
+ assert (@tstring_or_sym.member? "foo")
107
+ assert (@tstring_or_sym.member? :foo)
108
+ assert (not (@tstring_or_sym.member? o))
109
+ assert (@tstring_or_sym.member? nil)
110
+
111
+ assert (not (@tstring_and_sym.member? "foo"))
112
+ assert (not (@tstring_and_sym.member? :foo))
113
+ assert (not (@tstring_and_sym.member? o))
114
+ assert (@tstring_and_sym.member? nil)
115
+
116
+ assert (@tobject_and_basicobject.member? o)
117
+ assert (@tobject_and_basicobject.member? nil)
118
+ end
119
+
120
+ def test_var
121
+ assert_raises(TypeError) { @tavar.member? "foo" }
122
+ end
123
+
124
+ def test_tuple
125
+ t1 = TupleType.new(@tsym, @tstring)
126
+ assert (t1.member? [:foo, "foo"])
127
+ assert (not (t1.member? ["foo", :foo]))
128
+ assert (not (t1.member? [:foo, "foo", "bar"]))
129
+ t2 = TupleType.new
130
+ assert (t2.member? [])
131
+ assert (not (t2.member? [:foo]))
132
+ end
133
+
134
+ def test_finite_hash
135
+ t1 = FiniteHashType.new(a: @tsym, b: @tstring)
136
+ assert (t1.member?(a: :foo, b: "foo"))
137
+ assert (not (t1.member?(a: 1, b: "foo")))
138
+ assert (not (t1.member?(a: :foo)))
139
+ assert (not (t1.member?(b: "foo")))
140
+ assert (not (t1.member?(a: :foo, b: "foo", c: :baz)))
141
+ t2 = FiniteHashType.new({"a"=>@tsym, 2=>@tstring})
142
+ assert (t2.member?({"a"=>:foo, 2=>"foo"}))
143
+ assert (not (t2.member?({"a"=>2, 2=>"foo"})))
144
+ assert (not (t2.member?({"a"=>:foo})))
145
+ assert (not (t2.member?({2=>"foo"})))
146
+ assert (not (t2.member?({"a"=>:foo, 2=>"foo", 3=>"bar"})))
147
+ end
148
+ end
@@ -0,0 +1,196 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestParser < Minitest::Test
5
+ include RDL::Type
6
+
7
+ def setup
8
+ @p = Parser.new
9
+ @tnil = NilType.new
10
+ @ttop = TopType.new
11
+ @tfixnum = NominalType.new Fixnum
12
+ @tfixnumopt = OptionalType.new @tfixnum
13
+ @tfixnumvararg = VarargType.new @tfixnum
14
+ @tstring = NominalType.new String
15
+ @tstringopt = OptionalType.new @tstring
16
+ @tenum = NominalType.new :Enumerator
17
+ @ttrue = NominalType.new TrueClass
18
+ @tfalse = NominalType.new FalseClass
19
+ @tbool = UnionType.new @ttrue, @tfalse
20
+ @ta = NominalType.new :A
21
+ @tb = NominalType.new :B
22
+ @tc = NominalType.new :C
23
+ @tfixnumx = AnnotatedArgType.new("x", @tfixnum)
24
+ @tfixnumy = AnnotatedArgType.new("y", @tfixnum)
25
+ @tfixnumret = AnnotatedArgType.new("ret", @tfixnum)
26
+ @tfixnumoptx = AnnotatedArgType.new("x", @tfixnumopt)
27
+ @tfixnumvarargx = AnnotatedArgType.new("x", @tfixnumvararg)
28
+ @tsymbol = SingletonType.new(:symbol)
29
+ @tsymbolx = AnnotatedArgType.new("x", @tsymbol)
30
+ end
31
+
32
+ def test_basic
33
+ t1 = @p.scan_str "(nil) -> nil"
34
+ assert_equal (MethodType.new [@tnil], nil, @tnil), t1
35
+ t2 = @p.scan_str "(Fixnum, Fixnum) -> Fixnum"
36
+ assert_equal (MethodType.new [@tfixnum, @tfixnum], nil, @tfixnum), t2
37
+ t3 = @p.scan_str "() -> Enumerator"
38
+ assert_equal (MethodType.new [], nil, @tenum), t3
39
+ t4 = @p.scan_str "(%any) -> nil"
40
+ assert_equal (MethodType.new [@ttop], nil, @tnil), t4
41
+ t5 = @p.scan_str "(%bool) -> Fixnum"
42
+ assert_equal (MethodType.new [@tbool], nil, @tfixnum), t5
43
+ assert_raises(RuntimeError) { @p.scan_str "(%foo) -> nil" }
44
+ t6 = @p.scan_str "(A) -> nil"
45
+ assert_equal (MethodType.new [@ta], nil, @tnil), t6
46
+ t7 = @p.scan_str "(TestParser::A) -> nil"
47
+ assert_equal (MethodType.new [NominalType.new("TestParser::A")], nil, @tnil), t7
48
+ t8 = @p.scan_str "(Fixnum) { (%any, String) -> nil } -> :symbol"
49
+ assert_equal (MethodType.new [@tfixnum], MethodType.new([@ttop, @tstring], nil, @tnil), @tsymbol), t8
50
+ end
51
+
52
+ def test_opt_vararg
53
+ t1 = @p.scan_str "(Fixnum, ?Fixnum) -> Fixnum"
54
+ assert_equal (MethodType.new [@tfixnum, @tfixnumopt], nil, @tfixnum), t1
55
+ t2 = @p.scan_str "(Fixnum, *Fixnum) -> Fixnum"
56
+ assert_equal (MethodType.new [@tfixnum, @tfixnumvararg], nil, @tfixnum), t2
57
+ t3 = @p.scan_str "(Fixnum, ?Fixnum, ?Fixnum, *Fixnum) -> Fixnum"
58
+ assert_equal (MethodType.new [@tfixnum, @tfixnumopt, @tfixnumopt, @tfixnumvararg], nil, @tfixnum), t3
59
+ t4 = @p.scan_str "(?Fixnum) -> nil"
60
+ assert_equal (MethodType.new [@tfixnumopt], nil, @tnil), t4
61
+ t5 = @p.scan_str "(*Fixnum) -> nil"
62
+ assert_equal (MethodType.new [@tfixnumvararg], nil, @tnil), t5
63
+ end
64
+
65
+ def test_union
66
+ t1 = @p.scan_str "(A or B) -> nil"
67
+ assert_equal (MethodType.new [UnionType.new(@ta, @tb)], nil, @tnil), t1
68
+ t2 = @p.scan_str "(A or B or C) -> nil"
69
+ assert_equal (MethodType.new [UnionType.new(@ta, @tb, @tc)], nil, @tnil), t2
70
+ t3 = @p.scan_str "() -> A or B or C"
71
+ assert_equal (MethodType.new [], nil, UnionType.new(@ta, @tb, @tc)), t3
72
+ end
73
+
74
+ def test_bare
75
+ t1 = @p.scan_str "## nil"
76
+ assert_equal @tnil, t1
77
+ t2 = @p.scan_str "## %any"
78
+ assert_equal @ttop, t2
79
+ t3 = @p.scan_str "## A"
80
+ assert_equal NominalType.new("A"), t3
81
+ end
82
+
83
+ def test_symbol
84
+ t1 = @p.scan_str "## :symbol"
85
+ assert_equal @tsymbol, t1
86
+ end
87
+
88
+ def test_annotated_params
89
+ t1 = @p.scan_str "(Fixnum x, Fixnum) -> Fixnum"
90
+ assert_equal (MethodType.new [@tfixnumx, @tfixnum], nil, @tfixnum), t1
91
+ t2 = @p.scan_str "(Fixnum, ?Fixnum x) -> Fixnum"
92
+ assert_equal (MethodType.new [@tfixnum, @tfixnumoptx], nil, @tfixnum), t2
93
+ t3 = @p.scan_str "(Fixnum, *Fixnum x) -> Fixnum"
94
+ assert_equal (MethodType.new [@tfixnum, @tfixnumvarargx], nil, @tfixnum), t3
95
+ t4 = @p.scan_str "(Fixnum, Fixnum y) -> Fixnum"
96
+ assert_equal (MethodType.new [@tfixnum, @tfixnumy], nil, @tfixnum), t4
97
+ t5 = @p.scan_str "(Fixnum x, Fixnum y) -> Fixnum"
98
+ assert_equal (MethodType.new [@tfixnumx, @tfixnumy], nil, @tfixnum), t5
99
+ t6 = @p.scan_str "(Fixnum, Fixnum) -> Fixnum ret"
100
+ assert_equal (MethodType.new [@tfixnum, @tfixnum], nil, @tfixnumret), t6
101
+ t7 = @p.scan_str "(Fixnum x, Fixnum) -> Fixnum ret"
102
+ assert_equal (MethodType.new [@tfixnumx, @tfixnum], nil, @tfixnumret), t7
103
+ t8 = @p.scan_str "(Fixnum, Fixnum y) -> Fixnum ret"
104
+ assert_equal (MethodType.new [@tfixnum, @tfixnumy], nil, @tfixnumret), t8
105
+ t9 = @p.scan_str "(Fixnum x, Fixnum y) -> Fixnum ret"
106
+ assert_equal (MethodType.new [@tfixnumx, @tfixnumy], nil, @tfixnumret), t9
107
+ t10 = @p.scan_str "(:symbol x) -> Fixnum"
108
+ assert_equal (MethodType.new [@tsymbolx], nil, @tfixnum), t10
109
+ end
110
+
111
+ def test_generic
112
+ t1 = @p.scan_str "## t"
113
+ assert_equal (VarType.new "t"), t1
114
+ t2 = @p.scan_str "## Array"
115
+ assert_equal (NominalType.new "Array"), t2
116
+ t3 = @p.scan_str "## Array<t>"
117
+ assert_equal (GenericType.new(t2, t1)), t3
118
+ t4 = @p.scan_str "## Array<Array<t>>"
119
+ assert_equal (GenericType.new(t2, t3)), t4
120
+ t5 = @p.scan_str "## Hash"
121
+ assert_equal (NominalType.new "Hash"), t5
122
+ t6 = @p.scan_str "## Hash<u, v>"
123
+ assert_equal (GenericType.new(t5, VarType.new("u"), VarType.new("v"))), t6
124
+ t7 = @p.scan_str "## Foo<String, Array<t>, Array<Array<t>>>"
125
+ assert_equal (GenericType.new(NominalType.new("Foo"), @tstring, t3, t4)), t7
126
+ end
127
+
128
+ def test_tuple
129
+ t1 = @p.scan_str "## [Fixnum, String]"
130
+ assert_equal (TupleType.new(@tfixnum, @tstring)), t1
131
+ t2 = @p.scan_str "## [String]"
132
+ assert_equal (TupleType.new(@tstring)), t2
133
+ end
134
+
135
+ def test_fixnum
136
+ t1 = @p.scan_str "## 42"
137
+ assert_equal (SingletonType.new(42)), t1
138
+ t2 = @p.scan_str "## -42"
139
+ assert_equal (SingletonType.new(-42)), t2
140
+ end
141
+
142
+ def test_float
143
+ t1 = @p.scan_str "## 3.14"
144
+ assert_equal (SingletonType.new(3.14)), t1
145
+ end
146
+
147
+ def test_const
148
+ t1 = @p.scan_str "## ${Math::PI}"
149
+ assert_equal (SingletonType.new(Math::PI)), t1
150
+ end
151
+
152
+ def test_type_alias
153
+ type_alias '%foobarbaz', @tnil
154
+ assert_equal @tnil, (@p.scan_str "## %foobarbaz")
155
+ type_alias '%quxquxqux', 'nil'
156
+ assert_equal @tnil, (@p.scan_str "## %quxquxqux")
157
+ assert_raises(RuntimeError) { type_alias '%quxquxqux', 'nil' }
158
+ assert_raises(RuntimeError) { @p.scan_str "## %qux" }
159
+ end
160
+
161
+ def test_structural
162
+ t1 = @p.scan_str "## [to_str: () -> String]"
163
+ tm1 = MethodType.new [], nil, @tstring
164
+ ts1 = StructuralType.new(to_str: tm1)
165
+ assert_equal ts1, t1
166
+ end
167
+
168
+ def test_finite_hash
169
+ t1 = @p.scan_str "## {a: Fixnum, b: String}"
170
+ assert_equal (FiniteHashType.new({a: @tfixnum, b: @tstring})), t1
171
+ t2 = @p.scan_str "## {'a'=>Fixnum, 2=>String}"
172
+ assert_equal (FiniteHashType.new({"a"=>@tfixnum, 2=>@tstring})), t2
173
+ end
174
+
175
+ def test_named_params
176
+ t1 = @p.scan_str "(Fixnum, x: Fixnum) -> Fixnum"
177
+ assert_equal (MethodType.new [@tfixnum, FiniteHashType.new(x: @tfixnum)], nil, @tfixnum), t1
178
+ t2 = @p.scan_str "(Fixnum, x: Fixnum, y: String) -> Fixnum"
179
+ assert_equal (MethodType.new [@tfixnum, FiniteHashType.new(x: @tfixnum, y: @tstring)], nil, @tfixnum), t2
180
+ t3 = @p.scan_str "(Fixnum, y: String, x: Fixnum) -> Fixnum"
181
+ assert_equal (MethodType.new [@tfixnum, FiniteHashType.new(x: @tfixnum, y: @tstring)], nil, @tfixnum), t3
182
+ t4 = @p.scan_str "(Fixnum, y: String, x: ?Fixnum) -> Fixnum"
183
+ assert_equal (MethodType.new [@tfixnum, FiniteHashType.new(x: @tfixnumopt, y: @tstring)], nil, @tfixnum), t4
184
+ t4 = @p.scan_str "(Fixnum, y: ?String, x: Fixnum) -> Fixnum"
185
+ assert_equal (MethodType.new [@tfixnum, FiniteHashType.new(x: @tfixnum, y: @tstringopt)], nil, @tfixnum), t4
186
+ t5 = @p.scan_str "(Fixnum x, x: Fixnum) -> Fixnum"
187
+ assert_equal (MethodType.new [@tfixnumx, FiniteHashType.new(x: @tfixnum)], nil, @tfixnum), t5
188
+ t5 = @p.scan_str "(Fixnum x, x: Fixnum) -> Fixnum"
189
+ assert_equal (MethodType.new [@tfixnumx, FiniteHashType.new(x: @tfixnum)], nil, @tfixnum), t5
190
+ t6 = @p.scan_str "(x: Fixnum) -> Fixnum"
191
+ assert_equal (MethodType.new [FiniteHashType.new(x: @tfixnum)], nil, @tfixnum), t6
192
+ t7 = @p.scan_str "(x: Fixnum) { (%any, String) -> nil } -> :symbol"
193
+ assert_equal (MethodType.new [FiniteHashType.new(x: @tfixnum)], MethodType.new([@ttop, @tstring], nil, @tnil), @tsymbol), t7
194
+ end
195
+
196
+ end