contracts 0.10.1 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.markdown +9 -1
- data/TUTORIAL.md +51 -34
- data/lib/contracts.rb +10 -38
- data/lib/contracts/builtin_contracts.rb +16 -0
- data/lib/contracts/call_with.rb +3 -2
- data/lib/contracts/core.rb +45 -0
- data/lib/contracts/validators.rb +6 -0
- data/lib/contracts/version.rb +1 -1
- data/spec/builtin_contracts_spec.rb +36 -4
- data/spec/contracts_spec.rb +12 -2
- data/spec/fixtures/fixtures.rb +103 -84
- data/spec/module_spec.rb +2 -2
- data/spec/override_validators_spec.rb +4 -4
- data/spec/ruby_version_specific/contracts_spec_1.9.rb +2 -2
- data/spec/ruby_version_specific/contracts_spec_2.0.rb +2 -2
- data/spec/ruby_version_specific/contracts_spec_2.1.rb +4 -4
- data/spec/validators_spec.rb +25 -0
- metadata +5 -4
@@ -0,0 +1,45 @@
|
|
1
|
+
module Contracts
|
2
|
+
module Core
|
3
|
+
def self.included(base)
|
4
|
+
common(base)
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.extended(base)
|
8
|
+
common(base)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.common(base)
|
12
|
+
return if base.respond_to?(:Contract)
|
13
|
+
|
14
|
+
base.extend(MethodDecorators)
|
15
|
+
|
16
|
+
base.instance_eval do
|
17
|
+
def functype(funcname)
|
18
|
+
contracts = Engine.fetch_from(self).decorated_methods_for(:class_methods, funcname)
|
19
|
+
if contracts.nil?
|
20
|
+
"No contract for #{self}.#{funcname}"
|
21
|
+
else
|
22
|
+
"#{funcname} :: #{contracts[0]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
base.class_eval do
|
28
|
+
# TODO: deprecate
|
29
|
+
# Required when contracts are included in global scope
|
30
|
+
def Contract(*args)
|
31
|
+
self.class.Contract(*args)
|
32
|
+
end
|
33
|
+
|
34
|
+
def functype(funcname)
|
35
|
+
contracts = Engine.fetch_from(self.class).decorated_methods_for(:instance_methods, funcname)
|
36
|
+
if contracts.nil?
|
37
|
+
"No contract for #{self.class}.#{funcname}"
|
38
|
+
else
|
39
|
+
"#{funcname} :: #{contracts[0]}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
data/lib/contracts/validators.rb
CHANGED
data/lib/contracts/version.rb
CHANGED
@@ -150,7 +150,7 @@ RSpec.describe "Contracts:" do
|
|
150
150
|
end
|
151
151
|
|
152
152
|
it "should fail for an object with both methods :good and :bad" do
|
153
|
-
expect { @o.xor_test(
|
153
|
+
expect { @o.xor_test(F.new) }.to raise_error(ContractError)
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -160,7 +160,17 @@ RSpec.describe "Contracts:" do
|
|
160
160
|
end
|
161
161
|
|
162
162
|
it "should fail for an object that has a method :good but isn't of class A" do
|
163
|
-
expect { @o.and_test(
|
163
|
+
expect { @o.and_test(F.new) }.to raise_error(ContractError)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "Enum:" do
|
168
|
+
it "should pass for an object that is included" do
|
169
|
+
expect { @o.enum_test(:a) }.to_not raise_error
|
170
|
+
end
|
171
|
+
|
172
|
+
it "should fail for an object that is not included" do
|
173
|
+
expect { @o.enum_test(:z) }.to raise_error(ContractError)
|
164
174
|
end
|
165
175
|
end
|
166
176
|
|
@@ -180,7 +190,7 @@ RSpec.describe "Contracts:" do
|
|
180
190
|
end
|
181
191
|
|
182
192
|
it "should fail for an object that returns false for method :good" do
|
183
|
-
expect { @o.send_test(
|
193
|
+
expect { @o.send_test(F.new) }.to raise_error(ContractError)
|
184
194
|
end
|
185
195
|
end
|
186
196
|
|
@@ -322,6 +332,26 @@ RSpec.describe "Contracts:" do
|
|
322
332
|
end
|
323
333
|
end
|
324
334
|
|
335
|
+
describe "KeywordArgs:" do
|
336
|
+
it "should pass for exact correct input" do
|
337
|
+
expect { @o.person_keywordargs(:name => "calvin", :age => 10) }.to_not raise_error
|
338
|
+
end
|
339
|
+
|
340
|
+
it "should fail if some keys don't have contracts" do
|
341
|
+
expect { @o.person_keywordargs(:name => "calvin", :age => 10, :foo => "bar") }.to raise_error(ContractError)
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should fail if a key with a contract on it isn't provided" do
|
345
|
+
expect { @o.person_keywordargs(:name => "calvin") }.to raise_error(ContractError)
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should fail for incorrect input" do
|
349
|
+
expect { @o.person_keywordargs(:name => 50, :age => 10) }.to raise_error(ContractError)
|
350
|
+
expect { @o.hash_keywordargs(:hash => nil) }.to raise_error(ContractError)
|
351
|
+
expect { @o.hash_keywordargs(:hash => 1) }.to raise_error(ContractError)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
325
355
|
describe "Optional:" do
|
326
356
|
it "can't be used outside of KeywordArgs" do
|
327
357
|
expect do
|
@@ -334,7 +364,7 @@ RSpec.describe "Contracts:" do
|
|
334
364
|
it "doesn't allow to specify multiple key-value pairs with pretty syntax" do
|
335
365
|
expect do
|
336
366
|
Class.new do
|
337
|
-
include Contracts
|
367
|
+
include Contracts::Core
|
338
368
|
|
339
369
|
Contract Contracts::HashOf[Symbol => String, Contracts::Num => Contracts::Num] => nil
|
340
370
|
def something(hash)
|
@@ -351,6 +381,8 @@ RSpec.describe "Contracts:" do
|
|
351
381
|
|
352
382
|
context "given an unfulfilled contract" do
|
353
383
|
it { expect { @o.gives_max_value(:panda => "1", :bamboo => "2") }.to raise_error(ContractError) }
|
384
|
+
it { expect { @o.gives_max_value(nil) }.to raise_error(ContractError) }
|
385
|
+
it { expect { @o.gives_max_value(1) }.to raise_error(ContractError) }
|
354
386
|
it { expect { @o.pretty_gives_max_value(:panda => "1", :bamboo => "2") }.to raise_error(ContractError) }
|
355
387
|
end
|
356
388
|
|
data/spec/contracts_spec.rb
CHANGED
@@ -226,7 +226,7 @@ RSpec.describe "Contracts:" do
|
|
226
226
|
describe "anonymous classes" do
|
227
227
|
let(:klass) do
|
228
228
|
Class.new do
|
229
|
-
include Contracts
|
229
|
+
include Contracts::Core
|
230
230
|
|
231
231
|
Contract String => String
|
232
232
|
def greeting(name)
|
@@ -249,7 +249,7 @@ RSpec.describe "Contracts:" do
|
|
249
249
|
describe "anonymous modules" do
|
250
250
|
let(:mod) do
|
251
251
|
Module.new do
|
252
|
-
include Contracts
|
252
|
+
include Contracts::Core
|
253
253
|
|
254
254
|
Contract String => String
|
255
255
|
def greeting(name)
|
@@ -423,6 +423,16 @@ RSpec.describe "Contracts:" do
|
|
423
423
|
@o.maybe_call("bad")
|
424
424
|
end.to raise_error(ContractError)
|
425
425
|
end
|
426
|
+
|
427
|
+
describe "varargs are given with a maybe block" do
|
428
|
+
it "when a block is passed in, varargs should be correct" do
|
429
|
+
expect(@o.maybe_call(1, 2, 3) { 1 + 1 }).to eq([1, 2, 3])
|
430
|
+
end
|
431
|
+
|
432
|
+
it "when a block is NOT passed in, varargs should still be correct" do
|
433
|
+
expect(@o.maybe_call(1, 2, 3)).to eq([1, 2, 3])
|
434
|
+
end
|
435
|
+
end
|
426
436
|
end
|
427
437
|
|
428
438
|
describe "varargs" do
|
data/spec/fixtures/fixtures.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "date"
|
2
2
|
|
3
|
+
C = Contracts
|
4
|
+
|
3
5
|
class A
|
4
|
-
include Contracts
|
6
|
+
include Contracts::Core
|
5
7
|
|
6
|
-
Contract Num => Num
|
8
|
+
Contract C::Num => C::Num
|
7
9
|
def self.a_class_method x
|
8
10
|
x + 1
|
9
11
|
end
|
@@ -12,12 +14,12 @@ class A
|
|
12
14
|
true
|
13
15
|
end
|
14
16
|
|
15
|
-
Contract Num => Num
|
17
|
+
Contract C::Num => C::Num
|
16
18
|
def triple x
|
17
19
|
x * 3
|
18
20
|
end
|
19
21
|
|
20
|
-
Contract Num => Num
|
22
|
+
Contract C::Num => C::Num
|
21
23
|
def instance_and_class_method x
|
22
24
|
x * 2
|
23
25
|
end
|
@@ -29,7 +31,7 @@ class A
|
|
29
31
|
end
|
30
32
|
|
31
33
|
class B
|
32
|
-
include Contracts
|
34
|
+
include Contracts::Core
|
33
35
|
|
34
36
|
def bad
|
35
37
|
false
|
@@ -41,8 +43,8 @@ class B
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
44
|
-
class
|
45
|
-
include Contracts
|
46
|
+
class F
|
47
|
+
include Contracts::Core
|
46
48
|
|
47
49
|
def good
|
48
50
|
false
|
@@ -60,19 +62,19 @@ class EmptyCont
|
|
60
62
|
end
|
61
63
|
|
62
64
|
class GenericExample
|
63
|
-
include Contracts
|
65
|
+
include Contracts::Core
|
64
66
|
|
65
|
-
Contract Num => Num
|
67
|
+
Contract C::Num => C::Num
|
66
68
|
def self.a_class_method x
|
67
69
|
x + 1
|
68
70
|
end
|
69
71
|
|
70
|
-
Contract Num => nil
|
72
|
+
Contract C::Num => nil
|
71
73
|
def bad_double(x)
|
72
74
|
x * 2
|
73
75
|
end
|
74
76
|
|
75
|
-
Contract Num => Num
|
77
|
+
Contract C::Num => C::Num
|
76
78
|
def double(x)
|
77
79
|
x * 2
|
78
80
|
end
|
@@ -86,12 +88,12 @@ class GenericExample
|
|
86
88
|
def hello(name)
|
87
89
|
end
|
88
90
|
|
89
|
-
Contract lambda { |x| x.is_a? Numeric } => Num
|
91
|
+
Contract lambda { |x| x.is_a? Numeric } => C::Num
|
90
92
|
def square(x)
|
91
93
|
x ** 2
|
92
94
|
end
|
93
95
|
|
94
|
-
Contract [Num, Num, Num] => Num
|
96
|
+
Contract [C::Num, C::Num, C::Num] => C::Num
|
95
97
|
def sum_three(vals)
|
96
98
|
vals.inject(0) do |acc, x|
|
97
99
|
acc + x
|
@@ -102,43 +104,52 @@ class GenericExample
|
|
102
104
|
def person(data)
|
103
105
|
end
|
104
106
|
|
105
|
-
Contract ({ :rigged => Or[TrueClass, FalseClass] }) => nil
|
107
|
+
Contract ({ :rigged => C::Or[TrueClass, FalseClass] }) => nil
|
106
108
|
def hash_complex_contracts(data)
|
107
109
|
end
|
108
110
|
|
109
|
-
Contract ({ :rigged => Bool,
|
110
|
-
:contents => { :kind => Or[String, Symbol],
|
111
|
-
:total => Num }
|
111
|
+
Contract ({ :rigged => C::Bool,
|
112
|
+
:contents => { :kind => C::Or[String, Symbol],
|
113
|
+
:total => C::Num }
|
112
114
|
}) => nil
|
113
115
|
def nested_hash_complex_contracts(data)
|
114
116
|
end
|
115
117
|
|
116
|
-
Contract [
|
118
|
+
Contract C::KeywordArgs[:name => String, :age => Fixnum] => nil
|
119
|
+
def person_keywordargs(data)
|
120
|
+
end
|
121
|
+
|
122
|
+
Contract C::KeywordArgs[:hash => C::HashOf[Symbol, C::Num]] => nil
|
123
|
+
def hash_keywordargs(data)
|
124
|
+
end
|
125
|
+
|
126
|
+
Contract [C::Or[TrueClass, FalseClass]] => nil
|
117
127
|
def array_complex_contracts(data)
|
118
128
|
end
|
119
129
|
|
120
|
-
Contract [Bool, [Or[String, Symbol]]] => nil
|
130
|
+
Contract [C::Bool, [C::Or[String, Symbol]]] => nil
|
121
131
|
def nested_array_complex_contracts(data)
|
122
132
|
end
|
123
133
|
|
124
|
-
Contract Proc => Any
|
134
|
+
Contract Proc => C::Any
|
125
135
|
def do_call(&block)
|
126
136
|
block.call
|
127
137
|
end
|
128
138
|
|
129
|
-
Contract Args[Num], Maybe[Proc] => Any
|
139
|
+
Contract C::Args[C::Num], C::Maybe[Proc] => C::Any
|
130
140
|
def maybe_call(*vals, &block)
|
131
141
|
block.call if block
|
142
|
+
vals
|
132
143
|
end
|
133
144
|
|
134
|
-
Contract Args[Num] => Num
|
145
|
+
Contract C::Args[C::Num] => C::Num
|
135
146
|
def sum(*vals)
|
136
147
|
vals.inject(0) do |acc, val|
|
137
148
|
acc + val
|
138
149
|
end
|
139
150
|
end
|
140
151
|
|
141
|
-
Contract Args[Num], Proc => Num
|
152
|
+
Contract C::Args[C::Num], Proc => C::Num
|
142
153
|
def with_partial_sums(*vals, &blk)
|
143
154
|
sum = vals.inject(0) do |acc, val|
|
144
155
|
blk[acc]
|
@@ -147,7 +158,7 @@ class GenericExample
|
|
147
158
|
blk[sum]
|
148
159
|
end
|
149
160
|
|
150
|
-
Contract Args[Num], Func[Num => Num] => Num
|
161
|
+
Contract C::Args[C::Num], C::Func[C::Num => C::Num] => C::Num
|
151
162
|
def with_partial_sums_contracted(*vals, &blk)
|
152
163
|
sum = vals.inject(0) do |acc, val|
|
153
164
|
blk[acc]
|
@@ -157,102 +168,106 @@ class GenericExample
|
|
157
168
|
end
|
158
169
|
|
159
170
|
# Important to use different arg types or it falsely passes
|
160
|
-
Contract Num, Args[String] => ArrayOf[String]
|
171
|
+
Contract C::Num, C::Args[String] => C::ArrayOf[String]
|
161
172
|
def arg_then_splat(n, *vals)
|
162
173
|
vals.map { |v| v * n }
|
163
174
|
end
|
164
175
|
|
165
|
-
Contract Num, Proc => nil
|
176
|
+
Contract C::Num, Proc => nil
|
166
177
|
def double_with_proc(x, &blk)
|
167
178
|
blk.call(x * 2)
|
168
179
|
nil
|
169
180
|
end
|
170
181
|
|
171
|
-
Contract Pos => nil
|
182
|
+
Contract C::Pos => nil
|
172
183
|
def pos_test(x)
|
173
184
|
end
|
174
185
|
|
175
|
-
Contract Neg => nil
|
186
|
+
Contract C::Neg => nil
|
176
187
|
def neg_test(x)
|
177
188
|
end
|
178
189
|
|
179
|
-
Contract Nat => nil
|
190
|
+
Contract C::Nat => nil
|
180
191
|
def nat_test(x)
|
181
192
|
end
|
182
193
|
|
183
|
-
Contract Any => nil
|
194
|
+
Contract C::Any => nil
|
184
195
|
def show(x)
|
185
196
|
end
|
186
197
|
|
187
|
-
Contract None => nil
|
198
|
+
Contract C::None => nil
|
188
199
|
def fail_all(x)
|
189
200
|
end
|
190
201
|
|
191
|
-
Contract Or[Num, String] => nil
|
202
|
+
Contract C::Or[C::Num, String] => nil
|
192
203
|
def num_or_string(x)
|
193
204
|
end
|
194
205
|
|
195
|
-
Contract Xor[RespondTo[:good], RespondTo[:bad]] => nil
|
206
|
+
Contract C::Xor[C::RespondTo[:good], C::RespondTo[:bad]] => nil
|
196
207
|
def xor_test(x)
|
197
208
|
end
|
198
209
|
|
199
|
-
Contract And[A, RespondTo[:good]] => nil
|
210
|
+
Contract C::And[A, C::RespondTo[:good]] => nil
|
200
211
|
def and_test(x)
|
201
212
|
end
|
202
213
|
|
203
|
-
Contract
|
214
|
+
Contract C::Enum[:a, :b, :c] => nil
|
215
|
+
def enum_test(x)
|
216
|
+
end
|
217
|
+
|
218
|
+
Contract C::RespondTo[:good] => nil
|
204
219
|
def responds_test(x)
|
205
220
|
end
|
206
221
|
|
207
|
-
Contract Send[:good] => nil
|
222
|
+
Contract C::Send[:good] => nil
|
208
223
|
def send_test(x)
|
209
224
|
end
|
210
225
|
|
211
|
-
Contract Not[nil] => nil
|
226
|
+
Contract C::Not[nil] => nil
|
212
227
|
def not_nil(x)
|
213
228
|
end
|
214
229
|
|
215
|
-
Contract ArrayOf[Num] => Num
|
230
|
+
Contract C::ArrayOf[C::Num] => C::Num
|
216
231
|
def product(vals)
|
217
232
|
vals.inject(1) do |acc, x|
|
218
233
|
acc * x
|
219
234
|
end
|
220
235
|
end
|
221
236
|
|
222
|
-
Contract SetOf[Num] => Num
|
237
|
+
Contract C::SetOf[C::Num] => C::Num
|
223
238
|
def product_from_set(vals)
|
224
239
|
vals.inject(1) do |acc, x|
|
225
240
|
acc * x
|
226
241
|
end
|
227
242
|
end
|
228
243
|
|
229
|
-
Contract RangeOf[Num] => Num
|
244
|
+
Contract C::RangeOf[C::Num] => C::Num
|
230
245
|
def first_in_range_num(r)
|
231
246
|
r.first
|
232
247
|
end
|
233
248
|
|
234
|
-
Contract RangeOf[Date] => Date
|
249
|
+
Contract C::RangeOf[Date] => Date
|
235
250
|
def first_in_range_date(r)
|
236
251
|
r.first
|
237
252
|
end
|
238
253
|
|
239
|
-
Contract Bool => nil
|
254
|
+
Contract C::Bool => nil
|
240
255
|
def bool_test(x)
|
241
256
|
end
|
242
257
|
|
243
|
-
Contract Num
|
258
|
+
Contract C::Num
|
244
259
|
def no_args
|
245
260
|
1
|
246
261
|
end
|
247
262
|
|
248
263
|
# This function has a contract which says it has no args,
|
249
264
|
# but the function does have args.
|
250
|
-
Contract nil => Num
|
265
|
+
Contract nil => C::Num
|
251
266
|
def old_style_no_args
|
252
267
|
2
|
253
268
|
end
|
254
269
|
|
255
|
-
Contract ArrayOf[Num], Func[Num => Num] => ArrayOf[Num]
|
270
|
+
Contract C::ArrayOf[C::Num], C::Func[C::Num => C::Num] => C::ArrayOf[C::Num]
|
256
271
|
def map(arr, func)
|
257
272
|
ret = []
|
258
273
|
arr.each do |x|
|
@@ -261,7 +276,7 @@ class GenericExample
|
|
261
276
|
ret
|
262
277
|
end
|
263
278
|
|
264
|
-
Contract ArrayOf[Any], Proc => ArrayOf[Any]
|
279
|
+
Contract C::ArrayOf[C::Any], Proc => C::ArrayOf[C::Any]
|
265
280
|
def tutorial_map(arr, func)
|
266
281
|
ret = []
|
267
282
|
arr.each do |x|
|
@@ -272,29 +287,29 @@ class GenericExample
|
|
272
287
|
|
273
288
|
# Need to test Func with weak contracts for other args
|
274
289
|
# and changing type from input to output otherwise it falsely passes!
|
275
|
-
Contract Array, Func[String => Num] => Array
|
290
|
+
Contract Array, C::Func[String => C::Num] => Array
|
276
291
|
def map_plain(arr, func)
|
277
292
|
arr.map do |x|
|
278
293
|
func[x]
|
279
294
|
end
|
280
295
|
end
|
281
296
|
|
282
|
-
Contract None => Func[String => Num]
|
297
|
+
Contract C::None => C::Func[String => C::Num]
|
283
298
|
def lambda_with_wrong_return
|
284
299
|
lambda { |x| x }
|
285
300
|
end
|
286
301
|
|
287
|
-
Contract None => Func[String => Num]
|
302
|
+
Contract C::None => C::Func[String => C::Num]
|
288
303
|
def lambda_with_correct_return
|
289
304
|
lambda { |x| x.length }
|
290
305
|
end
|
291
306
|
|
292
|
-
Contract Num => Num
|
307
|
+
Contract C::Num => C::Num
|
293
308
|
def default_args(x = 1)
|
294
309
|
2
|
295
310
|
end
|
296
311
|
|
297
|
-
Contract Maybe[Num] => Maybe[Num]
|
312
|
+
Contract C::Maybe[C::Num] => C::Maybe[C::Num]
|
298
313
|
def maybe_double x
|
299
314
|
if x.nil?
|
300
315
|
nil
|
@@ -303,21 +318,25 @@ class GenericExample
|
|
303
318
|
end
|
304
319
|
end
|
305
320
|
|
306
|
-
Contract HashOf[Symbol, Num] => Num
|
321
|
+
Contract C::HashOf[Symbol, C::Num] => C::Num
|
307
322
|
def gives_max_value(hash)
|
308
323
|
hash.values.max
|
309
324
|
end
|
310
325
|
|
311
|
-
Contract HashOf[Symbol => Num] => Num
|
326
|
+
Contract C::HashOf[Symbol => C::Num] => C::Num
|
312
327
|
def pretty_gives_max_value(hash)
|
313
328
|
hash.values.max
|
314
329
|
end
|
315
330
|
|
316
|
-
Contract EmptyCont => Any
|
331
|
+
Contract EmptyCont => C::Any
|
317
332
|
def using_empty_contract(a)
|
318
333
|
a
|
319
334
|
end
|
320
335
|
|
336
|
+
Contract (1..10) => nil
|
337
|
+
def method_with_range_contract(x)
|
338
|
+
end
|
339
|
+
|
321
340
|
Contract String
|
322
341
|
def a_private_method
|
323
342
|
"works"
|
@@ -347,9 +366,9 @@ end
|
|
347
366
|
|
348
367
|
# for testing inheritance
|
349
368
|
class Parent
|
350
|
-
include Contracts
|
369
|
+
include Contracts::Core
|
351
370
|
|
352
|
-
Contract Num => Num
|
371
|
+
Contract C::Num => C::Num
|
353
372
|
def double x
|
354
373
|
x * 2
|
355
374
|
end
|
@@ -364,7 +383,7 @@ class GenericExample
|
|
364
383
|
a
|
365
384
|
end
|
366
385
|
|
367
|
-
Contract Exactly[Parent] => nil
|
386
|
+
Contract C::Exactly[Parent] => nil
|
368
387
|
def exactly_test(x)
|
369
388
|
end
|
370
389
|
end
|
@@ -377,22 +396,22 @@ end
|
|
377
396
|
Baz = 1
|
378
397
|
|
379
398
|
class GenericExample
|
380
|
-
Contract Eq[Foo] => Any
|
399
|
+
Contract C::Eq[Foo] => C::Any
|
381
400
|
def eq_class_test(x)
|
382
401
|
end
|
383
402
|
|
384
|
-
Contract Eq[Bar] => Any
|
403
|
+
Contract C::Eq[Bar] => C::Any
|
385
404
|
def eq_module_test(x)
|
386
405
|
end
|
387
406
|
|
388
|
-
Contract Eq[Baz] => Any
|
407
|
+
Contract C::Eq[Baz] => C::Any
|
389
408
|
def eq_value_test(x)
|
390
409
|
end
|
391
410
|
end
|
392
411
|
|
393
412
|
# pattern matching example with possible deep contract violation
|
394
413
|
class PatternMatchingExample
|
395
|
-
include Contracts
|
414
|
+
include Contracts::Core
|
396
415
|
|
397
416
|
class Success
|
398
417
|
attr_accessor :request
|
@@ -408,7 +427,7 @@ class PatternMatchingExample
|
|
408
427
|
class Failure
|
409
428
|
end
|
410
429
|
|
411
|
-
Response = Or[Success, Failure]
|
430
|
+
Response = C::Or[Success, Failure]
|
412
431
|
|
413
432
|
class StringWithHello
|
414
433
|
def self.valid?(string)
|
@@ -431,17 +450,17 @@ class PatternMatchingExample
|
|
431
450
|
request + "!"
|
432
451
|
end
|
433
452
|
|
434
|
-
Contract Num, String => String
|
453
|
+
Contract C::Num, String => String
|
435
454
|
def do_stuff(number, string)
|
436
455
|
"foo"
|
437
456
|
end
|
438
457
|
|
439
|
-
Contract Num, String, Num => String
|
458
|
+
Contract C::Num, String, C::Num => String
|
440
459
|
def do_stuff(number, string, other_number)
|
441
460
|
"bar"
|
442
461
|
end
|
443
462
|
|
444
|
-
Contract Num => Num
|
463
|
+
Contract C::Num => C::Num
|
445
464
|
def double x
|
446
465
|
"bad"
|
447
466
|
end
|
@@ -454,7 +473,7 @@ end
|
|
454
473
|
|
455
474
|
# invariant example (silliest implementation ever)
|
456
475
|
class MyBirthday
|
457
|
-
include Contracts
|
476
|
+
include Contracts::Core
|
458
477
|
include Contracts::Invariants
|
459
478
|
|
460
479
|
invariant(:day) { 1 <= day && day <= 31 }
|
@@ -466,30 +485,30 @@ class MyBirthday
|
|
466
485
|
@month = month
|
467
486
|
end
|
468
487
|
|
469
|
-
Contract None => Fixnum
|
488
|
+
Contract C::None => Fixnum
|
470
489
|
def silly_next_day!
|
471
490
|
self.day += 1
|
472
491
|
end
|
473
492
|
|
474
|
-
Contract None => Fixnum
|
493
|
+
Contract C::None => Fixnum
|
475
494
|
def silly_next_month!
|
476
495
|
self.month += 1
|
477
496
|
end
|
478
497
|
|
479
|
-
Contract None => Fixnum
|
498
|
+
Contract C::None => Fixnum
|
480
499
|
def clever_next_day!
|
481
500
|
return clever_next_month! if day == 31
|
482
501
|
self.day += 1
|
483
502
|
end
|
484
503
|
|
485
|
-
Contract None => Fixnum
|
504
|
+
Contract C::None => Fixnum
|
486
505
|
def clever_next_month!
|
487
506
|
return next_year! if month == 12
|
488
507
|
self.month += 1
|
489
508
|
self.day = 1
|
490
509
|
end
|
491
510
|
|
492
|
-
Contract None => Fixnum
|
511
|
+
Contract C::None => Fixnum
|
493
512
|
def next_year!
|
494
513
|
self.month = 1
|
495
514
|
self.day = 1
|
@@ -500,7 +519,7 @@ class SingletonClassExample
|
|
500
519
|
# This turned out to be required line here to make singleton classes
|
501
520
|
# work properly under all platforms. Not sure if it worth trying to
|
502
521
|
# do something with it.
|
503
|
-
include Contracts
|
522
|
+
include Contracts::Core
|
504
523
|
|
505
524
|
class << self
|
506
525
|
Contract String => String
|
@@ -508,7 +527,7 @@ class SingletonClassExample
|
|
508
527
|
"super#{str}"
|
509
528
|
end
|
510
529
|
|
511
|
-
Contract Num, Num => Num
|
530
|
+
Contract C::Num, C::Num => C::Num
|
512
531
|
def add(a, b)
|
513
532
|
a + b
|
514
533
|
end
|
@@ -517,7 +536,7 @@ end
|
|
517
536
|
|
518
537
|
with_enabled_no_contracts do
|
519
538
|
class NoContractsSimpleExample
|
520
|
-
include Contracts
|
539
|
+
include Contracts::Core
|
521
540
|
|
522
541
|
Contract String => nil
|
523
542
|
def some_method(x)
|
@@ -526,21 +545,21 @@ with_enabled_no_contracts do
|
|
526
545
|
end
|
527
546
|
|
528
547
|
class NoContractsInvariantsExample
|
529
|
-
include Contracts
|
548
|
+
include Contracts::Core
|
530
549
|
include Contracts::Invariants
|
531
550
|
|
532
551
|
attr_accessor :day
|
533
552
|
|
534
553
|
invariant(:day_rule) { 1 <= day && day <= 7 }
|
535
554
|
|
536
|
-
Contract None => nil
|
555
|
+
Contract C::None => nil
|
537
556
|
def next_day
|
538
557
|
self.day += 1
|
539
558
|
end
|
540
559
|
end
|
541
560
|
|
542
561
|
class NoContractsPatternMatchingExample
|
543
|
-
include Contracts
|
562
|
+
include Contracts::Core
|
544
563
|
|
545
564
|
Contract 200, String => String
|
546
565
|
def on_response(status, body)
|
@@ -555,9 +574,9 @@ with_enabled_no_contracts do
|
|
555
574
|
end
|
556
575
|
|
557
576
|
module ModuleExample
|
558
|
-
include Contracts
|
577
|
+
include Contracts::Core
|
559
578
|
|
560
|
-
Contract Num, Num => Num
|
579
|
+
Contract C::Num, C::Num => C::Num
|
561
580
|
def plus(a, b)
|
562
581
|
a + b
|
563
582
|
end
|
@@ -581,9 +600,9 @@ class KlassWithModuleExample
|
|
581
600
|
end
|
582
601
|
|
583
602
|
class SingletonInheritanceExample
|
584
|
-
include Contracts
|
603
|
+
include Contracts::Core
|
585
604
|
|
586
|
-
Contract Any => Any
|
605
|
+
Contract C::Any => C::Any
|
587
606
|
def self.a_contracted_self
|
588
607
|
self
|
589
608
|
end
|
@@ -593,16 +612,16 @@ class SingletonInheritanceExampleSubclass < SingletonInheritanceExample
|
|
593
612
|
end
|
594
613
|
|
595
614
|
class BareOptionalContractUsed
|
596
|
-
include Contracts
|
615
|
+
include Contracts::Core
|
597
616
|
|
598
|
-
Contract Num, Optional[Num] => nil
|
617
|
+
Contract C::Num, C::Optional[C::Num] => nil
|
599
618
|
def something(a, b)
|
600
619
|
nil
|
601
620
|
end
|
602
621
|
end
|
603
622
|
|
604
623
|
module ModuleContractExample
|
605
|
-
include Contracts
|
624
|
+
include Contracts::Core
|
606
625
|
|
607
626
|
module AModule
|
608
627
|
end
|