contracts 0.10.1 → 0.11.0
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.
- 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
|