ruby-contract 0.1.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 (74) hide show
  1. data/COPYING +56 -0
  2. data/Manifest +85 -0
  3. data/README +32 -0
  4. data/TODO +83 -0
  5. data/doc/classes/Contract.html +599 -0
  6. data/doc/classes/Contract/Check.html +229 -0
  7. data/doc/classes/Contract/Check/All.html +172 -0
  8. data/doc/classes/Contract/Check/Any.html +172 -0
  9. data/doc/classes/Contract/Check/Block.html +172 -0
  10. data/doc/classes/Contract/Check/None.html +173 -0
  11. data/doc/classes/Contract/Check/Quack.html +172 -0
  12. data/doc/classes/Contract/ContractError.html +151 -0
  13. data/doc/classes/Contract/ContractException.html +162 -0
  14. data/doc/classes/Contract/ContractMismatch.html +134 -0
  15. data/doc/classes/Kernel.html +256 -0
  16. data/doc/classes/Method.html +135 -0
  17. data/doc/classes/MethodSignatureMixin.html +208 -0
  18. data/doc/classes/Module.html +526 -0
  19. data/doc/created.rid +1 -0
  20. data/doc/dot/f_0.dot +14 -0
  21. data/doc/dot/f_0.png +0 -0
  22. data/doc/dot/f_1.dot +14 -0
  23. data/doc/dot/f_1.png +0 -0
  24. data/doc/dot/f_2.dot +14 -0
  25. data/doc/dot/f_2.png +0 -0
  26. data/doc/dot/f_3.dot +112 -0
  27. data/doc/dot/f_3.png +0 -0
  28. data/doc/dot/f_4.dot +62 -0
  29. data/doc/dot/f_4.png +0 -0
  30. data/doc/dot/f_5.dot +62 -0
  31. data/doc/dot/f_5.png +0 -0
  32. data/doc/dot/f_6.dot +224 -0
  33. data/doc/dot/f_6.png +0 -0
  34. data/doc/dot/f_6_0.dot +24 -0
  35. data/doc/dot/f_6_0.png +0 -0
  36. data/doc/dot/f_6_1.dot +24 -0
  37. data/doc/dot/f_6_1.png +0 -0
  38. data/doc/dot/f_7.dot +62 -0
  39. data/doc/dot/f_7.png +0 -0
  40. data/doc/files/COPYING.html +168 -0
  41. data/doc/files/README.html +146 -0
  42. data/doc/files/TODO.html +240 -0
  43. data/doc/files/lib/contract/assertions_rb.html +118 -0
  44. data/doc/files/lib/contract/exception_rb.html +125 -0
  45. data/doc/files/lib/contract/integration_rb.html +130 -0
  46. data/doc/files/lib/contract/overrides_rb.html +118 -0
  47. data/doc/files/lib/contract_rb.html +127 -0
  48. data/doc/fr_class_index.html +40 -0
  49. data/doc/fr_file_index.html +34 -0
  50. data/doc/fr_method_index.html +45 -0
  51. data/doc/index.html +24 -0
  52. data/doc/rdoc-style.css +208 -0
  53. data/lib/contract.rb +146 -0
  54. data/lib/contract/assertions.rb +42 -0
  55. data/lib/contract/exception.rb +95 -0
  56. data/lib/contract/integration.rb +664 -0
  57. data/lib/contract/overrides.rb +41 -0
  58. data/setup.rb +1360 -0
  59. data/test/coverage/_-lib-contract-assertions_rb.html +526 -0
  60. data/test/coverage/_-lib-contract-exception_rb.html +632 -0
  61. data/test/coverage/_-lib-contract-integration_rb.html +1450 -0
  62. data/test/coverage/_-lib-contract-overrides_rb.html +524 -0
  63. data/test/coverage/_-lib-contract_rb.html +724 -0
  64. data/test/coverage/__-lib-contract-assertions_rb.html +484 -0
  65. data/test/coverage/__-lib-contract-exception_rb.html +537 -0
  66. data/test/coverage/__-lib-contract-integration_rb.html +946 -0
  67. data/test/coverage/__-lib-contract-overrides_rb.html +483 -0
  68. data/test/coverage/__-lib-contract_rb.html +583 -0
  69. data/test/coverage/index.html +93 -0
  70. data/test/tc_all.rb +8 -0
  71. data/test/tc_contract.rb +109 -0
  72. data/test/tc_exception.rb +43 -0
  73. data/test/tc_integration.rb +357 -0
  74. metadata +136 -0
@@ -0,0 +1,93 @@
1
+ <?xml version="1.0" encoding="ISO-8859-15"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
+ "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
+ <html xmlns="http://www.w3.org/1999/xhtml">
5
+ <head><title>coverage</title>
6
+ <style type="text/css">body {
7
+ background-color: rgb(180, 180, 180));
8
+ }
9
+ span.marked {
10
+ background-color: rgb(185, 200, 200);
11
+ display: block;
12
+ }
13
+ span.inferred {
14
+ background-color: rgb(180, 195, 195);
15
+ display: block;
16
+ }
17
+ span.overview {
18
+ border-bottom: 8px solid black;
19
+ }
20
+ </style></head>
21
+ <body><h3><tt>Sat Feb 05 23:35:41 Westeurop�ische Normalzeit 2005</tt></h3><h1>Average (code only): 45.9%</h1><h2>Average (with comments): 47.8%</h2><table><tr>
22
+ <td><a href="_-lib-contract_rb.html">./lib/contract.rb</a></td>
23
+ <td><tt>282</tt></td>
24
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
25
+ <td><tt>122</tt></td>
26
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
27
+ <td><tt>48.9%</tt></td>
28
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
29
+ <td><tt>47.5%</tt></td>
30
+ </tr>
31
+ <tr>
32
+ <td><a href="_-lib-contract-assertions_rb.html">./lib/contract/assertions.rb</a></td>
33
+ <td><tt>84</tt></td>
34
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
35
+ <td><tt>20</tt></td>
36
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
37
+ <td><tt>50.0%</tt></td>
38
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
39
+ <td><tt>50.0%</tt></td>
40
+ </tr>
41
+ <tr>
42
+ <td><a href="_-lib-contract-exception_rb.html">./lib/contract/exception.rb</a></td>
43
+ <td><tt>190</tt></td>
44
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
45
+ <td><tt>110</tt></td>
46
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
47
+ <td><tt>50.0%</tt></td>
48
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
49
+ <td><tt>50.0%</tt></td>
50
+ </tr>
51
+ <tr>
52
+ <td><a href="_-lib-contract-integration_rb.html">./lib/contract/integration.rb</a></td>
53
+ <td><tt>1008</tt></td>
54
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
55
+ <td><tt>494</tt></td>
56
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
57
+ <td><tt>46.6%</tt></td>
58
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
59
+ <td><tt>43.9%</tt></td>
60
+ </tr>
61
+ <tr>
62
+ <td><a href="_-lib-contract-overrides_rb.html">./lib/contract/overrides.rb</a></td>
63
+ <td><tt>82</tt></td>
64
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
65
+ <td><tt>50</tt></td>
66
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
67
+ <td><tt>50.0%</tt></td>
68
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
69
+ <td><tt>50.0%</tt></td>
70
+ </tr>
71
+ <tr><td>TOTAL</td>
72
+ <td><tt>1646</tt></td>
73
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
74
+ <td><tt>796</tt></td>
75
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
76
+ <td><tt>47.8%</tt></td>
77
+ <td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td>
78
+ <td><tt>45.9%</tt></td>
79
+ </tr></table>
80
+ <hr />
81
+ <p>
82
+ <a href="http://validator.w3.org/check/referer">
83
+ <img src="http://www.w3.org/Icons/valid-xhtml11"
84
+ alt="Valid XHTML 1.1!" height="31" width="88" />
85
+ </a>
86
+ <a href="http://jigsaw.w3.org/css-validator/">
87
+ <img style="border:0;width:88px;height:31px"
88
+ src="http://jigsaw.w3.org/css-validator/images/vcss"
89
+ alt="Valid CSS!" />
90
+ </a>
91
+ </p>
92
+ </body>
93
+ </html>
@@ -0,0 +1,8 @@
1
+ # Runs all tests.
2
+
3
+ $LOAD_PATH.unshift "lib"
4
+
5
+ test_dir = File.split(Dir.pwd).last == "test" ? "." : "test"
6
+
7
+ tests = Dir["#{test_dir}/**/*.rb"].reject { |file| file == "tc_all.rb" }
8
+ tests.each { |test| require test }
@@ -0,0 +1,109 @@
1
+ require 'test/unit'
2
+ $LOAD_PATH << "../lib"
3
+ require 'contract'
4
+
5
+ class TC_Integration_Signature < Test::Unit::TestCase
6
+ class EnumerableContract < Contract
7
+ provides :each
8
+ end
9
+
10
+ module List
11
+ module NonEmpty; end
12
+ end
13
+
14
+ class ListContract < Contract
15
+ implies List
16
+
17
+ def self.check_count() 3 end
18
+
19
+ provides :each
20
+ provides :[]
21
+ provides :size do
22
+ assert(@object.size >= 0)
23
+ end
24
+ end
25
+
26
+ class NonEmptyListContract < ListContract
27
+ implies List::NonEmpty
28
+
29
+ provides :size do
30
+ assert(@object.size > 0)
31
+ end
32
+ end
33
+
34
+ class EmptyList
35
+ def each() end
36
+ def [](idx) end
37
+ def size() 0 end
38
+
39
+ fulfills ListContract
40
+ end
41
+
42
+ class NonEmptyList < EmptyList
43
+ def size() 1 end
44
+
45
+ fulfills NonEmptyListContract
46
+ end
47
+
48
+ class BrokenContract < Contract
49
+ provides :size do
50
+ [][]
51
+ end
52
+ end
53
+
54
+ def test_contract_test()
55
+ result = EnumerableContract.test([])
56
+ assert_equal(nil, result)
57
+ result = EnumerableContract.test(5)
58
+ assert_instance_of(Contract::ContractMismatch, result)
59
+ end
60
+
61
+ def test_contract_test_all()
62
+ result = ListContract.test_all([])
63
+ assert_equal(nil, result)
64
+ result = ListContract.test_all(Object.new)
65
+ assert_instance_of(Array, result)
66
+ assert_equal(ListContract.check_count, result.size)
67
+ end
68
+
69
+ def test_contract_fulfilled_by?()
70
+ result = EnumerableContract.fulfilled_by?([])
71
+ assert_equal(true, result)
72
+ result = EnumerableContract.fulfilled_by?(5)
73
+ assert_equal(false, result)
74
+ end
75
+
76
+ def test_contract_enforce()
77
+ assert_nothing_raised { ListContract.enforce([]) }
78
+ assert_raise(Contract::ContractMismatch) do
79
+ ListContract.enforce(5)
80
+ end
81
+ end
82
+
83
+ def test_broken_contract()
84
+ result = BrokenContract.test(5)
85
+ assert_instance_of(Contract::ContractError, result)
86
+ end
87
+
88
+ def test_implies_non_module()
89
+ assert_raise(TypeError) do
90
+ Class.new(Contract) { implies 5 }
91
+ end
92
+ end
93
+
94
+ def test_implications()
95
+ assert_equal([List], ListContract.implications)
96
+ end
97
+
98
+ def test_inherited_implications()
99
+ assert_equal([List, List::NonEmpty], NonEmptyListContract.implications)
100
+ end
101
+
102
+ def test_implies()
103
+ assert_equal(true, EmptyList.ancestors.include?(List))
104
+ end
105
+
106
+ def test_inherited_implies()
107
+ assert_equal(true, NonEmptyList.ancestors.include?(List::NonEmpty))
108
+ end
109
+ end
@@ -0,0 +1,43 @@
1
+ require 'test/unit'
2
+ $LOAD_PATH << "../lib"
3
+ require 'contract'
4
+
5
+ class TC_Exception < Test::Unit::TestCase
6
+ def test_extract_method_name()
7
+ { "test_provides_each(ListContract)" => "test_provides_each",
8
+ "test_foo(Foo::Bar)" => "test_foo",
9
+ "test_bar(#<Class:0x2ba5e08>)" => "test_bar"
10
+ }.each do |from, to|
11
+ assert_equal(to, Contract.extract_method_name(from))
12
+ end
13
+ end
14
+
15
+ def test_fault_to_exception()
16
+ name, backtrace, message, object, contract =
17
+ "test_name(Contract)", caller, "message", Object.new,
18
+ Class.new(Contract)
19
+ exception = Exception.new(message)
20
+ exception.set_backtrace(backtrace)
21
+
22
+ [ Test::Unit::Failure.new(name, backtrace, message),
23
+ Test::Unit::Error.new(name, exception)
24
+ ].each do |fault|
25
+ result = Contract.fault_to_exception(fault, object, contract)
26
+
27
+ assert_kind_of(Contract::ContractException, result)
28
+ assert_equal("test_name", result.test_method)
29
+ assert_equal(backtrace, result.backtrace)
30
+ assert_equal(message, result.original_message)
31
+ assert_equal(object, result.test_object)
32
+ assert_equal(contract, result.test_contract)
33
+
34
+ case fault
35
+ when Test::Unit::Failure then
36
+ assert_instance_of(Contract::ContractMismatch, result)
37
+ when Test::Unit::Error then
38
+ assert_instance_of(Contract::ContractError, result)
39
+ assert_equal(exception.class, result.type)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,357 @@
1
+ require 'test/unit'
2
+ $LOAD_PATH << "../lib"
3
+ require 'contract'
4
+
5
+ module SignatureHelpers
6
+ def object(type = Object, *args, &block)
7
+ Class.new(type, &block).new(*args)
8
+ end
9
+ end
10
+
11
+ class TC_Integration_Signature < Test::Unit::TestCase
12
+ include SignatureHelpers
13
+
14
+ def setup()
15
+ Contract.check_signatures = true
16
+ end
17
+
18
+ def test_incompatible_signature()
19
+ exception = assert_raise(ArgumentError) do
20
+ object do
21
+ signature :to_s, :any
22
+ end
23
+ end
24
+ assert_equal("signature isn't compatible with arity",
25
+ exception.message)
26
+ end
27
+
28
+ def test_empty_repeated()
29
+ exception = assert_raise(ArgumentError) do
30
+ object do
31
+ signature :to_s, :repeated => []
32
+ end
33
+ end
34
+ assert_equal("repeated arguments may not be an empty Array",
35
+ exception.message)
36
+ end
37
+
38
+ def test_invalid_specifier()
39
+ assert_raise(ArgumentError) do
40
+ object do
41
+ signature :is_a?, Class.new { undef :=== }.new
42
+ end
43
+ end
44
+ end
45
+
46
+ def test_no_arguments()
47
+ obj = object do
48
+ alias :old_to_s :to_s
49
+ signature :to_s
50
+ end
51
+ assert_nothing_raised { obj.to_s }
52
+ assert_equal(obj.old_to_s, obj.to_s)
53
+ assert_raise(ArgumentError) { obj.to_s(1) }
54
+ end
55
+
56
+ def test_return()
57
+ obj = object do
58
+ signature :inspect, :return => String
59
+ def foo() end
60
+ signature :foo, :return => String
61
+ end
62
+ assert_nothing_raised { obj.inspect }
63
+ assert_raise(StandardError) { obj.foo }
64
+ end
65
+
66
+ def test_no_block()
67
+ obj = object do
68
+ signature :to_s, :block => false
69
+ end
70
+ assert_nothing_raised { obj.to_s }
71
+ assert_raise(ArgumentError) { obj.to_s { 1+1 } }
72
+ end
73
+
74
+ def test_block()
75
+ obj = object(Array) do
76
+ signature :each, :block => true
77
+ end
78
+ assert_nothing_raised { obj.each {} }
79
+ assert_raise(ArgumentError) { obj.each }
80
+ end
81
+
82
+ def test_any_arguments()
83
+ obj = object do
84
+ signature :respond_to?, :any, :any
85
+ end
86
+ assert_nothing_raised { obj.respond_to?(:inspect, true) }
87
+ assert_raise(ArgumentError) { obj.respond_to?() }
88
+ end
89
+
90
+ def test_allow_trailing()
91
+ obj = object(Array) do
92
+ signature :zip, :allow_trailing => true
93
+ signature :values_at, :any, :allow_trailing => true
94
+ end
95
+ assert_nothing_raised { obj.zip }
96
+ assert_nothing_raised { obj.zip(obj) }
97
+ assert_nothing_raised { obj.values_at(0) }
98
+ assert_nothing_raised { obj.values_at(0, 0) }
99
+ assert_raise(ArgumentError) { obj.values_at }
100
+ end
101
+
102
+ def test_classes()
103
+ obj = object(Array) do
104
+ signature :is_a?, Module
105
+ signature :join, String
106
+ signature :at, Integer
107
+ end
108
+ assert_nothing_raised { obj.is_a?(Array) }
109
+ assert_nothing_raised { obj.join(", ") }
110
+ assert_nothing_raised { obj.at(0) }
111
+ assert_raise(ArgumentError) { obj.is_a?(5) }
112
+ assert_raise(ArgumentError) { obj.join(5) }
113
+ assert_raise(ArgumentError) { obj.at("x") }
114
+ end
115
+
116
+ def test_callable()
117
+ obj = object(Array) do
118
+ alias :x :*
119
+
120
+ signature :*, lambda { |arg| arg >= 0 }
121
+ signature :x, 0.method(:<=)
122
+ end
123
+
124
+ assert_nothing_raised { obj * 0 }
125
+ assert_nothing_raised { obj.x(0) }
126
+ assert_raise(ArgumentError) { obj * -1 }
127
+ assert_raise(ArgumentError) { obj.x(-1) }
128
+ end
129
+
130
+ def test_optional()
131
+ obj = object do
132
+ def foo(x, y=5, z=3, *args) [x, y, z, *args] end
133
+ signature :foo, Numeric, :optional => [Numeric, Numeric],
134
+ :allow_trailing => true
135
+ end
136
+
137
+ assert_nothing_raised { obj.foo(5) }
138
+ assert_equal([5, 5, 3], obj.foo(5))
139
+ assert_nothing_raised { obj.foo(5, 4, 3) }
140
+ assert_nothing_raised { obj.foo(5, 4, 3, 2) }
141
+ assert_equal([5, 4, 3, 2], obj.foo(5, 4, 3, 2))
142
+ assert_raise(ArgumentError) { obj.foo }
143
+ assert_raise(ArgumentError) { obj.foo(5, "foo") }
144
+ end
145
+
146
+ def test_repeated()
147
+ obj = object(Array) do
148
+ signature :zip, :repeated => [Enumerable]
149
+ signature :values_at, Numeric, :repeated => Numeric
150
+ end
151
+ assert_nothing_raised { obj.zip }
152
+ assert_nothing_raised { obj.zip(obj) }
153
+ assert_nothing_raised { obj.values_at(0) }
154
+ assert_nothing_raised { obj.values_at(0, 0) }
155
+ assert_raise(ArgumentError) { obj.values_at }
156
+ end
157
+
158
+ def test_no_adaption()
159
+ obj = object do
160
+ signature :respond_to?, Symbol, :no_adaption => true
161
+ end
162
+ assert_nothing_raised { obj.respond_to?(:to_s) }
163
+ assert_raises(ArgumentError) { obj.respond_to?("to_s") }
164
+ end
165
+ end
166
+
167
+
168
+ class TC_Integration_Checks < Test::Unit::TestCase
169
+ def test_block()
170
+ check = Contract::Check.block { |obj| obj > 0 }
171
+ assert_equal(true, check === 5)
172
+ assert_equal(false, check === -5)
173
+ end
174
+
175
+ def test_quack()
176
+ check = Contract::Check::Quack[:to_str]
177
+ assert_equal(true, check === "foo")
178
+ assert_equal(false, check === Object.new)
179
+ end
180
+
181
+ def test_all()
182
+ check = Contract::Check::All[Numeric, 3 .. 10]
183
+ assert_equal(false, check === "x")
184
+ assert_equal(false, check === 2)
185
+ assert_equal(true, check === 5)
186
+ end
187
+
188
+ def test_any()
189
+ check = Contract::Check::Any[Numeric, Symbol]
190
+ assert_equal(false, check === "x")
191
+ assert_equal(true, check === 5)
192
+ assert_equal(true, check === :x)
193
+ end
194
+
195
+ def test_none()
196
+ check = Contract::Check::None[Numeric, Symbol]
197
+ assert_equal(true, check === "x")
198
+ assert_equal(false, check === 5)
199
+ assert_equal(false, check === :x)
200
+ end
201
+
202
+ def test_aliases()
203
+ assert_equal(Contract::Check::All, Contract::Check::And)
204
+ assert_equal(Contract::Check::Any, Contract::Check::Or)
205
+ assert_equal(Contract::Check::None, Contract::Check::Not)
206
+ end
207
+ end
208
+
209
+
210
+ class TC_Integration_Fulfills < Test::Unit::TestCase
211
+ class ListContract < Contract
212
+ provides :each, :[]
213
+ provides :size do
214
+ assert_nothing_raised { @object.size }
215
+ assert(@object.size >= 0)
216
+ end
217
+ end
218
+
219
+ class ListWrapper
220
+ def initialize(list)
221
+ @list = list
222
+ end
223
+
224
+ def each(&block) @list.each(&block) end
225
+ def size() @list.size end
226
+ def [](*args) @list[*args] end
227
+
228
+ fulfills ListContract
229
+ end
230
+
231
+ def setup()
232
+ Contract.check_fulfills = true
233
+ end
234
+
235
+ def test_fulfills()
236
+ assert_nothing_raised { ListWrapper.new([]) }
237
+ assert_raise(Contract::ContractMismatch) { ListWrapper.new(Object.new) }
238
+ end
239
+ end
240
+
241
+
242
+ class TC_Integration_Adaption < Test::Unit::TestCase
243
+ include SignatureHelpers
244
+
245
+ def test_no_from_and_to()
246
+ assert_raises(ArgumentError) do
247
+ object { adaption :via => :to_s }
248
+ end
249
+
250
+ assert_raises(ArgumentError) do
251
+ cls = Class.new
252
+ adaption :from => cls, :to => cls, :via => :to_s
253
+ end
254
+ end
255
+
256
+ def test_no_via()
257
+ assert_raises(ArgumentError) do
258
+ adaption :from => Class.new, :to => Class.new
259
+ end
260
+ end
261
+
262
+ def test_via_and_block()
263
+ assert_raises(ArgumentError) do
264
+ adaption :from => Class.new, :to => Class.new, :via => :to_s do |obj|
265
+ obj.to_s
266
+ end
267
+ end
268
+ end
269
+
270
+ def test_block()
271
+ obj = object do
272
+ adaption(:to => String) { "string" }
273
+ end
274
+
275
+ assert_equal("string", Contract.adapt(obj, String))
276
+ end
277
+
278
+ def test_callable_if()
279
+ cls = Class.new(Object) do
280
+ attr_accessor :value
281
+
282
+ def initialize(value)
283
+ @value = value
284
+ end
285
+ end
286
+
287
+ obj = object do
288
+ adaption :from => cls, :to => String, :via => :value,
289
+ :if => lambda { |obj| obj.value.is_a?(String) }
290
+ end
291
+
292
+ assert_equal("foo", Contract.adapt(cls.new("foo"), String))
293
+ obj = cls.new(5)
294
+ assert_equal(obj, Contract.adapt(obj, String))
295
+ end
296
+
297
+ def test_default_adaptions()
298
+ obj = object do
299
+ [Symbol, String, Array, Integer].each do |cls|
300
+ method = cls.name.downcase.intern
301
+ define_method(method) { |arg| arg }
302
+ signature(method, cls)
303
+ end
304
+ end
305
+
306
+ string_like = object { def to_str() "foo" end }
307
+ array_like = object { def to_ary() [1, 2] end }
308
+
309
+ assert_equal(:foo, obj.symbol("foo"))
310
+ assert_equal("foo", obj.string(string_like))
311
+ assert_equal([1, 2], obj.array(array_like))
312
+ assert_equal(5, obj.integer(5.0))
313
+ end
314
+ end
315
+
316
+
317
+ class TC_Integration_MethodSignatureMixin < Test::Unit::TestCase
318
+ include SignatureHelpers
319
+
320
+ def test_origin()
321
+ assert_equal(String, "foo".method(:+).origin)
322
+ assert_equal(Array, Array.instance_method(:[]).origin)
323
+ end
324
+
325
+ def test_name()
326
+ assert_equal(:+, "foo".method(:+).name)
327
+ assert_equal(:[], Array.instance_method(:[]).name)
328
+ end
329
+
330
+ def test_has_signature?()
331
+ assert(!"foo".method(:+).has_signature?)
332
+ obj = object do
333
+ def x() end
334
+ signature :x
335
+ end
336
+ assert(obj.method(:x).has_signature?)
337
+ end
338
+
339
+ def test_signature()
340
+ obj = object do
341
+ def m0() end
342
+ def m1(a) end
343
+ def t(a,*) end
344
+ end
345
+ assert_equal([[], {}], obj.method(:m0).signature)
346
+ assert_equal([[:any], {}], obj.method(:m1).signature)
347
+ assert_equal([[:any], { :allow_trailing => true }],
348
+ obj.method(:t).signature)
349
+
350
+ sign = [[Fixnum, String], { :repeated => [1 .. 10, 2 .. 3] }]
351
+ obj = object do
352
+ def x(*) end
353
+ signature(:x, *sign.flatten)
354
+ end
355
+ assert_equal(sign, obj.method(:x).signature)
356
+ end
357
+ end