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,301 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestRDL < Minitest::Test
5
+
6
+ # Test wrapping with no types or contracts
7
+ def test_wrap
8
+ def m1(x) return x; end
9
+ def m2(x) return x; end
10
+ def m3(x) return x; end
11
+ def m4(x) return x; end
12
+ assert(not(RDL::Wrap.wrapped?(TestRDL, :m1)))
13
+ assert(not(RDL::Wrap.wrapped?(TestRDL, :m2)))
14
+ assert(not(RDL::Wrap.wrapped?(TestRDL, :m3)))
15
+ assert(not(RDL::Wrap.wrapped?(TestRDL, :m4)))
16
+ RDL::Wrap.wrap(TestRDL, :m1)
17
+ RDL::Wrap.wrap("TestRDL", :m2)
18
+ RDL::Wrap.wrap(:TestRDL, :m3)
19
+ RDL::Wrap.wrap(TestRDL, "m4")
20
+ assert(RDL::Wrap.wrapped?(TestRDL, :m1))
21
+ assert(RDL::Wrap.wrapped?(TestRDL, :m2))
22
+ assert(RDL::Wrap.wrapped?(TestRDL, :m3))
23
+ assert(RDL::Wrap.wrapped?(TestRDL, :m4))
24
+ assert_equal 3, m1(3)
25
+ assert_equal 3, m2(3)
26
+ assert_equal 3, m3(3)
27
+ assert_equal 3, m4(3)
28
+ end
29
+
30
+ def test_process_pre_post_args
31
+ ppos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
32
+ assert_equal ["TestRDL", :m1, ppos], RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, :m1, ppos)
33
+ assert_equal ["TestRDL", :m1, ppos], RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, "m1", ppos)
34
+ assert_equal ["[singleton]TestRDL", :m1, ppos], RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, "self.m1", ppos)
35
+ assert_equal ["TestRDL", :m1, ppos], RDL::Wrap.process_pre_post_args(self.class, "C", :m1, ppos)
36
+ assert_equal ["TestRDL", nil, ppos], RDL::Wrap.process_pre_post_args(self.class, "C", ppos)
37
+ klass1, meth1, c1 = RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, :m1) { |x| x > 0 }
38
+ assert_equal ["TestRDL", :m1], [klass1, meth1]
39
+ assert (c1.is_a? RDL::Contract::FlatContract)
40
+
41
+ klass2, meth2, c2 = RDL::Wrap.process_pre_post_args(self.class, "C", :m1) { |x| x > 0 }
42
+ assert_equal ["TestRDL", :m1], [klass2, meth2]
43
+ assert (c2.is_a? RDL::Contract::FlatContract)
44
+
45
+ klass3, meth3, c3 = RDL::Wrap.process_pre_post_args(self.class, "C") { |x| x > 0 }
46
+ assert_equal ["TestRDL", nil], [klass3, meth3]
47
+ assert (c3.is_a? RDL::Contract::FlatContract)
48
+
49
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C") }
50
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", 42) }
51
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", 42) { |x| x > 0} }
52
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", ppos) { |x| x > 0 } }
53
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", :m1) }
54
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL) }
55
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL) { |x| x > 0 } }
56
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, ppos) }
57
+ assert_raises(ArgumentError) { RDL::Wrap.process_pre_post_args(self.class, "C", TestRDL, :m1, ppos, 42) }
58
+ end
59
+
60
+ def test_pre_contract
61
+ pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
62
+ def m5(x) return x; end
63
+ pre TestRDL, :m5, pos
64
+ assert_equal 3, m5(3)
65
+ assert_raises(RDL::Contract::ContractError) { m5(-1) }
66
+ end
67
+
68
+ def test_post_contract
69
+ neg = RDL::Contract::FlatContract.new("Negative") { |x| x < 0 }
70
+ def m6(x) return 3; end
71
+ post TestRDL, :m6, neg
72
+ assert_raises(RDL::Contract::ContractError) { m6(42) }
73
+ end
74
+
75
+ def test_pre_post_contract
76
+ pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
77
+ ppos = RDL::Contract::FlatContract.new("Positive") { |r, x| r > 0 }
78
+ def m7(x) return x; end
79
+ pre TestRDL, :m7, pos
80
+ post TestRDL, :m7, ppos
81
+ assert_equal 3, m7(3)
82
+ end
83
+
84
+ def test_and_contract
85
+ pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
86
+ five = RDL::Contract::FlatContract.new("Five") { |x| x == 5 }
87
+ gt = RDL::Contract::FlatContract.new("Greater Than 3") { |x| x > 3 }
88
+ def m8(x) return x; end
89
+ pre TestRDL, :m8, pos
90
+ pre TestRDL, :m8, gt
91
+ assert_equal 5, m8(5)
92
+ assert_equal 4, m8(4)
93
+ assert_raises(RDL::Contract::ContractError) { m8 3 }
94
+ def m9(x) return x; end
95
+ pre TestRDL, :m9, pos
96
+ pre TestRDL, :m9, gt
97
+ pre TestRDL, :m9, five
98
+ assert_equal 5, m9(5)
99
+ assert_raises(RDL::Contract::ContractError) { m9 4 }
100
+ assert_raises(RDL::Contract::ContractError) { m9 3 }
101
+
102
+ ppos = RDL::Contract::FlatContract.new("Positive") { |r, x| r > 0 }
103
+ pfive = RDL::Contract::FlatContract.new("Five") { |r, x| r == 5 }
104
+ pgt = RDL::Contract::FlatContract.new("Greater Than 3") { |r, x| r > 3 }
105
+ def m10(x) return x; end
106
+ post TestRDL, :m10, ppos
107
+ post TestRDL, :m10, pgt
108
+ assert_equal 5, m10(5)
109
+ assert_equal 4, m10(4)
110
+ assert_raises(RDL::Contract::ContractError) { m10 3 }
111
+ def m11(x) return x; end
112
+ post TestRDL, :m11, ppos
113
+ post TestRDL, :m11, pgt
114
+ post TestRDL, :m11, pfive
115
+ assert_equal 5, m11(5)
116
+ assert_raises(RDL::Contract::ContractError) { m11 4 }
117
+ assert_raises(RDL::Contract::ContractError) { m11 3 }
118
+ end
119
+
120
+ def test_deferred_wrap
121
+ pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
122
+ pre TestRDL, :m12, pos
123
+ def m12(x) return x; end
124
+ assert_equal 3, m12(3)
125
+ assert_raises(RDL::Contract::ContractError) { m12(-1) }
126
+
127
+ ppos = RDL::Contract::FlatContract.new("Positive") { |r, x| r > 0 }
128
+ post TestRDL, :m13, ppos
129
+ def m13(x) return x; end
130
+ assert_equal 3, m13(3)
131
+ assert_raises(RDL::Contract::ContractError) { m13(-1) }
132
+
133
+ self.class.class_eval {
134
+ pre(pos)
135
+ def m14(x) return x; end
136
+ }
137
+ assert_equal 3, m14(3)
138
+ assert_raises(RDL::Contract::ContractError) { m14(-1) }
139
+
140
+ self.class.class_eval {
141
+ pre { |x| x > 0 }
142
+ def m15(x) return x; end
143
+ }
144
+ assert_equal 3, m15(3)
145
+ assert_raises(RDL::Contract::ContractError) { m15(-1) }
146
+
147
+ self.class.class_eval {
148
+ pre { |x| x > 0 }
149
+ post { |r, x| x > 0 }
150
+ def m17(x) return x; end
151
+ }
152
+ assert_equal 3, m17(3)
153
+ assert_raises(RDL::Contract::ContractError) { m17(-1) }
154
+
155
+ self.class.class_eval {
156
+ pre { |x| x > 0 }
157
+ post { |r, x| x < 0 }
158
+ def m18(x) return x; end
159
+ }
160
+ assert_raises(RDL::Contract::ContractError) { m18(-1) }
161
+
162
+ self.class.class_eval {
163
+ pre { |x| x > 0 }
164
+ pre { |x| x < 5 }
165
+ def m19(x) return x; end
166
+ }
167
+ assert_equal 3, m19(3)
168
+ assert_raises(RDL::Contract::ContractError) { m19(6) }
169
+ assert_raises(RDL::Contract::ContractError) { m19(-1) }
170
+
171
+ assert_raises(RuntimeError) {
172
+ self.class.class_eval <<-RUBY, __FILE__, __LINE__
173
+ pre { |x| x > 0 }
174
+ class Inner
175
+ def m20(x)
176
+ return x
177
+ end
178
+ end
179
+ RUBY
180
+ }
181
+ end
182
+
183
+ def test_special_method_names
184
+ self.class.class_eval {
185
+ pre { |x| x > 0 }
186
+ def [](x) return x end
187
+ }
188
+ assert_equal 3, self[3]
189
+ assert_raises(RDL::Contract::ContractError) { self[-1] }
190
+ self.class.class_eval {
191
+ pre { |x| x > 0 }
192
+ def foo?(x) return x end
193
+ }
194
+ assert_equal 3, foo?(3)
195
+ assert_raises(RDL::Contract::ContractError) { foo?(-1) }
196
+ self.class.class_eval {
197
+ pre(:"bar!") { |x| x > 0 }
198
+ def bar!(x) return x end
199
+ }
200
+ assert_equal 3, bar!(3)
201
+ assert_raises(RDL::Contract::ContractError) { bar!(-1) }
202
+ end
203
+
204
+ def test_wrap_access_control
205
+ def m20(x) return x; end
206
+ def m21(x) return x; end
207
+ def m22(x) return x; end
208
+ self.class.class_eval { public(:m20) }
209
+ self.class.class_eval { protected(:m21) }
210
+ self.class.class_eval { private(:m22) }
211
+ RDL::Wrap.wrap(TestRDL, :m20)
212
+ RDL::Wrap.wrap(TestRDL, :m21)
213
+ RDL::Wrap.wrap(TestRDL, :m22)
214
+ assert (self.class.class_eval { public_method_defined? :m20 })
215
+ assert (self.class.class_eval { protected_method_defined? :m21 })
216
+ assert (self.class.class_eval { private_method_defined? :m22 })
217
+ end
218
+
219
+ def test_type_params
220
+ self.class.class_eval "class TP1; type_params [:t], :all? end"
221
+ assert_equal [[:t], [:~], :all?], RDL::Wrap.get_type_params(TestRDL::TP1)
222
+ self.class.class_eval "class TP2; type_params([:t], nil) { |t| true } end"
223
+ tp2 = RDL::Wrap.get_type_params(TestRDL::TP2)
224
+ assert_equal [:t], tp2[0]
225
+ assert_equal [:~], tp2[1]
226
+ assert_raises(RuntimeError) { self.class.class_eval "class TP1; type_params [:t], :all? end" }
227
+ self.class.class_eval "class TP3; type_params [:t, :u], :all? end"
228
+ assert_equal [[:t, :u], [:~, :~], :all?], RDL::Wrap.get_type_params(TestRDL::TP3)
229
+
230
+ self.class.class_eval "class TP4; type_params [:t, :u, :v], :all?, variance: [:+, :-, :~] end"
231
+ assert_equal [[:t, :u, :v], [:+, :-, :~], :all?], RDL::Wrap.get_type_params(TestRDL::TP4)
232
+ assert_raises(RuntimeError) { self.class.class_eval "class TP5; type_params([], :all?) { true } end" }
233
+ assert_raises(RuntimeError) { self.class.class_eval "class TP6; type_params [:t, :u], :all?, variance: [:+] end" }
234
+ assert_raises(RuntimeError) { self.class.class_eval "class TP7; type_params [:t, :u], :all?, variance: [:a, :b] end" }
235
+ assert_raises(RuntimeError) { self.class.class_eval "class TP8; type_params([:t], :all?) { |t| true } end" }
236
+ assert_raises(RuntimeError) { self.class.class_eval "class TP8; type_params [:t], 42 end" }
237
+ end
238
+
239
+ def test_wrap_new
240
+ self.class.class_eval "class B; def initialize(x); @x = x end; def get(); return @x end end"
241
+ pre("TestRDL::B", "self.new") { |x| x > 0 }
242
+ assert_equal 3, TestRDL::B.new(3).get
243
+ assert_raises(RDL::Contract::ContractError) { TestRDL::B.new(-3) }
244
+
245
+ self.class.class_eval "class C; pre { |x| x > 0 }; def initialize(x); @x = x end; def get(); return @x end end"
246
+ assert_equal 3, TestRDL::C.new(3).get
247
+ assert_raises(RDL::Contract::ContractError) { TestRDL::C.new(-3) }
248
+
249
+ self.class.class_eval "class D; def get(); return @x end end"
250
+ pre("TestRDL::D", "self.new") { |x| x > 0 }
251
+ self.class.class_eval "class D; def initialize(x); @x = x end end"
252
+ assert_equal 3, TestRDL::D.new(3).get
253
+ assert_raises(RDL::Contract::ContractError) { TestRDL::D.new(-3) }
254
+
255
+ skip "Can't defer contracts on new yet"
256
+ pre("TestRDL::E", "self.new") { |x| x > 0 }
257
+ self.class.class_eval "class E; def initialize(x); @x = x end end"
258
+ assert (TestRDL::E.new(3))
259
+ assert_raises(RDL::Contract::ContractError) { TestRDL::E.new(-3) }
260
+ end
261
+
262
+ def test_class_method
263
+ pos = RDL::Contract::FlatContract.new("Positive") { |x| x > 0 }
264
+ self.class.class_eval { def self.cm1(x) return x; end }
265
+ pre TestRDL, "self.cm1", pos
266
+ assert_equal 3, TestRDL.cm1(3)
267
+ assert_raises(RDL::Contract::ContractError) { TestRDL.cm1(-1) }
268
+
269
+ assert_raises(RuntimeError) { pre TestRDL, "TestRDL.cm1", pos }
270
+
271
+ pre TestRDL, "self.cm2", pos
272
+ self.class.class_eval { def self.cm2(x) return x; end }
273
+ assert_equal 3, TestRDL.cm2(3)
274
+ assert_raises(RDL::Contract::ContractError) { TestRDL.cm2(-1) }
275
+
276
+ self.class.class_eval {
277
+ pre { |x| x > 0 }
278
+ def self.cm3(x) return x; end
279
+ }
280
+ assert_equal 3, TestRDL.cm3(3)
281
+ assert_raises(RDL::Contract::ContractError) { TestRDL.cm3(-1) }
282
+ end
283
+
284
+ def test_cast
285
+ ntyp = RDL::Type::NilType.new
286
+ obj1 = 3.type_cast(ntyp)
287
+ assert (ntyp.member? obj1)
288
+ obj2 = 3.type_cast('nil')
289
+ assert (ntyp.member? obj2)
290
+ end
291
+
292
+ def test_pre_post_self
293
+ self.class.class_eval {
294
+ pre { |x| self.instance_of? TestRDL }
295
+ post { |r, x| self.instance_of? TestRDL }
296
+ def m23(x) return x; end
297
+ }
298
+ assert_equal 3, m23(3)
299
+ end
300
+
301
+ end
@@ -0,0 +1,70 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestRDLType < Minitest::Test
5
+ def test_single_type_contract
6
+ def m1(x) return x; end
7
+ type TestRDLType, :m1, "(Fixnum) -> Fixnum"
8
+ assert_equal 5, m1(5)
9
+ assert_raises(RDL::Type::TypeError) { m1("foo") }
10
+
11
+ self.class.class_eval {
12
+ type :m2, "(Fixnum) -> Fixnum"
13
+ def m2(x) return x; end
14
+ }
15
+ assert_equal 5, m2(5)
16
+ assert_raises(RDL::Type::TypeError) { m2("foo") }
17
+
18
+ self.class.class_eval {
19
+ type "(Fixnum) -> Fixnum"
20
+ def m3(x) return x; end
21
+ }
22
+ assert_equal 5, m3(5)
23
+ assert_raises(RDL::Type::TypeError) { m3("foo") }
24
+ end
25
+
26
+ def test_intersection_type_contract
27
+ self.class.class_eval {
28
+ type "(Fixnum) -> Fixnum"
29
+ type "(String) -> String"
30
+ def m4(x) return x; end
31
+ }
32
+ assert_equal 5, m4(5)
33
+ assert_equal "foo", m4("foo")
34
+ assert_raises(RDL::Type::TypeError) { m4(:foo) }
35
+
36
+ self.class.class_eval {
37
+ type "(Fixnum) -> Fixnum"
38
+ type "(String) -> String"
39
+ def m5(x) return 42; end
40
+ }
41
+ assert_equal 42, m5(3)
42
+ assert_raises(RDL::Type::TypeError) { m5("foo") }
43
+
44
+ self.class.class_eval {
45
+ type "(Fixnum) -> Fixnum"
46
+ type "(Fixnum) -> String"
47
+ def m6(x) if x > 10 then :oops elsif x > 5 then x else "small" end end
48
+ }
49
+ assert_equal 8, m6(8)
50
+ assert_equal "small", m6(1)
51
+ assert_raises(RDL::Type::TypeError) { m6(42) }
52
+ end
53
+
54
+ def test_fixnum_type_contract
55
+ self.class.class_eval {
56
+ type "(0) -> Fixnum"
57
+ def m7(x) return x; end
58
+ }
59
+ assert_equal 0, m7(0)
60
+ assert_raises(RDL::Type::TypeError) { m7(1) }
61
+ end
62
+
63
+ def test_wrap_new_inherited
64
+ self.class.class_eval "class NI_A; def initialize(x); @x = x; end; end; class NI_B < NI_A; end"
65
+ type "TestRDLType::NI_A", "self.new", "(Fixnum) -> TestRDLType::NI_A"
66
+ assert (TestRDLType::NI_B.new(3))
67
+ assert_raises(RDL::Type::TypeError) { TestRDLType::NI_B.new("3") }
68
+ end
69
+
70
+ end
@@ -0,0 +1,187 @@
1
+ require 'minitest/autorun'
2
+ require_relative '../lib/rdl.rb'
3
+
4
+ class TestTypeContract < Minitest::Test
5
+ include RDL::Type
6
+ include RDL::Contract
7
+
8
+ def setup
9
+ @p = Parser.new
10
+ end
11
+
12
+ def test_flat
13
+ tnil = NilType.new
14
+ cnil = tnil.to_contract
15
+ assert (cnil.check self, nil)
16
+ assert_raises(TypeError) { cnil.check self, true }
17
+ tfixnum = NominalType.new :Fixnum
18
+ cfixnum = tfixnum.to_contract
19
+ assert (cfixnum.check self, 42)
20
+ assert (cfixnum.check self, nil)
21
+ assert_raises(TypeError) { cfixnum.check self, "42" }
22
+ end
23
+
24
+ def test_proc
25
+ t1 = @p.scan_str "(nil) -> nil"
26
+ p1 = t1.to_contract.wrap(self) { |x| nil }
27
+ assert_nil p1.call(nil)
28
+ assert_raises(TypeError) { p1.call(42) }
29
+ p1b = t1.to_contract.wrap(self) { |x| 42 }
30
+ assert_raises(TypeError) { p1b.call(nil) }
31
+
32
+ t2 = @p.scan_str "(Fixnum, Fixnum) -> Fixnum"
33
+ p2 = t2.to_contract.wrap(self) { |x, y| x }
34
+ assert_equal 42, p2.call(42, 43)
35
+ assert_equal 42, p2.call(42, nil)
36
+ assert_raises(TypeError) { p2.call(42, 43, 44) }
37
+ assert_raises(TypeError) { p2.call(42, 43, 44, 45) }
38
+ assert_raises(TypeError) { p2.call(42) }
39
+ assert_raises(TypeError) { p2.call }
40
+
41
+ t3 = @p.scan_str "() -> nil"
42
+ p3 = t3.to_contract.wrap(self) { nil }
43
+ assert_nil p3.call
44
+ assert_raises(TypeError) { p3.call(42) }
45
+
46
+ t4 = @p.scan_str "(Fixnum, ?Fixnum) -> Fixnum"
47
+ p4 = t4.to_contract.wrap(self) { |x| x }
48
+ assert_equal 42, p4.call(42)
49
+ assert_equal 42, p4.call(42, 43)
50
+ assert_raises(TypeError) { p4.call(42, 43, 44) }
51
+ assert_raises(TypeError) { p4.call }
52
+
53
+ t5 = @p.scan_str "(Fixnum, *Fixnum) -> Fixnum"
54
+ p5 = t5.to_contract.wrap(self) { |x| x }
55
+ assert_equal 42, p5.call(42)
56
+ assert_equal 42, p5.call(42, 43)
57
+ assert_equal 42, p5.call(42, 43, 44)
58
+ assert_equal 42, p5.call(42, 43, 44, 45)
59
+ assert_raises(TypeError) { p5.call }
60
+ assert_raises(TypeError) { p5.call("42") }
61
+ assert_raises(TypeError) { p5.call(42, "43") }
62
+ assert_raises(TypeError) { p5.call(42, 43, "44") }
63
+ assert_raises(TypeError) { p5.call(42, 43, 44, "45") }
64
+
65
+ t6 = @p.scan_str "(Fixnum, ?Fixnum, ?Fixnum, *Fixnum) -> Fixnum"
66
+ p6 = t6.to_contract.wrap(self) { |x| x }
67
+ assert_equal 42, p6.call(42)
68
+ assert_equal 42, p6.call(42, 43)
69
+ assert_equal 42, p6.call(42, 43, 44)
70
+ assert_equal 42, p6.call(42, 43, 44, 45)
71
+ assert_equal 42, p6.call(42, 43, 44, 45, 46)
72
+ assert_raises(TypeError) { p6.call }
73
+ assert_raises(TypeError) { p6.call("42") }
74
+ assert_raises(TypeError) { p6.call(42, "43") }
75
+ assert_raises(TypeError) { p6.call(42, 43, "44") }
76
+ assert_raises(TypeError) { p6.call(42, 43, 44, "45") }
77
+ assert_raises(TypeError) { p6.call(42, 43, 44, 45, "46") }
78
+
79
+ t7 = @p.scan_str "(?Fixnum) -> nil"
80
+ p7 = t7.to_contract.wrap(self) { nil }
81
+ assert_nil p7.call
82
+ assert_nil p7.call(42)
83
+ assert_raises(TypeError) { p7.call("42") }
84
+ assert_raises(TypeError) { p7.call(42, 43) }
85
+ assert_raises(TypeError) { p7.call(42, 43, 44) }
86
+
87
+ t8 = @p.scan_str "(*Fixnum) -> nil"
88
+ p8 = t8.to_contract.wrap(self) { nil }
89
+ assert_nil p8.call
90
+ assert_nil p8.call(42)
91
+ assert_nil p8.call(42, 43)
92
+ assert_nil p8.call(42, 43, 44)
93
+ assert_raises(TypeError) { p8.call("42") }
94
+ assert_raises(TypeError) { p8.call(42, "43") }
95
+ assert_raises(TypeError) { p8.call(42, 43, "44") }
96
+
97
+ t9 = @p.scan_str "(Fixnum arg1, ?Fixnum arg2) -> Fixnum"
98
+ p9 = t9.to_contract.wrap(self) { |x| x }
99
+ assert_equal 42, p9.call(42)
100
+ assert_equal 42, p9.call(42, 43)
101
+ assert_raises(TypeError) { p9.call(42, 43, 44) }
102
+ assert_raises(TypeError) { p9.call }
103
+
104
+ t10 = @p.scan_str "(?Fixnum, String) -> Fixnum"
105
+ p10 = t10.to_contract.wrap(self) { |*args| 42 }
106
+ assert_equal 42, p10.call("44")
107
+ assert_equal 42, p10.call(43, "44")
108
+ assert_raises(TypeError) { p10.call() }
109
+ assert_raises(TypeError) { p10.call(43, "44", 45) }
110
+ end
111
+
112
+ def test_proc_names
113
+ t1 = @p.scan_str "(x: Fixnum) -> Fixnum"
114
+ p1 = t1.to_contract.wrap(self) { |x:| x }
115
+ assert_equal 42, p1.call(x: 42)
116
+ assert_raises(TypeError) { p1.call(x: "42") }
117
+ assert_raises(TypeError) { p1.call() }
118
+ assert_raises(TypeError) { p1.call(x: 42, y: 42) }
119
+ assert_raises(TypeError) { p1.call(y: 42) }
120
+ assert_raises(TypeError) { p1.call(42) }
121
+ assert_raises(TypeError) { p1.call(42, x: 42) }
122
+ t2 = @p.scan_str "(x: Fixnum, y: String) -> Fixnum"
123
+ p2 = t2.to_contract.wrap(self) { |x:,y:| x }
124
+ assert_equal 42, p2.call(x: 42, y: "33")
125
+ assert_raises(TypeError) { p2.call() }
126
+ assert_raises(TypeError) { p2.call(x: 42) }
127
+ assert_raises(TypeError) { p2.call(x: "42", y: "33") }
128
+ assert_raises(TypeError) { p2.call(42, "43") }
129
+ assert_raises(TypeError) { p2.call(42, x: 42, y: "33") }
130
+ assert_raises(TypeError) { p2.call(x: 42, y: "33", z: 44) }
131
+ t3 = @p.scan_str "(Fixnum, y: String) -> Fixnum"
132
+ p3 = t3.to_contract.wrap(self) { |x, y:| x }
133
+ assert_equal 42, p3.call(42, y:"43")
134
+ assert_raises(TypeError) { p3.call(42) }
135
+ assert_raises(TypeError) { p3.call(42, y: 43) }
136
+ assert_raises(TypeError) { p3.call() }
137
+ assert_raises(TypeError) { p3.call(42, 43, y: 44) }
138
+ assert_raises(TypeError) { p3.call(42, y: 43, z: 44) }
139
+ t4 = @p.scan_str "(Fixnum, x: Fixnum, y: String) -> Fixnum"
140
+ p4 = t4.to_contract.wrap(self) { |a, x:, y:| a }
141
+ assert_equal 42, p4.call(42, x: 43, y: "44")
142
+ assert_raises(TypeError) { p4.call(42, x: 43) }
143
+ assert_raises(TypeError) { p4.call(42, y: "43") }
144
+ assert_raises(TypeError) { p4.call() }
145
+ assert_raises(TypeError) { p4.call(42, 43, x: 44, y: "45") }
146
+ assert_raises(TypeError) { p4.call(42, x: 43, y: "44", z: 45) }
147
+ t5 = @p.scan_str "(x: Fixnum, y: ?String) -> Fixnum"
148
+ p5 = t5.to_contract.wrap(self) { |x:, **ys| x }
149
+ assert_equal 42, p5.call(x: 42, y: "43")
150
+ assert_equal 42, p5.call(x: 42)
151
+ assert_raises(TypeError) { p5.call() }
152
+ assert_raises(TypeError) { p5.call(x: 42, y: 43) }
153
+ assert_raises(TypeError) { p5.call(x: 42, y: 43, z: 44) }
154
+ assert_raises(TypeError) { p5.call(3, x: 42, y: 43) }
155
+ assert_raises(TypeError) { p5.call(3, x: 42) }
156
+ t6 = @p.scan_str "(x: ?Fixnum, y: String) -> Fixnum"
157
+ p6 = t6.to_contract.wrap(self) { |y:, **xs| 42 }
158
+ assert_equal 42, p6.call(x: 43, y: "44")
159
+ assert_equal 42, p6.call(y: "44")
160
+ assert_raises(TypeError) { p6.call() }
161
+ assert_raises(TypeError) { p6.call(x: "43", y: "44") }
162
+ assert_raises(TypeError) { p6.call(42, x: 43, y: "44") }
163
+ assert_raises(TypeError) { p6.call(x: 43, y: "44", z: 45) }
164
+ t7 = @p.scan_str "(x: ?Fixnum, y: ?String) -> Fixnum"
165
+ p7 = t7.to_contract.wrap(self) { |**args| 42 }
166
+ assert_equal 42, p7.call()
167
+ assert_equal 42, p7.call(x: 43)
168
+ assert_equal 42, p7.call(y: "44")
169
+ assert_equal 42, p7.call(x: 43, y: "44")
170
+ assert_raises(TypeError) { p7.call(x: "43", y: "44") }
171
+ assert_raises(TypeError) { p7.call(41, x: 43, y: "44") }
172
+ assert_raises(TypeError) { p7.call(x: 43, y: "44", z: 45) }
173
+ t8 = @p.scan_str "(?Fixnum, x: ?Symbol, y: ?String) -> Fixnum"
174
+ p8 = t8.to_contract.wrap(self) { |*args| 42 }
175
+ assert_equal 42, p8.call()
176
+ assert_equal 42, p8.call(43)
177
+ assert_equal 42, p8.call(x: :foo)
178
+ assert_equal 42, p8.call(43, x: :foo)
179
+ assert_equal 42, p8.call(y: "foo")
180
+ assert_equal 42, p8.call(43, y: "foo")
181
+ assert_equal 42, p8.call(x: :foo, y: "foo")
182
+ assert_equal 42, p8.call(43, x: :foo, y: "foo")
183
+ assert_raises(TypeError) { p8.call(43, 44, x: :foo, y: "foo") }
184
+ assert_raises(TypeError) { p8.call(43, x: "foo", y: "foo") }
185
+ assert_raises(TypeError) { p8.call(43, x: :foo, y: "foo", z: 44) }
186
+ end
187
+ end