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,85 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestDsl < Minitest::Test
5
+
6
+ class Pair
7
+
8
+ # dsl {
9
+ # type :left, '(Fixnum) -> Fixnum'
10
+ # type :right, '(Fixnum) -> Fixnum'
11
+ # }
12
+ def entry(&blk)
13
+ instance_eval(&blk)
14
+ end
15
+
16
+ def left(x)
17
+ @left = x
18
+ end
19
+
20
+ def right(x)
21
+ @right = x
22
+ end
23
+
24
+ def get
25
+ [@left, @right]
26
+ end
27
+ end
28
+
29
+ class Tree
30
+
31
+ # dsl :tree { # recursive DSL
32
+ # type :left, '(Fixnum) -> Fixnum'
33
+ # dsl :left, :tree
34
+ # type :right, '(Fixnum) -> Fixnum'
35
+ # dsl :right, :tree
36
+ # }
37
+ def entry(val, &blk)
38
+ @val = val
39
+ instance_eval(&blk)
40
+ end
41
+
42
+ def left(x, &blk)
43
+ if blk
44
+ @left = Tree.new.entry(x, &blk)
45
+ else
46
+ @left = x
47
+ end
48
+ end
49
+
50
+ def right(x, &blk)
51
+ if blk
52
+ @right = Tree.new.entry(x, &blk)
53
+ else
54
+ @right = x
55
+ end
56
+ end
57
+
58
+ def get
59
+ l = @left.instance_of?(Tree) ? @left.get : @left
60
+ r = @right.instance_of?(Tree) ? @right.get : @right
61
+ [@val, l, r]
62
+ end
63
+ end
64
+
65
+ def test_pair
66
+ p = Pair.new.entry {
67
+ left 3
68
+ right 4
69
+ }
70
+ end
71
+
72
+ def test_tree
73
+ t = Tree.new.entry(2) {
74
+ left(3)
75
+ right(4) {
76
+ left(5) {
77
+ left(6)
78
+ right(7)
79
+ }
80
+ right(8)
81
+ }
82
+ }
83
+ end
84
+ end
85
+
@@ -0,0 +1,188 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestGeneric < Minitest::Test
5
+
6
+ # Make two classes that wrap Array and Hash, so we don't mess with their
7
+ # implementations in test case evaluation.
8
+ class A
9
+ type_params [:t], :all?
10
+ def initialize(a); @a = a end
11
+ def all?(&blk)
12
+ @a.all?(&blk)
13
+ end
14
+ end
15
+
16
+ class H
17
+ type_params [:k, :v], :all?
18
+ def initialize(h); @h = h end
19
+ def all?(&blk)
20
+ @h.all? { |x, y| blk.call(x, y) } # have to do extra wrap to avoid splat issues
21
+ end
22
+ end
23
+
24
+ class B
25
+ # class for checking other variance annotations
26
+ type_params [:a, :b], nil, variance: [:+, :-] { |a, b| true }
27
+ type "(a) -> nil"
28
+ def m1(x)
29
+ nil
30
+ end
31
+ def m2(x) # no type annotation
32
+ nil
33
+ end
34
+ end
35
+
36
+ def setup
37
+ @ta = RDL::Type::NominalType.new "TestGeneric::A"
38
+ @th = RDL::Type::NominalType.new "TestGeneric::H"
39
+ @tstring = RDL::Type::NominalType.new "String"
40
+ @tobject = RDL::Type::NominalType.new "Object"
41
+ @tfixnum = RDL::Type::NominalType.new "Fixnum"
42
+ @tas = RDL::Type::GenericType.new(@ta, @tstring)
43
+ @tao = RDL::Type::GenericType.new(@ta, @tobject)
44
+ @taas = RDL::Type::GenericType.new(@ta, @tas)
45
+ @taao = RDL::Type::GenericType.new(@ta, @tao)
46
+ @thss = RDL::Type::GenericType.new(@th, @tstring, @tstring)
47
+ @thoo = RDL::Type::GenericType.new(@th, @tobject, @tobject)
48
+ @thsf = RDL::Type::GenericType.new(@th, @tstring, @tfixnum)
49
+ @tb = RDL::Type::NominalType.new "TestGeneric::B"
50
+ @tnil = RDL::Type::NilType.new
51
+ end
52
+
53
+ def test_le
54
+ # Check invariance for A and H
55
+ assert (@tas <= @tas)
56
+ assert (@tao <= @tao)
57
+ assert (@taas <= @taas)
58
+ assert (@thss <= @thss)
59
+ assert (@thoo <= @thoo)
60
+ assert (not (@tas <= @tao))
61
+ assert (not (@tao <= @tas))
62
+ assert (not (@thss <= @thoo))
63
+ assert (not (@thoo <= @thss))
64
+
65
+ # Check "raw" class subtyping is forbidden
66
+ assert (not (@ta <= @tas))
67
+ assert (not (@tas <= @ta))
68
+ assert (not (@ta <= @taas))
69
+ assert (not (@taas <= @ta))
70
+ assert (not (@th <= @thss))
71
+ assert (not (@thss <= @th))
72
+
73
+ # Check co- and contravariance using B
74
+ tbss = RDL::Type::GenericType.new(@tb, @tstring, @tstring)
75
+ tbso = RDL::Type::GenericType.new(@tb, @tstring, @tobject)
76
+ tbos = RDL::Type::GenericType.new(@tb, @tobject, @tstring)
77
+ tboo = RDL::Type::GenericType.new(@tb, @tobject, @tobject)
78
+ assert (tbss <= tbss)
79
+ assert (not (tbss <= tbso))
80
+ assert (tbss <= tbos)
81
+ assert (not (tbss <= tboo))
82
+ assert (tbso <= tbss)
83
+ assert (tbso <= tbso)
84
+ assert (tbso <= tbos)
85
+ assert (tbso <= tboo)
86
+ assert (not (tbos <= tbss))
87
+ assert (not (tbos <= tbso))
88
+ assert (tbos <= tbos)
89
+ assert (not (tbos <= tboo))
90
+ assert (not (tboo <= tbss))
91
+ assert (not (tboo <= tbso))
92
+ assert (tboo <= tbos)
93
+ assert (tboo <= tboo)
94
+ end
95
+
96
+ def test_le_structural
97
+ tbss = RDL::Type::GenericType.new(@tb, @tstring, @tstring)
98
+ tma = RDL::Type::MethodType.new([], nil, @tnil)
99
+ tmb = RDL::Type::MethodType.new([@tstring], nil, @tnil)
100
+ tmc = RDL::Type::MethodType.new([@tfixnum], nil, @tnil)
101
+ ts1 = RDL::Type::StructuralType.new(m2: tma)
102
+ assert (tbss <= ts1)
103
+ ts2 = RDL::Type::StructuralType.new(m1: tmb)
104
+ assert (tbss <= ts2)
105
+ ts3 = RDL::Type::StructuralType.new(m1: tmb, m2: tma)
106
+ assert (tbss <= ts3)
107
+ ts4 = RDL::Type::StructuralType.new(m1: tmc, m2: tma)
108
+ assert (not (tbss <= ts4))
109
+ ts5 = RDL::Type::StructuralType.new(m1: tmb, m2: tmc)
110
+ assert (tbss <= ts5)
111
+ end
112
+
113
+ class C
114
+ type "() -> self"
115
+ def m1() return self; end
116
+ type "() -> self"
117
+ def m2() return C.new; end
118
+ end
119
+
120
+ def test_self_type
121
+ c = C.new
122
+ assert(c.m1)
123
+ assert_raises(RDL::Type::TypeError) { c.m2 }
124
+ end
125
+
126
+ def test_member
127
+ # member? should only check the base types
128
+ assert (@ta.member?(A.new([1, 2, 3])))
129
+ assert (@ta.member?(A.new([])))
130
+ assert (@ta.member?(A.new(["a", "b", "c"])))
131
+ assert (@tas.member?(A.new([1, 2, 3])))
132
+ assert (@tas.member?(A.new([])))
133
+ assert (@tas.member?(A.new(["a", "b", "c"])))
134
+ assert (@taas.member?(A.new([1, 2, 3])))
135
+ assert (@taas.member?(A.new([])))
136
+ assert (@taas.member?(A.new(["a", "b", "c"])))
137
+ end
138
+
139
+ def test_instantiate
140
+ assert_raises(RuntimeError) { Object.new.instantiate!(@tstring) }
141
+
142
+ # Array<String>
143
+ assert (A.new([]).instantiate!('String'))
144
+ assert (A.new(["a", "b", "c"]).instantiate!(@tstring))
145
+ assert (A.new(["a", "b", "c"]).instantiate!('String'))
146
+ assert_raises(RDL::Type::TypeError) { A.new([1, 2, 3]).instantiate!('String') }
147
+
148
+ # Array<Object>
149
+ assert (A.new([])).instantiate!('Object')
150
+ assert (A.new(["a", "b", "c"]).instantiate!(@tobject))
151
+ assert (A.new(["a", "b", "c"]).instantiate!('Object'))
152
+ assert (A.new([1, 2, 3]).instantiate!('Object'))
153
+
154
+ # Hash<String, Fixnum>
155
+ assert (H.new({}).instantiate!('String', 'Fixnum'))
156
+ assert (H.new({"one"=>1, "two"=>2}).instantiate!('String', 'Fixnum'))
157
+ assert_raises(RDL::Type::TypeError) {
158
+ H.new(one: 1, two: 2).instantiate!('String', 'Fixnum')
159
+ }
160
+ assert_raises(RDL::Type::TypeError){
161
+ H.new({"one"=>:one, "two"=>:two}).instantiate!('String', 'Fixnum')
162
+ }
163
+
164
+ # Hash<Object, Object>
165
+ assert (H.new({}).instantiate!('Object', 'Object'))
166
+ assert (H.new({"one"=>1, "two"=>2}).instantiate!('Object', 'Object'))
167
+ assert (H.new(one: 1, two: 2).instantiate!('Object', 'Object'))
168
+ assert (H.new({"one"=>:one, "two"=>:two}).instantiate!('Object', 'Object'))
169
+
170
+ # A<A<String>>
171
+ assert (A.new([A.new(["a", "b"]).instantiate!('String'),
172
+ A.new(["c"]).instantiate!('String')]).instantiate!('TestGeneric::A<String>'))
173
+ assert_raises(RDL::Type::TypeError) {
174
+ # Must instantiate all members
175
+ A.new([A.new(["a", "b"]).instantiate!('String'), A.new([])]).instantiate!('TestGeneric::A<String>')
176
+ }
177
+ assert_raises(RDL::Type::TypeError) {
178
+ # All members must be of same type
179
+ A.new([A.new(["a", "b"]).instantiate!('String'), "A"]).instantiate!('TestGeneric::A<String>')
180
+ }
181
+ assert_raises(RDL::Type::TypeError) {
182
+ # All members must be instantiated and of same type
183
+ A.new([A.new(["a", "b"]).instantiate!('String'),
184
+ H.new({a: 1, b: 2}).instantiate!('Object', 'Object')]).instantiate!('TestGeneric::A<String>')
185
+ }
186
+ end
187
+
188
+ end
@@ -0,0 +1,41 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestIntersection < Minitest::Test
5
+ include RDL::Type
6
+
7
+ def setup
8
+ @parser = RDL::Type::Parser.new
9
+
10
+ @fixnum = NominalType.new(Fixnum)
11
+ @string = NominalType.new(String)
12
+ @array = NominalType.new(Array)
13
+ @hash = NominalType.new(Hash)
14
+ @true_n = NominalType.new(TrueClass)
15
+
16
+ @tparam_t = VarType.new(:t)
17
+
18
+ @f_or_s = UnionType.new(@fixnum, @string)
19
+ @string_or_true = UnionType.new(@string, @true_n)
20
+
21
+ @array_of_fixnum = GenericType.new(@array, @fixnum)
22
+ @array_of_true = GenericType.new(@array, @true_n)
23
+ @array_of_fixnum_string = GenericType.new(@array, @f_or_s)
24
+ @array_of_true_string = GenericType.new(@array, @string_or_true)
25
+ @hash_of_string_fixnum = GenericType.new(@hash, @string, @fixnum)
26
+ @hash_of_string_true_fixnum = GenericType.new(@hash, @string_or_true, @fixnum)
27
+ @a_a_f = GenericType.new(@array, @array_of_fixnum)
28
+ @a_a_a_f = GenericType.new(@array, @a_a_f)
29
+ @a_a_a_a_f = GenericType.new(@array, @a_a_a_f)
30
+ end
31
+
32
+ def test_intersection_same
33
+ t1 = @parser.scan_str "(Fixnum) -> Fixnum"
34
+ t2 = @parser.scan_str "(Fixnum) -> Fixnum"
35
+ t3 = @parser.scan_str "(Fixnum) -> Fixnum"
36
+ i = IntersectionType.new(t1, t2, t3)
37
+
38
+ assert_equal(t1, i)
39
+ end
40
+ end
41
+
@@ -0,0 +1,193 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestLe < 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
+ @ta = NominalType.new A
25
+ @tb = NominalType.new B
26
+ @tc = NominalType.new C
27
+ @tfixnum = NominalType.new "Fixnum"
28
+ end
29
+
30
+ def test_nil
31
+ assert (@tnil <= @ttop)
32
+ assert (@tnil <= @tstring)
33
+ assert (@tnil <= @tobject)
34
+ assert (@tnil <= @tbasicobject)
35
+ assert (@tnil <= @tsymfoo)
36
+ assert (not (@ttop <= @tnil))
37
+ assert (not (@tstring <= @tnil))
38
+ assert (not (@tobject <= @tnil))
39
+ assert (not (@tbasicobject <= @tnil))
40
+ assert (not (@tsymfoo <= @tnil))
41
+ end
42
+
43
+ def test_top
44
+ assert (not (@ttop <= @tnil))
45
+ assert (not (@ttop <= @tstring))
46
+ assert (not (@ttop <= @tobject))
47
+ assert (not (@ttop <= @tbasicobject))
48
+ assert (not (@ttop <= @tsymfoo))
49
+ assert (@ttop <= @ttop)
50
+ assert (@tstring <= @ttop)
51
+ assert (@tobject <= @ttop)
52
+ assert (@tbasicobject <= @ttop)
53
+ assert (@tsymfoo <= @ttop)
54
+ end
55
+
56
+ def test_sym
57
+ assert (@tsym <= @tsym)
58
+ assert (@tsymfoo <= @tsymfoo)
59
+ assert (@tsymfoo <= @tsym)
60
+ assert (not (@tsym <= @tsymfoo))
61
+ end
62
+
63
+ def test_nominal
64
+ assert (@tstring <= @tstring)
65
+ assert (@tsym <= @tsym)
66
+ assert (not (@tstring <= @tsym))
67
+ assert (not (@tsym <= @tstring))
68
+ assert (@tstring <= @tobject)
69
+ assert (@tstring <= @tbasicobject)
70
+ assert (@tobject <= @tbasicobject)
71
+ assert (not (@tobject <= @tstring))
72
+ assert (not (@tbasicobject <= @tstring))
73
+ assert (not (@tbasicobject <= @tobject))
74
+ assert (@ta <= @ta)
75
+ assert (@tb <= @ta)
76
+ assert (@tc <= @ta)
77
+ assert (not (@ta <= @tb))
78
+ assert (@tb <= @tb)
79
+ assert (@tc <= @tb)
80
+ assert (not (@ta <= @tc))
81
+ assert (not (@tb <= @tc))
82
+ assert (@tc <= @tc)
83
+ end
84
+
85
+ def test_union
86
+ tstring_or_sym = UnionType.new(@tstring, @tsym)
87
+ assert (tstring_or_sym <= @tobject)
88
+ assert (not (@tobject <= @tstring_or_sym))
89
+ end
90
+
91
+ def test_tuple
92
+ t1 = TupleType.new(@tsym, @tstring)
93
+ t2 = TupleType.new(@tobject, @tobject)
94
+ tarray = NominalType.new("Array")
95
+ assert (t1 <= t1)
96
+ assert (t2 <= t2)
97
+ assert (not (t1 <= t2)) # invariant subtyping since tuples are mutable
98
+ assert (not (t2 <= t1))
99
+ assert (not (t1 <= tarray)) # no convertability to arrays due to mutability
100
+ assert (not (tarray <= t1))
101
+ end
102
+
103
+ def test_method
104
+ tss = MethodType.new([@tstring], nil, @tstring)
105
+ tso = MethodType.new([@tstring], nil, @tobject)
106
+ tos = MethodType.new([@tobject], nil, @tstring)
107
+ too = MethodType.new([@tobject], nil, @tobject)
108
+ assert (tss <= tss)
109
+ assert (tss <= tso)
110
+ assert (not (tss <= tos))
111
+ assert (not (tss <= too))
112
+ assert (not (tso <= tss))
113
+ assert (tso <= tso)
114
+ assert (not (tso <= tos))
115
+ assert (not (tso <= too))
116
+ assert (tos <= tss)
117
+ assert (tos <= tso)
118
+ assert (tos <= tos)
119
+ assert (tos <= too)
120
+ assert (not (too <= tss))
121
+ assert (too <= tso)
122
+ assert (not (too <= tos))
123
+ assert (too <= too)
124
+ tbos = MethodType.new([], tos, @tobject)
125
+ tbso = MethodType.new([], tso, @tobject)
126
+ assert (tbos <= tbos)
127
+ assert (not (tbos <= tbso))
128
+ assert (tbso <= tbso)
129
+ assert (tbso <= tbos)
130
+ end
131
+
132
+ def test_structural
133
+ tso = MethodType.new([@tstring], nil, @tobject)
134
+ tos = MethodType.new([@tobject], nil, @tstring)
135
+ ts1 = StructuralType.new(m1: tso)
136
+ ts2 = StructuralType.new(m1: tos)
137
+ assert (ts1 <= @ttop)
138
+ assert (ts1 <= ts1)
139
+ assert (ts2 <= ts2)
140
+ assert (ts2 <= ts1)
141
+ assert (not (ts1 <= ts2))
142
+ ts3 = StructuralType.new(m1: tso, m2: tso) # width subtyping
143
+ assert (ts3 <= ts1)
144
+ assert (not (ts1 <= ts3))
145
+ end
146
+
147
+ class Nom
148
+ def m1()
149
+ nil
150
+ end
151
+ def m2()
152
+ nil
153
+ end
154
+ end
155
+
156
+ class NomT
157
+ type "() -> nil"
158
+ def m1()
159
+ nil
160
+ end
161
+ type "() -> nil"
162
+ def m2()
163
+ nil
164
+ end
165
+ end
166
+
167
+ def test_nominal_structural
168
+ tnom = NominalType.new(Nom)
169
+ tnomt = NominalType.new(NomT)
170
+ tma = MethodType.new([], nil, @tnil)
171
+ tmb = MethodType.new([@tfixnum], nil, @tnil)
172
+ ts1 = StructuralType.new(m1: tma)
173
+ assert (tnom <= ts1)
174
+ assert (tnomt <= ts1)
175
+ ts2 = StructuralType.new(m1: tma, m2: tma)
176
+ assert (tnom <= ts2)
177
+ assert (tnomt <= ts2)
178
+ ts3 = StructuralType.new(m1: tma, m2: tma, m3: tma)
179
+ assert (not (tnom <= ts3))
180
+ assert (not (tnomt <= ts3))
181
+ ts4 = StructuralType.new(m1: tmb)
182
+ assert (tnom <= ts4) # types don't matter, only methods
183
+ assert (not (tnomt <= ts4))
184
+ end
185
+
186
+ # def test_intersection
187
+ # skip "<= not defined on intersection"
188
+ # tobject_and_basicobject = IntersectionType.new(@tobject, @tbasicobject)
189
+ # assert (not (tobject_and_basicobject <= @tobject))
190
+ # assert (@tobject <= tobject_and_basicobject)
191
+ # end
192
+
193
+ end