contracts 0.14.0 → 0.15.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 +4 -0
- data/Gemfile +1 -1
- data/README.md +6 -2
- data/lib/contracts/builtin_contracts.rb +1 -1
- data/lib/contracts/call_with.rb +5 -2
- data/lib/contracts/decorators.rb +1 -0
- data/lib/contracts/version.rb +1 -1
- data/spec/builtin_contracts_spec.rb +113 -113
- data/spec/methods_spec.rb +54 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5f95ed9c9dca3e23e9feb707360335388730304e
|
4
|
+
data.tar.gz: 634613562833a5f69e2171163eb71e64314ae252
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e9393b9202596fbd5df5a53c1e4fd963ed9f5d881277f7705415fce911cba40c47ad0cf6ce993b1f94670fb8e5c7ab4ff9bcff9c20990826600969b686f7cce
|
7
|
+
data.tar.gz: 30bddf252a1e2da5a53223189bae378e834087ba3e1813c5acb8ad96bd62f75878d9bcf1afd4e861d87c63d1195af26ca1f9d89248b7089a54913090b52d1449
|
data/CHANGELOG.markdown
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
## v0.15.0
|
2
|
+
- Bugfix: Func contract's return value isn't enforced with blocks - [Piotr Szmielew](https://github.com/esse) [#251](https://github.com/egonSchiele/contracts.ruby/pull/251)
|
3
|
+
- Bugfx: Fix contracts used in AR-models - [Gert Goet](https://github.com/eval) [#237](https://github.com/egonSchiele/contracts.ruby/pull/237)
|
4
|
+
|
1
5
|
## v0.14.0
|
2
6
|
- Enhancement: Add StrictHash contract - [Fyodor](https://github.com/cbrwizard) [#236](https://github.com/egonSchiele/contracts.ruby/pull/236)
|
3
7
|
- Bugfix: dont fail if something other than a hash is passed to a KeywordArgs - [Dan Padilha](https://github.com/dpad) [#234](https://github.com/egonSchiele/contracts.ruby/pull/234)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -69,8 +69,12 @@ To get started do the following:
|
|
69
69
|
|
70
70
|
2. Run our test suite
|
71
71
|
|
72
|
-
`bundle exec
|
73
|
-
|
72
|
+
`bundle exec rspec`
|
73
|
+
|
74
|
+
3. Run our code style checks
|
75
|
+
|
76
|
+
`bundle exec rubocop`
|
77
|
+
|
74
78
|
## Performance
|
75
79
|
|
76
80
|
Using contracts.ruby results in very little slowdown. Check out [this blog post](http://adit.io/posts/2013-03-04-How-I-Made-My-Ruby-Project-10x-Faster.html#seconds-6) for more info.
|
@@ -441,7 +441,7 @@ module Contracts
|
|
441
441
|
end
|
442
442
|
|
443
443
|
# Use this for specifying contracts for class arguments
|
444
|
-
# Example: <tt>
|
444
|
+
# Example: <tt>DescendantOf[ e: Range, f: Optional[Num] ]</tt>
|
445
445
|
class DescendantOf < CallableClass
|
446
446
|
def initialize(parent_class)
|
447
447
|
@parent_class = parent_class
|
data/lib/contracts/call_with.rb
CHANGED
@@ -26,7 +26,9 @@ module Contracts
|
|
26
26
|
:return_value => false)
|
27
27
|
end
|
28
28
|
|
29
|
-
if contract.is_a?(Contracts::Func)
|
29
|
+
if contract.is_a?(Contracts::Func) && blk && !nil_block_appended
|
30
|
+
blk = Contract.new(klass, arg, *contract.contracts)
|
31
|
+
elsif contract.is_a?(Contracts::Func)
|
30
32
|
args[i] = Contract.new(klass, arg, *contract.contracts)
|
31
33
|
end
|
32
34
|
end
|
@@ -73,7 +75,8 @@ module Contracts
|
|
73
75
|
method.call(*args, &blk)
|
74
76
|
else
|
75
77
|
# original method name referrence
|
76
|
-
|
78
|
+
added_block = blk ? lambda { |*params| blk.call(*params) } : nil
|
79
|
+
method.send_to(this, *args, &added_block)
|
77
80
|
end
|
78
81
|
|
79
82
|
unless @ret_validator[result]
|
data/lib/contracts/decorators.rb
CHANGED
data/lib/contracts/version.rb
CHANGED
@@ -3,296 +3,304 @@ RSpec.describe "Contracts:" do
|
|
3
3
|
@o = GenericExample.new
|
4
4
|
end
|
5
5
|
|
6
|
+
def fails(&some)
|
7
|
+
expect { some.call }.to raise_error(ContractError)
|
8
|
+
end
|
9
|
+
|
10
|
+
def passes(&some)
|
11
|
+
expect { some.call }.to_not raise_error
|
12
|
+
end
|
13
|
+
|
6
14
|
describe "DescendantOf:" do
|
7
15
|
it "should pass for Array" do
|
8
|
-
|
16
|
+
passes { @o.enumerable_descendant_test(Array) }
|
9
17
|
end
|
10
18
|
|
11
19
|
it "should pass for a hash" do
|
12
|
-
|
20
|
+
passes { @o.enumerable_descendant_test(Hash) }
|
13
21
|
end
|
14
22
|
|
15
23
|
it "should fail for a number class" do
|
16
|
-
|
24
|
+
fails { @o.enumerable_descendant_test(Integer) }
|
17
25
|
end
|
18
26
|
|
19
27
|
it "should fail for a non-class" do
|
20
|
-
|
28
|
+
fails { @o.enumerable_descendant_test(1) }
|
21
29
|
end
|
22
30
|
end
|
23
31
|
|
24
32
|
describe "Num:" do
|
25
33
|
it "should pass for Fixnums" do
|
26
|
-
|
34
|
+
passes { @o.double(2) }
|
27
35
|
end
|
28
36
|
|
29
37
|
it "should pass for Floats" do
|
30
|
-
|
38
|
+
passes { @o.double(2.2) }
|
31
39
|
end
|
32
40
|
|
33
41
|
it "should fail for nil and other data types" do
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
42
|
+
fails { @o.double(nil) }
|
43
|
+
fails { @o.double(:x) }
|
44
|
+
fails { @o.double("x") }
|
45
|
+
fails { @o.double(/x/) }
|
38
46
|
end
|
39
47
|
end
|
40
48
|
|
41
49
|
describe "Pos:" do
|
42
50
|
it "should pass for positive numbers" do
|
43
|
-
|
44
|
-
|
51
|
+
passes { @o.pos_test(1) }
|
52
|
+
passes { @o.pos_test(1.6) }
|
45
53
|
end
|
46
54
|
|
47
55
|
it "should fail for 0" do
|
48
|
-
|
56
|
+
fails { @o.pos_test(0) }
|
49
57
|
end
|
50
58
|
|
51
59
|
it "should fail for negative numbers" do
|
52
|
-
|
53
|
-
|
60
|
+
fails { @o.pos_test(-1) }
|
61
|
+
fails { @o.pos_test(-1.6) }
|
54
62
|
end
|
55
63
|
|
56
64
|
it "should fail for nil and other data types" do
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
65
|
+
fails { @o.pos_test(nil) }
|
66
|
+
fails { @o.pos_test(:x) }
|
67
|
+
fails { @o.pos_test("x") }
|
68
|
+
fails { @o.pos_test(/x/) }
|
61
69
|
end
|
62
70
|
end
|
63
71
|
|
64
72
|
describe "Neg:" do
|
65
73
|
it "should pass for negative numbers" do
|
66
|
-
|
67
|
-
|
74
|
+
passes { @o.neg_test(-1) }
|
75
|
+
passes { @o.neg_test(-1.6) }
|
68
76
|
end
|
69
77
|
|
70
78
|
it "should fail for 0" do
|
71
|
-
|
79
|
+
fails { @o.neg_test(0) }
|
72
80
|
end
|
73
81
|
|
74
82
|
it "should fail for positive numbers" do
|
75
|
-
|
76
|
-
|
83
|
+
fails { @o.neg_test(1) }
|
84
|
+
fails { @o.neg_test(1.6) }
|
77
85
|
end
|
78
86
|
|
79
87
|
it "should fail for nil and other data types" do
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
88
|
+
fails { @o.neg_test(nil) }
|
89
|
+
fails { @o.neg_test(:x) }
|
90
|
+
fails { @o.neg_test("x") }
|
91
|
+
fails { @o.neg_test(/x/) }
|
84
92
|
end
|
85
93
|
end
|
86
94
|
|
87
95
|
describe "Nat:" do
|
88
96
|
it "should pass for 0" do
|
89
|
-
|
97
|
+
passes { @o.nat_test(0) }
|
90
98
|
end
|
91
99
|
|
92
100
|
it "should pass for positive whole numbers" do
|
93
|
-
|
101
|
+
passes { @o.nat_test(1) }
|
94
102
|
end
|
95
103
|
|
96
104
|
it "should fail for positive non-whole numbers" do
|
97
|
-
|
105
|
+
fails { @o.nat_test(1.5) }
|
98
106
|
end
|
99
107
|
|
100
108
|
it "should fail for negative numbers" do
|
101
|
-
|
102
|
-
|
109
|
+
fails { @o.nat_test(-1) }
|
110
|
+
fails { @o.nat_test(-1.6) }
|
103
111
|
end
|
104
112
|
|
105
113
|
it "should fail for nil and other data types" do
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
114
|
+
fails { @o.nat_test(nil) }
|
115
|
+
fails { @o.nat_test(:x) }
|
116
|
+
fails { @o.nat_test("x") }
|
117
|
+
fails { @o.nat_test(/x/) }
|
110
118
|
end
|
111
119
|
end
|
112
120
|
|
113
121
|
describe "Any:" do
|
114
122
|
it "should pass for numbers" do
|
115
|
-
|
123
|
+
passes { @o.show(1) }
|
116
124
|
end
|
117
125
|
it "should pass for strings" do
|
118
|
-
|
126
|
+
passes { @o.show("bad") }
|
119
127
|
end
|
120
128
|
it "should pass for procs" do
|
121
|
-
|
129
|
+
passes { @o.show(lambda {}) }
|
122
130
|
end
|
123
131
|
it "should pass for nil" do
|
124
|
-
|
132
|
+
passes { @o.show(nil) }
|
125
133
|
end
|
126
134
|
end
|
127
135
|
|
128
136
|
describe "None:" do
|
129
137
|
it "should fail for numbers" do
|
130
|
-
|
138
|
+
fails { @o.fail_all(1) }
|
131
139
|
end
|
132
140
|
it "should fail for strings" do
|
133
|
-
|
141
|
+
fails { @o.fail_all("bad") }
|
134
142
|
end
|
135
143
|
it "should fail for procs" do
|
136
|
-
|
144
|
+
fails { @o.fail_all(lambda {}) }
|
137
145
|
end
|
138
146
|
it "should fail for nil" do
|
139
|
-
|
147
|
+
fails { @o.fail_all(nil) }
|
140
148
|
end
|
141
149
|
end
|
142
150
|
|
143
151
|
describe "Or:" do
|
144
152
|
it "should pass for nums" do
|
145
|
-
|
153
|
+
passes { @o.num_or_string(1) }
|
146
154
|
end
|
147
155
|
|
148
156
|
it "should pass for strings" do
|
149
|
-
|
157
|
+
passes { @o.num_or_string("bad") }
|
150
158
|
end
|
151
159
|
|
152
160
|
it "should fail for nil" do
|
153
|
-
|
161
|
+
fails { @o.num_or_string(nil) }
|
154
162
|
end
|
155
163
|
end
|
156
164
|
|
157
165
|
describe "Xor:" do
|
158
166
|
it "should pass for an object with a method :good" do
|
159
|
-
|
167
|
+
passes { @o.xor_test(A.new) }
|
160
168
|
end
|
161
169
|
|
162
170
|
it "should pass for an object with a method :bad" do
|
163
|
-
|
171
|
+
passes { @o.xor_test(B.new) }
|
164
172
|
end
|
165
173
|
|
166
174
|
it "should fail for an object with neither method" do
|
167
|
-
|
175
|
+
fails { @o.xor_test(1) }
|
168
176
|
end
|
169
177
|
|
170
178
|
it "should fail for an object with both methods :good and :bad" do
|
171
|
-
|
179
|
+
fails { @o.xor_test(F.new) }
|
172
180
|
end
|
173
181
|
end
|
174
182
|
|
175
183
|
describe "And:" do
|
176
184
|
it "should pass for an object of class A that has a method :good" do
|
177
|
-
|
185
|
+
passes { @o.and_test(A.new) }
|
178
186
|
end
|
179
187
|
|
180
188
|
it "should fail for an object that has a method :good but isn't of class A" do
|
181
|
-
|
189
|
+
fails { @o.and_test(F.new) }
|
182
190
|
end
|
183
191
|
end
|
184
192
|
|
185
193
|
describe "Enum:" do
|
186
194
|
it "should pass for an object that is included" do
|
187
|
-
|
195
|
+
passes { @o.enum_test(:a) }
|
188
196
|
end
|
189
197
|
|
190
198
|
it "should fail for an object that is not included" do
|
191
|
-
|
199
|
+
fails { @o.enum_test(:z) }
|
192
200
|
end
|
193
201
|
end
|
194
202
|
|
195
203
|
describe "RespondTo:" do
|
196
204
|
it "should pass for an object that responds to :good" do
|
197
|
-
|
205
|
+
passes { @o.responds_test(A.new) }
|
198
206
|
end
|
199
207
|
|
200
208
|
it "should fail for an object that doesn't respond to :good" do
|
201
|
-
|
209
|
+
fails { @o.responds_test(B.new) }
|
202
210
|
end
|
203
211
|
end
|
204
212
|
|
205
213
|
describe "Send:" do
|
206
214
|
it "should pass for an object that returns true for method :good" do
|
207
|
-
|
215
|
+
passes { @o.send_test(A.new) }
|
208
216
|
end
|
209
217
|
|
210
218
|
it "should fail for an object that returns false for method :good" do
|
211
|
-
|
219
|
+
fails { @o.send_test(F.new) }
|
212
220
|
end
|
213
221
|
end
|
214
222
|
|
215
223
|
describe "Exactly:" do
|
216
224
|
it "should pass for an object that is exactly a Parent" do
|
217
|
-
|
225
|
+
passes { @o.exactly_test(Parent.new) }
|
218
226
|
end
|
219
227
|
|
220
228
|
it "should fail for an object that inherits from Parent" do
|
221
|
-
|
229
|
+
fails { @o.exactly_test(Child.new) }
|
222
230
|
end
|
223
231
|
|
224
232
|
it "should fail for an object that is not related to Parent at all" do
|
225
|
-
|
233
|
+
fails { @o.exactly_test(A.new) }
|
226
234
|
end
|
227
235
|
end
|
228
236
|
|
229
237
|
describe "Eq:" do
|
230
238
|
it "should pass for a class" do
|
231
|
-
|
239
|
+
passes { @o.eq_class_test(Foo) }
|
232
240
|
end
|
233
241
|
|
234
242
|
it "should pass for a module" do
|
235
|
-
|
243
|
+
passes { @o.eq_module_test(Bar) }
|
236
244
|
end
|
237
245
|
|
238
246
|
it "should pass for other values" do
|
239
|
-
|
247
|
+
passes { @o.eq_value_test(Baz) }
|
240
248
|
end
|
241
249
|
|
242
250
|
it "should fail when not equal" do
|
243
|
-
|
251
|
+
fails { @o.eq_class_test(Bar) }
|
244
252
|
end
|
245
253
|
|
246
254
|
it "should fail when given instance of class" do
|
247
|
-
|
255
|
+
fails { @o.eq_class_test(Foo.new) }
|
248
256
|
end
|
249
257
|
end
|
250
258
|
|
251
259
|
describe "Not:" do
|
252
260
|
it "should pass for an argument that isn't nil" do
|
253
|
-
|
261
|
+
passes { @o.not_nil(1) }
|
254
262
|
end
|
255
263
|
|
256
264
|
it "should fail for nil" do
|
257
|
-
|
265
|
+
fails { @o.not_nil(nil) }
|
258
266
|
end
|
259
267
|
end
|
260
268
|
|
261
269
|
describe "ArrayOf:" do
|
262
270
|
it "should pass for an array of nums" do
|
263
|
-
|
271
|
+
passes { @o.product([1, 2, 3]) }
|
264
272
|
end
|
265
273
|
|
266
274
|
it "should fail for an array with one non-num" do
|
267
|
-
|
275
|
+
fails { @o.product([1, 2, 3, "bad"]) }
|
268
276
|
end
|
269
277
|
|
270
278
|
it "should fail for a non-array" do
|
271
|
-
|
279
|
+
fails { @o.product(1) }
|
272
280
|
end
|
273
281
|
end
|
274
282
|
|
275
283
|
describe "RangeOf:" do
|
276
284
|
require "date"
|
277
285
|
it "should pass for a range of nums" do
|
278
|
-
|
286
|
+
passes { @o.first_in_range_num(3..10) }
|
279
287
|
end
|
280
288
|
|
281
289
|
it "should pass for a range of dates" do
|
282
290
|
d1 = Date.today
|
283
291
|
d2 = d1 + 18
|
284
|
-
|
292
|
+
passes { @o.first_in_range_date(d1..d2) }
|
285
293
|
end
|
286
294
|
|
287
295
|
it "should fail for a non-range" do
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
296
|
+
fails { @o.first_in_range_num("foo") }
|
297
|
+
fails { @o.first_in_range_num(:foo) }
|
298
|
+
fails { @o.first_in_range_num(5) }
|
299
|
+
fails { @o.first_in_range_num(nil) }
|
292
300
|
end
|
293
301
|
|
294
302
|
it "should fail for a range with incorrect data type" do
|
295
|
-
|
303
|
+
fails { @o.first_in_range_num("a".."z") }
|
296
304
|
end
|
297
305
|
|
298
306
|
it "should fail for a badly-defined range" do
|
@@ -302,8 +310,8 @@ RSpec.describe "Contracts:" do
|
|
302
310
|
# This test guards against ranges with inconsistent data types.
|
303
311
|
begin
|
304
312
|
d1 = Date.today
|
305
|
-
|
306
|
-
|
313
|
+
fails { @o.first_in_range_date(d1..10) }
|
314
|
+
fails { @o.first_in_range_num(d1..10) }
|
307
315
|
rescue ArgumentError
|
308
316
|
# If Ruby doesn't like the range, we ignore the test.
|
309
317
|
:nop
|
@@ -313,26 +321,26 @@ RSpec.describe "Contracts:" do
|
|
313
321
|
|
314
322
|
describe "SetOf:" do
|
315
323
|
it "should pass for a set of nums" do
|
316
|
-
|
324
|
+
passes { @o.product_from_set(Set.new([1, 2, 3])) }
|
317
325
|
end
|
318
326
|
|
319
327
|
it "should fail for an array with one non-num" do
|
320
|
-
|
328
|
+
fails { @o.product_from_set(Set.new([1, 2, 3, "bad"])) }
|
321
329
|
end
|
322
330
|
|
323
331
|
it "should fail for a non-array" do
|
324
|
-
|
332
|
+
fails { @o.product_from_set(1) }
|
325
333
|
end
|
326
334
|
end
|
327
335
|
|
328
336
|
describe "Bool:" do
|
329
337
|
it "should pass for an argument that is a boolean" do
|
330
|
-
|
331
|
-
|
338
|
+
passes { @o.bool_test(true) }
|
339
|
+
passes { @o.bool_test(false) }
|
332
340
|
end
|
333
341
|
|
334
342
|
it "should fail for nil" do
|
335
|
-
|
343
|
+
fails { @o.bool_test(nil) }
|
336
344
|
end
|
337
345
|
end
|
338
346
|
|
@@ -346,31 +354,31 @@ RSpec.describe "Contracts:" do
|
|
346
354
|
end
|
347
355
|
|
348
356
|
it "should fail for strings" do
|
349
|
-
|
357
|
+
fails { @o.maybe_double("foo") }
|
350
358
|
end
|
351
359
|
end
|
352
360
|
|
353
361
|
describe "KeywordArgs:" do
|
354
362
|
it "should pass for exact correct input" do
|
355
|
-
|
363
|
+
passes { @o.person_keywordargs(:name => "calvin", :age => 10) }
|
356
364
|
end
|
357
365
|
|
358
366
|
it "should fail if some keys don't have contracts" do
|
359
|
-
|
367
|
+
fails { @o.person_keywordargs(:name => "calvin", :age => 10, :foo => "bar") }
|
360
368
|
end
|
361
369
|
|
362
370
|
it "should fail if a key with a contract on it isn't provided" do
|
363
|
-
|
371
|
+
fails { @o.person_keywordargs(:name => "calvin") }
|
364
372
|
end
|
365
373
|
|
366
374
|
it "should fail for incorrect input" do
|
367
|
-
|
368
|
-
|
369
|
-
|
375
|
+
fails { @o.person_keywordargs(:name => 50, :age => 10) }
|
376
|
+
fails { @o.hash_keywordargs(:hash => nil) }
|
377
|
+
fails { @o.hash_keywordargs(:hash => 1) }
|
370
378
|
end
|
371
379
|
|
372
380
|
it "should pass if a method is overloaded with non-KeywordArgs" do
|
373
|
-
|
381
|
+
passes { @o.person_keywordargs("name", 10) }
|
374
382
|
end
|
375
383
|
end
|
376
384
|
|
@@ -402,10 +410,10 @@ RSpec.describe "Contracts:" do
|
|
402
410
|
end
|
403
411
|
|
404
412
|
context "given an unfulfilled contract" do
|
405
|
-
it {
|
406
|
-
it {
|
407
|
-
it {
|
408
|
-
it {
|
413
|
+
it { fails { @o.gives_max_value(:panda => "1", :bamboo => "2") } }
|
414
|
+
it { fails { @o.gives_max_value(nil) } }
|
415
|
+
it { fails { @o.gives_max_value(1) } }
|
416
|
+
it { fails { @o.pretty_gives_max_value(:panda => "1", :bamboo => "2") } }
|
409
417
|
end
|
410
418
|
|
411
419
|
describe "#to_s" do
|
@@ -422,39 +430,31 @@ RSpec.describe "Contracts:" do
|
|
422
430
|
describe "StrictHash:" do
|
423
431
|
context "when given an exact correct input" do
|
424
432
|
it "does not raise an error" do
|
425
|
-
|
426
|
-
@o.strict_person(:name => "calvin", :age => 10)
|
427
|
-
end.to_not raise_error
|
433
|
+
passes { @o.strict_person(:name => "calvin", :age => 10) }
|
428
434
|
end
|
429
435
|
end
|
430
436
|
|
431
437
|
context "when given an input with correct keys but wrong types" do
|
432
438
|
it "raises an error" do
|
433
|
-
|
434
|
-
@o.strict_person(:name => "calvin", :age => "10")
|
435
|
-
end.to raise_error(ContractError)
|
439
|
+
fails { @o.strict_person(:name => "calvin", :age => "10") }
|
436
440
|
end
|
437
441
|
end
|
438
442
|
|
439
443
|
context "when given an input with missing keys" do
|
440
444
|
it "raises an error" do
|
441
|
-
|
442
|
-
@o.strict_person(:name => "calvin")
|
443
|
-
end.to raise_error(ContractError)
|
445
|
+
fails { @o.strict_person(:name => "calvin") }
|
444
446
|
end
|
445
447
|
end
|
446
448
|
|
447
449
|
context "when given an input with extra keys" do
|
448
450
|
it "raises an error" do
|
449
|
-
|
450
|
-
@o.strict_person(:name => "calvin", :age => "10", :soft => true)
|
451
|
-
end.to raise_error(ContractError)
|
451
|
+
fails { @o.strict_person(:name => "calvin", :age => "10", :soft => true) }
|
452
452
|
end
|
453
453
|
end
|
454
454
|
|
455
455
|
context "when given not a hash" do
|
456
456
|
it "raises an error" do
|
457
|
-
|
457
|
+
fails { @o.strict_person(1337) }
|
458
458
|
end
|
459
459
|
end
|
460
460
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
RSpec.describe "Contracts:" do
|
2
|
+
describe "method called with blocks" do
|
3
|
+
module FuncTest
|
4
|
+
include Contracts::Core
|
5
|
+
include Contracts::Builtin
|
6
|
+
|
7
|
+
Contract Func[Num=>Num] => nil
|
8
|
+
def foo(&blk)
|
9
|
+
_ = blk.call(2)
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
Contract Num, Func[Num=>Num] => nil
|
14
|
+
def foo2(a, &blk)
|
15
|
+
_ = blk.call(2)
|
16
|
+
nil
|
17
|
+
end
|
18
|
+
|
19
|
+
Contract Func[Num=>Num] => nil
|
20
|
+
def bar(blk)
|
21
|
+
_ = blk.call(2)
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
Contract Num, Func[Num=>Num] => nil
|
26
|
+
def bar2(a, blk)
|
27
|
+
_ = blk.call(2)
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def obj
|
33
|
+
Object.new.tap do |o|
|
34
|
+
o.extend(FuncTest)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should enforce return value inside block with no other parameter" do
|
39
|
+
expect { obj.foo(&:to_s) }.to raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should enforce return value inside block with other parameter" do
|
43
|
+
expect { obj.foo2(2) { |x| x.to_s } }.to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should enforce return value inside lambda with no other parameter" do
|
47
|
+
expect { obj.bar lambda { |x| x.to_s } }.to raise_error
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should enforce return value inside lambda with other parameter" do
|
51
|
+
expect { obj.bar2(2, lambda { |x| x.to_s }) }.to raise_error
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: contracts
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aditya Bhargava
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This library provides contracts for Ruby. Contracts let you clearly express
|
14
14
|
how your code behaves, and free you from writing tons of boilerplate, defensive
|
@@ -92,6 +92,7 @@ files:
|
|
92
92
|
- spec/contracts_spec.rb
|
93
93
|
- spec/fixtures/fixtures.rb
|
94
94
|
- spec/invariants_spec.rb
|
95
|
+
- spec/methods_spec.rb
|
95
96
|
- spec/module_spec.rb
|
96
97
|
- spec/override_validators_spec.rb
|
97
98
|
- spec/ruby_version_specific/contracts_spec_1.9.rb
|
@@ -121,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
121
122
|
version: '0'
|
122
123
|
requirements: []
|
123
124
|
rubyforge_project:
|
124
|
-
rubygems_version: 2.
|
125
|
+
rubygems_version: 2.5.1
|
125
126
|
signing_key:
|
126
127
|
specification_version: 4
|
127
128
|
summary: Contracts for Ruby.
|