prop_check 0.10.1 → 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5b0170f4c948f3ffb903842c33204d4a9d5f74dd4f1d29313a60dec638670623
4
- data.tar.gz: 447b87275c1e379502694d96591a871a527535e290daf3cc255476965752e1d2
3
+ metadata.gz: '099a3bafe1fae426f476e3add7fb93ab333506670c72c35bb78e5e505b9f0764'
4
+ data.tar.gz: d1c433ef97043f38c84a5bf8768fb46aa5fcc97f00518da831fbebc36142d2e5
5
5
  SHA512:
6
- metadata.gz: 533aae467c23eb1ecc974e842e735b49f3cfdef7ae51090ef11ad86e95f90f81660a6617565df4aab6470d2c2ae9ff5978826b48ed2686a727ac53b7c065a7b1
7
- data.tar.gz: 4d6cc50716b03427a0aba7c4617a2970cc791c524d6aa427d22a63870853118cd72c6eca469fcd1e42ce2288f42a63b7fc577b248aea47a2892f324d94377db8
6
+ metadata.gz: 782411f48a77c4bc2213d6ecaecd70d7d7c3609c13bab2125ce853dedd7d3029fd8801ac882154d8c924cea212698740d8e330f8e2b90f460a5a87484413e560
7
+ data.tar.gz: dd18135801b66e2f073e82066506f8bb26cf031a4bd8d2fc208864acd7ef3a7ec564f8364628d34e4ab40429a5444a1dbc41f329bb4c7d3a608011407bb0a923
@@ -1 +1 @@
1
- ruby 2.6.5
1
+ ruby 2.7.1
@@ -10,6 +10,8 @@ module PropCheck
10
10
  class Generator
11
11
  @@default_size = 10
12
12
  @@default_rng = Random.new
13
+ @@max_consecutive_attempts = 100
14
+ @@default_kwargs = {size: @@default_size, rng: @@default_rng, max_consecutive_attempts: @@max_consecutive_attempts}
13
15
 
14
16
  ##
15
17
  # Being a special kind of Proc, a Generator wraps a block.
@@ -20,26 +22,38 @@ module PropCheck
20
22
  ##
21
23
  # Given a `size` (integer) and a random number generator state `rng`,
22
24
  # generate a LazyTree.
23
- def generate(size = @@default_size, rng = @@default_rng)
24
- @block.call(size, rng)
25
+ def generate(**kwargs)
26
+ kwargs = @@default_kwargs.merge(kwargs)
27
+ max_consecutive_attempts = kwargs[:max_consecutive_attempts]
28
+
29
+ (0..max_consecutive_attempts).each do
30
+ res = @block.call(**kwargs)
31
+ return res unless res.root == :"_PropCheck.filter_me"
32
+ end
33
+
34
+ raise Errors::GeneratorExhaustedError, """
35
+ Exhausted #{max_consecutive_attempts} consecutive generation attempts.
36
+
37
+ Probably too few generator results were adhering to a `where` condition.
38
+ """
25
39
  end
26
40
 
27
41
  ##
28
42
  # Generates a value, and only return this value
29
43
  # (drop information for shrinking)
30
44
  #
31
- # >> Generators.integer.call(1000, Random.new(42))
45
+ # >> Generators.integer.call(size: 1000, rng: Random.new(42))
32
46
  # => 126
33
- def call(size = @@default_size, rng = @@default_rng)
34
- generate(size, rng).root
47
+ def call(**kwargs)
48
+ generate(**@@default_kwargs.merge(kwargs)).root
35
49
  end
36
50
 
37
51
  ##
38
52
  # Returns `num_of_samples` values from calling this Generator.
39
53
  # This is mostly useful for debugging if a generator behaves as you intend it to.
40
- def sample(num_of_samples = 10, size: @@default_size, rng: @@default_rng)
54
+ def sample(num_of_samples = 10, **kwargs)
41
55
  num_of_samples.times.map do
42
- call(size, rng)
56
+ call(**@@default_kwargs.merge(kwargs))
43
57
  end
44
58
  end
45
59
 
@@ -49,10 +63,10 @@ module PropCheck
49
63
  #
50
64
  # Keen readers may notice this as the Monadic 'pure'/'return' implementation for Generators.
51
65
  #
52
- # >> Generators.integer.bind { |a| Generators.integer.bind { |b| Generator.wrap([a , b]) } }.call(100, Random.new(42))
66
+ # >> Generators.integer.bind { |a| Generators.integer.bind { |b| Generator.wrap([a , b]) } }.call(size: 100, rng: Random.new(42))
53
67
  # => [2, 79]
54
68
  def self.wrap(val)
55
- Generator.new { |_size, _rng| LazyTree.wrap(val) }
69
+ Generator.new { LazyTree.wrap(val) }
56
70
  end
57
71
 
58
72
  ##
@@ -61,7 +75,7 @@ module PropCheck
61
75
  #
62
76
  # Keen readers may notice this as the Monadic 'bind' (sometimes known as '>>=') implementation for Generators.
63
77
  #
64
- # >> Generators.integer.bind { |a| Generators.integer.bind { |b| Generator.wrap([a , b]) } }.call(100, Random.new(42))
78
+ # >> Generators.integer.bind { |a| Generators.integer.bind { |b| Generator.wrap([a , b]) } }.call(size: 100, rng: Random.new(42))
65
79
  # => [2, 79]
66
80
  def bind(&generator_proc)
67
81
  # Generator.new do |size, rng|
@@ -71,11 +85,11 @@ module PropCheck
71
85
  # inner_generator.generate(size, rng)
72
86
  # end.flatten
73
87
  # end
74
- Generator.new do |size, rng|
75
- outer_result = self.generate(size, rng)
88
+ Generator.new do |**kwargs|
89
+ outer_result = self.generate(**kwargs)
76
90
  outer_result.bind do |outer_val|
77
91
  inner_generator = generator_proc.call(outer_val)
78
- inner_generator.generate(size, rng)
92
+ inner_generator.generate(**kwargs)
79
93
  end
80
94
  end
81
95
  end
@@ -83,11 +97,11 @@ module PropCheck
83
97
  ##
84
98
  # Creates a new Generator that returns a value by running `proc` on the output of the current Generator.
85
99
  #
86
- # >> Generators.choose(32..128).map(&:chr).call(10, Random.new(42))
100
+ # >> Generators.choose(32..128).map(&:chr).call(size: 10, rng: Random.new(42))
87
101
  # => "S"
88
102
  def map(&proc)
89
- Generator.new do |size, rng|
90
- result = self.generate(size, rng)
103
+ Generator.new do |**kwargs|
104
+ result = self.generate(**kwargs)
91
105
  result.map(&proc)
92
106
  end
93
107
  end
@@ -96,19 +110,13 @@ module PropCheck
96
110
  # Creates a new Generator that only produces a value when the block `condition` returns a truthy value.
97
111
  def where(&condition)
98
112
  self.map do |result|
99
- if condition.call(*result)
113
+ # if condition.call(*result)
114
+ if PropCheck::Helper.call_splatted(result, &condition)
100
115
  result
101
116
  else
102
117
  :"_PropCheck.filter_me"
103
118
  end
104
119
  end
105
- # self.map do |*result|
106
- # if condition.call(*result)
107
- # result
108
- # else
109
- # :'_PropCheck.filter_me'
110
- # end
111
- # end
112
120
  end
113
121
  end
114
122
  end
@@ -10,6 +10,7 @@ module PropCheck
10
10
  # where you want to use them.
11
11
  module Generators
12
12
  extend self
13
+
13
14
  ##
14
15
  # Always returns the same value, regardless of `size` or `rng` (random number generator state)
15
16
  #
@@ -59,7 +60,7 @@ module PropCheck
59
60
  # >> r = Random.new(42); Generators.choose(0..5).sample(size: 20000, rng: r)
60
61
  # => [3, 4, 2, 4, 4, 1, 2, 2, 2, 4]
61
62
  def choose(range)
62
- Generator.new do |_size, rng|
63
+ Generator.new do |rng:, **|
63
64
  val = rng.rand(range)
64
65
  LazyTree.new(val, integer_shrink(val))
65
66
  end
@@ -73,14 +74,14 @@ module PropCheck
73
74
  #
74
75
  # Shrinks to integers closer to zero.
75
76
  #
76
- # >> Generators.integer.call(2, Random.new(42))
77
+ # >> Generators.integer.call(size: 2, rng: Random.new(42))
77
78
  # => 1
78
- # >> Generators.integer.call(10000, Random.new(42))
79
+ # >> Generators.integer.call(size: 10000, rng: Random.new(42))
79
80
  # => 5795
80
81
  # >> r = Random.new(42); Generators.integer.sample(size: 20000, rng: r)
81
82
  # => [-4205, -19140, 18158, -8716, -13735, -3150, 17194, 1962, -3977, -18315]
82
83
  def integer
83
- Generator.new do |size, rng|
84
+ Generator.new do |size:, rng:, **|
84
85
  val = rng.rand(-size..size)
85
86
  LazyTree.new(val, integer_shrink(val))
86
87
  end
@@ -193,12 +194,12 @@ module PropCheck
193
194
  #
194
195
  # Shrinks element generators, one at a time (trying last one first).
195
196
  #
196
- # >> Generators.tuple(Generators.integer, Generators.real_float).call(10, Random.new(42))
197
+ # >> Generators.tuple(Generators.integer, Generators.real_float).call(size: 10, rng: Random.new(42))
197
198
  # => [-4, 13.0]
198
199
  def tuple(*generators)
199
- Generator.new do |size, rng|
200
+ Generator.new do |**kwargs|
200
201
  LazyTree.zip(generators.map do |generator|
201
- generator.generate(size, rng)
202
+ generator.generate(**kwargs)
202
203
  end)
203
204
  end
204
205
  end
@@ -210,7 +211,7 @@ module PropCheck
210
211
  #
211
212
  # Shrinks element generators.
212
213
  #
213
- # >> Generators.fixed_hash(a: Generators.integer(), b: Generators.real_float(), c: Generators.integer()).call(10, Random.new(42))
214
+ # >> Generators.fixed_hash(a: Generators.integer(), b: Generators.real_float(), c: Generators.integer()).call(size: 10, rng: Random.new(42))
214
215
  # => {:a=>-4, :b=>13.0, :c=>-3}
215
216
  def fixed_hash(hash)
216
217
  keypair_generators =
@@ -227,17 +228,42 @@ module PropCheck
227
228
  # is generated by `element_generator`.
228
229
  #
229
230
  # Shrinks to shorter arrays (with shrunken elements).
231
+ # Accepted keyword arguments:
232
+ #
233
+ # `empty:` When false, behaves the same as `min: 1`
234
+ # `min:` Ensures at least this many elements are generated. (default: 0)
235
+ # `max:` Ensures at most this many elements are generated. When nil, an arbitrary count is used instead. (default: nil)
236
+ #
230
237
  #
238
+ # >> Generators.array(Generators.positive_integer).sample(5, size: 1, rng: Random.new(42))
239
+ # => [[2], [2], [2], [1], [2]]
231
240
  # >> Generators.array(Generators.positive_integer).sample(5, size: 10, rng: Random.new(42))
232
241
  # => [[10, 5, 1, 4], [5, 9, 1, 1, 11, 8, 4, 9, 11, 10], [6], [11, 11, 2, 2, 7, 2, 6, 5, 5], [2, 10, 9, 7, 9, 5, 11, 3]]
233
- def array(element_generator)
234
- nonnegative_integer.bind do |generator|
235
- generators = (0...generator).map do
242
+ #
243
+ # >> Generators.array(Generators.positive_integer, empty: true).sample(5, size: 1, rng: Random.new(1))
244
+ # => [[], [2], [], [], [2]]
245
+ # >> Generators.array(Generators.positive_integer, empty: false).sample(5, size: 1, rng: Random.new(1))
246
+ # => [[2], [1], [2], [1], [1]]
247
+
248
+
249
+ def array(element_generator, min: 0, max: nil, empty: true)
250
+ min = 1 if min.zero? && !empty
251
+
252
+ res = proc do |count|
253
+ count = min + 1 if count < min
254
+ count += 1 if count == min && min != 0
255
+ generators = (min...count).map do
236
256
  element_generator.clone
237
257
  end
238
258
 
239
259
  tuple(*generators)
240
260
  end
261
+
262
+ if max.nil?
263
+ nonnegative_integer.bind(&res)
264
+ else
265
+ proc.call(max)
266
+ end
241
267
  end
242
268
 
243
269
  ##
@@ -249,11 +275,22 @@ module PropCheck
249
275
  #
250
276
  # >> Generators.hash(Generators.printable_ascii_string, Generators.positive_integer).sample(5, size: 3, rng: Random.new(42))
251
277
  # => [{""=>2, "g\\4"=>4, "rv"=>2}, {"7"=>2}, {"!"=>1, "E!"=>1}, {"kY5"=>2}, {}]
252
- def hash(key_generator, value_generator)
253
- array(tuple(key_generator, value_generator))
254
- .map(&:to_h)
278
+ def hash(*args, **kwargs)
279
+ if args.length == 2
280
+ hash_of(*args, **kwargs)
281
+ else
282
+ super
283
+ end
255
284
  end
256
285
 
286
+ ##
287
+ #
288
+ # Alias for `#hash` that does not conflict with a possibly overriden `Object#hash`.
289
+ #
290
+ def hash_of(key_generator, value_generator, **kwargs)
291
+ array(tuple(key_generator, value_generator), **kwargs)
292
+ .map(&:to_h)
293
+ end
257
294
 
258
295
  @alphanumeric_chars = [('a'..'z'), ('A'..'Z'), ('0'..'9')].flat_map(&:to_a).freeze
259
296
  ##
@@ -276,8 +313,8 @@ module PropCheck
276
313
  #
277
314
  # >> Generators.alphanumeric_string.sample(5, size: 10, rng: Random.new(42))
278
315
  # => ["ZCoQ", "8uM", "wkkx0JNx", "v0bxRDLb", "Gl5v8RyWA6"]
279
- def alphanumeric_string
280
- array(alphanumeric_char).map(&:join)
316
+ def alphanumeric_string(**kwargs)
317
+ array(alphanumeric_char, **kwargs).map(&:join)
281
318
  end
282
319
 
283
320
  @printable_ascii_chars = (' '..'~').to_a.freeze
@@ -302,8 +339,8 @@ module PropCheck
302
339
  #
303
340
  # >> Generators.printable_ascii_string.sample(5, size: 10, rng: Random.new(42))
304
341
  # => ["S|.g", "rvjjw7\"5T!", "=", "!_[4@", "Y"]
305
- def printable_ascii_string
306
- array(printable_ascii_char).map(&:join)
342
+ def printable_ascii_string(**kwargs)
343
+ array(printable_ascii_char, **kwargs).map(&:join)
307
344
  end
308
345
 
309
346
  @ascii_chars = [
@@ -341,8 +378,8 @@ module PropCheck
341
378
  #
342
379
  # >> Generators.ascii_string.sample(5, size: 10, rng: Random.new(42))
343
380
  # => ["S|.g", "drvjjw\b\a7\"", "!w=E!_[4@k", "x", "zZI{[o"]
344
- def ascii_string
345
- array(ascii_char).map(&:join)
381
+ def ascii_string(**kwargs)
382
+ array(ascii_char, **kwargs).map(&:join)
346
383
  end
347
384
 
348
385
  @printable_chars = [
@@ -372,8 +409,8 @@ module PropCheck
372
409
  #
373
410
  # >> Generators.printable_string.sample(5, size: 10, rng: Random.new(42))
374
411
  # => ["", "Ȍ", "𐁂", "Ȕ", ""]
375
- def printable_string
376
- array(printable_char).map(&:join)
412
+ def printable_string(**kwargs)
413
+ array(printable_char, **kwargs).map(&:join)
377
414
  end
378
415
 
379
416
  ##
@@ -398,8 +435,8 @@ module PropCheck
398
435
  #
399
436
  # >> Generators.string.sample(5, size: 10, rng: Random.new(42))
400
437
  # => ["\u{A3DB3}𠍜\u{3F46A}\u{1AEBC}", "􍙦𡡹󴇒\u{DED74}𪱣\u{43E97}ꂂ\u{50695}􏴴\u{C0301}", "\u{4FD9D}", "\u{C14BF}\u{193BB}𭇋󱣼\u{76B58}", "𦐺\u{9FDDB}\u{80ABB}\u{9E3CF}𐂽\u{14AAE}"]
401
- def string
402
- array(char).map(&:join)
438
+ def string(**kwargs)
439
+ array(char, **kwargs).map(&:join)
403
440
  end
404
441
 
405
442
  ##
@@ -31,5 +31,19 @@ module PropCheck
31
31
  def lazy_append(this_enumerator, other_enumerator)
32
32
  [this_enumerator, other_enumerator].lazy.flat_map(&:lazy)
33
33
  end
34
+
35
+ def call_splatted(val, &block)
36
+ case val
37
+ when Hash
38
+ block.call(**val)
39
+ else
40
+ block.call(val)
41
+ end
42
+ # if kwval != {}
43
+ # block.call(**kwval)
44
+ # else
45
+ # block.call(*val)
46
+ # end
47
+ end
34
48
  end
35
49
  end
@@ -7,6 +7,8 @@ module PropCheck
7
7
  class LazyTree
8
8
  require 'prop_check/helper'
9
9
 
10
+ include Enumerable
11
+
10
12
  attr_accessor :root, :children
11
13
  def initialize(root, children = [].lazy)
12
14
  @root = root
@@ -66,25 +68,15 @@ module PropCheck
66
68
  # >> LazyTree.new(1, [LazyTree.new(2, [LazyTree.new(3)]), LazyTree.new(4)]).each.force
67
69
  # => [1, 4, 2, 3]
68
70
  def each(&block)
69
- squish = lambda do |tree, list|
70
- new_children = tree.children.reduce(list) { |acc, elem| squish.call(elem, acc) }
71
- PropCheck::Helper.lazy_append([tree.root], new_children)
72
- end
73
-
74
- squish
75
- .call(self, [])
71
+ self.to_enum(:each) unless block_given?
76
72
 
77
- # base = [root]
78
- # recursive = children.map(&:each)
79
- # res = PropCheck::Helper.lazy_append(base, recursive)
80
-
81
- # return res.each(&block) if block_given?
82
-
83
- # res
73
+ squish([])
74
+ .each(&block)
75
+ end
84
76
 
85
- # res = [[root], children.flat_map(&:each)].lazy.flat_map(&:lazy)
86
- # res = res.map(&block) if block_given?
87
- # res
77
+ protected def squish(arr)
78
+ new_children = self.children.reduce(arr) { |acc, elem| elem.squish(acc) }
79
+ PropCheck::Helper.lazy_append([self.root], new_children)
88
80
  end
89
81
 
90
82
  ##
@@ -35,9 +35,9 @@ module PropCheck
35
35
  # a Property object is returned, which you can call the other instance methods
36
36
  # of this class on before finally passing a block to it using `#check`.
37
37
  # (so `forall(Generators.integer) do |val| ... end` and forall(Generators.integer).check do |val| ... end` are the same)
38
- def self.forall(*bindings, &block)
38
+ def self.forall(*bindings, **kwbindings, &block)
39
39
 
40
- property = new(*bindings)
40
+ property = new(*bindings, **kwbindings)
41
41
 
42
42
  return property.check(&block) if block_given?
43
43
 
@@ -66,8 +66,9 @@ module PropCheck
66
66
  def initialize(*bindings, **kwbindings)
67
67
  raise ArgumentError, 'No bindings specified!' if bindings.empty? && kwbindings.empty?
68
68
 
69
- @bindings = bindings
70
- @kwbindings = kwbindings
69
+ # @bindings = bindings
70
+ # @kwbindings = kwbindings
71
+ @gen = gen_from_bindings(bindings, kwbindings)
71
72
  @condition = proc { true }
72
73
  @config = self.class.configuration
73
74
  @hooks = PropCheck::Hooks.new
@@ -106,14 +107,17 @@ module PropCheck
106
107
  # you might encounter a GeneratorExhaustedError.
107
108
  # Only filter if you have few inputs to reject. Otherwise, improve your generators.
108
109
  def where(&condition)
109
- original_condition = @condition.dup
110
- @condition = proc do |*args|
111
- original_condition.call(*args) && condition.call(*args)
112
- end
110
+ # original_condition = @condition.dup
111
+ # @condition = proc do |val|
112
+ # call_splatted(val, &original_condition) && call_splatted(val, &condition)
113
+ # # original_condition.call(val) && condition.call(val)
114
+ # end
115
+ @gen = @gen.where(&condition)
113
116
 
114
117
  self
115
118
  end
116
119
 
120
+
117
121
  ##
118
122
  # Calls `hook` before each time a check is run with new data.
119
123
  #
@@ -155,21 +159,11 @@ module PropCheck
155
159
  ##
156
160
  # Checks the property (after settings have been altered using the other instance methods in this class.)
157
161
  def check(&block)
158
- gens =
159
- if @kwbindings != {}
160
- kwbinding_generator = PropCheck::Generators.fixed_hash(**@kwbindings)
161
- @bindings + [kwbinding_generator]
162
- else
163
- @bindings
164
- end
165
- binding_generator = PropCheck::Generators.tuple(*gens)
166
- # binding_generator = PropCheck::Generators.fixed_hash(**@kwbindings)
167
-
168
162
  n_runs = 0
169
163
  n_successful = 0
170
164
 
171
165
  # Loop stops at first exception
172
- attempts_enum(binding_generator).each do |generator_result|
166
+ attempts_enum(@gen).each do |generator_result|
173
167
  n_runs += 1
174
168
  check_attempt(generator_result, n_successful, &block)
175
169
  n_successful += 1
@@ -178,6 +172,25 @@ module PropCheck
178
172
  ensure_not_exhausted!(n_runs)
179
173
  end
180
174
 
175
+ private def gen_from_bindings(bindings, kwbindings)
176
+ if bindings == [] && kwbindings != {}
177
+ PropCheck::Generators.fixed_hash(**kwbindings)
178
+ elsif bindings != [] && kwbindings == {}
179
+ if bindings.size == 1
180
+ bindings.first
181
+ else
182
+ PropCheck::Generators.tuple(*bindings)
183
+ end
184
+ else
185
+ raise ArgumentError,
186
+ 'Attempted to use both normal and keyword bindings at the same time.
187
+ This is not supported because of the separation of positional and keyword arguments
188
+ (the old behaviour is deprecated in Ruby 2.7 and will be removed in 3.0)
189
+ c.f. https://www.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/
190
+ '
191
+ end
192
+ end
193
+
181
194
  private def ensure_not_exhausted!(n_runs)
182
195
  return if n_runs >= @config.n_runs
183
196
 
@@ -196,7 +209,7 @@ module PropCheck
196
209
  end
197
210
 
198
211
  private def check_attempt(generator_result, n_successful, &block)
199
- block.call(*generator_result.root)
212
+ PropCheck::Helper.call_splatted(generator_result.root, &block)
200
213
 
201
214
  # immediately stop (without shrinnking) for when the app is asked
202
215
  # to close by outside intervention
@@ -236,9 +249,7 @@ module PropCheck
236
249
  size = 1
237
250
  (0...@config.max_generate_attempts)
238
251
  .lazy
239
- .map { binding_generator.generate(size, rng) }
240
- .reject { |val| val.root.any? { |elem| elem == :"_PropCheck.filter_me" }}
241
- .select { |val| @condition.call(*val.root) }
252
+ .map { binding_generator.generate(size: size, rng: rng, max_consecutive_attempts: @config.max_consecutive_attempts) }
242
253
  .map do |result|
243
254
  size += 1
244
255
 
@@ -1,8 +1,20 @@
1
1
  module PropCheck
2
2
  class Property
3
- Configuration = Struct.new(:verbose, :n_runs, :max_generate_attempts, :max_shrink_steps, keyword_init: true) do
3
+ Configuration = Struct.new(
4
+ :verbose,
5
+ :n_runs,
6
+ :max_generate_attempts,
7
+ :max_shrink_steps,
8
+ :max_consecutive_attempts,
9
+ keyword_init: true) do
4
10
 
5
- def initialize(verbose: false, n_runs: 1_000, max_generate_attempts: 10_000, max_shrink_steps: 10_000)
11
+ def initialize(
12
+ verbose: false,
13
+ n_runs: 1_000,
14
+ max_generate_attempts: 10_000,
15
+ max_shrink_steps: 10_000,
16
+ max_consecutive_attempts: 30
17
+ )
6
18
  super
7
19
  end
8
20
 
@@ -1,3 +1,4 @@
1
+ require 'prop_check/helper'
1
2
  class PropCheck::Property::Shrinker
2
3
  def initialize(bindings_tree, io, hooks, config)
3
4
  @problem_child = bindings_tree
@@ -62,7 +63,7 @@ class PropCheck::Property::Shrinker
62
63
 
63
64
  private def safe_call_block(sibling, &block)
64
65
  begin
65
- block.call(*sibling.root)
66
+ PropCheck::Helper.call_splatted(sibling.root, &block)
66
67
  # It is correct that we want to rescue _all_ Exceptions
67
68
  # not only 'StandardError's
68
69
  rescue Exception => e
@@ -1,3 +1,3 @@
1
1
  module PropCheck
2
- VERSION = '0.10.1'
2
+ VERSION = '0.11.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prop_check
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.1
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Qqwy/Wiebe-Marten Wijnja
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
83
  - !ruby/object:Gem::Version
84
84
  version: '0'
85
85
  requirements: []
86
- rubygems_version: 3.0.3
86
+ rubygems_version: 3.1.2
87
87
  signing_key:
88
88
  specification_version: 4
89
89
  summary: PropCheck allows you to do property-based testing, including shrinking.