minitest-proptest 0.2.1 → 0.3.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/lib/minitest/proptest/gen/value_generator.rb +5 -1
- data/lib/minitest/proptest/gen.rb +17 -28
- data/lib/minitest/proptest/property.rb +56 -53
- data/lib/minitest/proptest/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 236dabad0376379b518d9c29fc12f1bca0a17343c9dc85c6ff19ef94419698e8
|
4
|
+
data.tar.gz: dbe3075e50971bac885e3fcc6d3c607c9edb4a9e5bac4cc9dc1863a874ac2d5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70f655e9358ce5e198b5489e94a8cdb32d0a58b0d88393482f7faf8e911ab81a50bdc5514add06cb168f13a2c687a825725e00e59c0497937bd076ba8279bc91
|
7
|
+
data.tar.gz: 9dde2177e0f6a9458f1226abd43c5bd1b7048c3c69c6f746043fb02a4c5e9de1f5e8082bad699001f238b478528da350a63ede6d84b6058f011f9d6960217c88
|
@@ -98,7 +98,11 @@ module Minitest
|
|
98
98
|
def shrink_candidates
|
99
99
|
fs = @type_parameters.map { |x| x.method(:shrink_function) }
|
100
100
|
os = score
|
101
|
-
|
101
|
+
# Ensure that the end of the shrink attempt will contain the original
|
102
|
+
# value. This is necessary to guarantee that the shrink process
|
103
|
+
# produces at least one failure for the purpose of capturing variable
|
104
|
+
# assignment.
|
105
|
+
candidates = shrink_function(*fs, value) + [value]
|
102
106
|
candidates
|
103
107
|
.map { |c| [force(c).score, c] }
|
104
108
|
.reject { |(s, _)| s > os }
|
@@ -287,47 +287,27 @@ module Minitest
|
|
287
287
|
|
288
288
|
generator_for(Int8) do
|
289
289
|
r = sized(0xff)
|
290
|
-
(r & 0x80).zero? ? r : -((
|
291
|
-
end.with_shrink_function
|
292
|
-
j = (i & 0x80).zero? ? i : -(((i & 0x7f) - 1) ^ 0x7f)
|
293
|
-
integral_shrink.call(j)
|
294
|
-
end
|
290
|
+
(r & 0x80).zero? ? r : -((r ^ 0x7f) - 0x7f)
|
291
|
+
end.with_shrink_function(&integral_shrink)
|
295
292
|
|
296
293
|
generator_for(Int16) do
|
297
294
|
r = sized(0xffff)
|
298
|
-
(r & 0x8000).zero? ? r : -((
|
299
|
-
end.with_shrink_function
|
300
|
-
j = (i & 0x8000).zero? ? i : -(((i & 0x7fff) - 1) ^ 0x7fff)
|
301
|
-
integral_shrink.call(j)
|
302
|
-
end
|
295
|
+
(r & 0x8000).zero? ? r : -((r ^ 0x7fff) - 0x7fff)
|
296
|
+
end.with_shrink_function(&integral_shrink)
|
303
297
|
|
304
298
|
generator_for(Int32) do
|
305
299
|
r = sized(0xffffffff)
|
306
|
-
(r & 0x80000000).zero? ? r : -((
|
307
|
-
end.with_shrink_function
|
308
|
-
j = if (i & 0x80000000).zero?
|
309
|
-
i
|
310
|
-
else
|
311
|
-
-(((i & 0x7fffffff) - 1) ^ 0x7fffffff)
|
312
|
-
end
|
313
|
-
integral_shrink.call(j)
|
314
|
-
end
|
300
|
+
(r & 0x80000000).zero? ? r : -((r ^ 0x7fffffff) - 0x7fffffff)
|
301
|
+
end.with_shrink_function(&integral_shrink)
|
315
302
|
|
316
303
|
generator_for(Int64) do
|
317
304
|
r = sized(0xffffffffffffffff)
|
318
305
|
if (r & 0x8000000000000000).zero?
|
319
306
|
r
|
320
307
|
else
|
321
|
-
-((
|
308
|
+
-((r ^ 0x7fffffffffffffff) - 0x7fffffffffffffff)
|
322
309
|
end
|
323
|
-
end.with_shrink_function
|
324
|
-
j = if (i & 0x8000000000000000).zero?
|
325
|
-
i
|
326
|
-
else
|
327
|
-
-(((i & 0x7fffffffffffffff) - 1) ^ 0x7fffffffffffffff)
|
328
|
-
end
|
329
|
-
integral_shrink.call(j)
|
330
|
-
end
|
310
|
+
end.with_shrink_function(&integral_shrink)
|
331
311
|
|
332
312
|
generator_for(UInt8) do
|
333
313
|
sized(0xff)
|
@@ -471,6 +451,15 @@ module Minitest
|
|
471
451
|
end.with_score_function do |_|
|
472
452
|
1
|
473
453
|
end
|
454
|
+
|
455
|
+
generator_for(Time) do
|
456
|
+
r = sized(0xffffffff)
|
457
|
+
Time.at((r & 0x80000000).zero? ? r : -((r ^ 0x7fffffff) - 0x7fffffff))
|
458
|
+
end.with_shrink_function do |t|
|
459
|
+
integral_shrink.call(t.to_i).map(&Time.method(:at))
|
460
|
+
end.with_score_function do |t|
|
461
|
+
t.to_i.abs
|
462
|
+
end
|
474
463
|
end
|
475
464
|
end
|
476
465
|
end
|
@@ -7,6 +7,8 @@ module Minitest
|
|
7
7
|
require 'minitest/assertions'
|
8
8
|
include Minitest::Assertions
|
9
9
|
|
10
|
+
class InvalidProperty < StandardError; end
|
11
|
+
|
10
12
|
attr_reader :calls, :result, :status, :trivial
|
11
13
|
|
12
14
|
attr_accessor :assertions
|
@@ -47,7 +49,6 @@ module Minitest
|
|
47
49
|
@max_shrinks = max_shrinks
|
48
50
|
@status = Status.unknown
|
49
51
|
@trivial = false
|
50
|
-
@valid_test_case = true
|
51
52
|
@result = nil
|
52
53
|
@exception = nil
|
53
54
|
@calls = 0
|
@@ -126,40 +127,35 @@ module Minitest
|
|
126
127
|
end
|
127
128
|
|
128
129
|
def where(&b)
|
129
|
-
|
130
|
+
raise InvalidProperty unless b.call
|
130
131
|
end
|
131
132
|
|
132
133
|
def iterate!
|
133
134
|
while continue_iterate? && @result.nil? && @valid_test_cases <= @max_success
|
134
|
-
@valid_test_case = true
|
135
135
|
@generated = []
|
136
136
|
@generator = ::Minitest::Proptest::Gen.new(@random)
|
137
137
|
@calls += 1
|
138
138
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
end
|
149
|
-
if @valid_test_case && success
|
150
|
-
@status = Status.valid if @status.unknown?
|
151
|
-
@valid_test_cases += 1
|
152
|
-
elsif @valid_test_case
|
139
|
+
begin
|
140
|
+
if instance_eval(&@test_proc)
|
141
|
+
@status = Status.valid if @status.unknown?
|
142
|
+
@valid_test_cases += 1
|
143
|
+
else
|
144
|
+
@result = @generated
|
145
|
+
@status = Status.interesting
|
146
|
+
end
|
147
|
+
rescue Minitest::Assertion
|
153
148
|
@result = @generated
|
154
149
|
@status = Status.interesting
|
150
|
+
rescue InvalidProperty
|
151
|
+
rescue => e
|
152
|
+
@status = Status.invalid
|
153
|
+
@exception = e
|
155
154
|
end
|
156
155
|
|
157
156
|
@status = Status.exhausted if @calls >= @max_success * (@max_discard_ratio + 1)
|
158
157
|
@trivial = true if @generated.empty?
|
159
158
|
end
|
160
|
-
rescue => e
|
161
|
-
@status = Status.invalid
|
162
|
-
@exception = e
|
163
159
|
end
|
164
160
|
|
165
161
|
def rerun!
|
@@ -181,22 +177,22 @@ module Minitest
|
|
181
177
|
end
|
182
178
|
|
183
179
|
@generator = ::Minitest::Proptest::Gen.new(@random)
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
false
|
193
|
-
end
|
194
|
-
end
|
195
|
-
if success || !@valid_test_case
|
196
|
-
@generated = []
|
197
|
-
elsif @valid_test_case
|
180
|
+
begin
|
181
|
+
if instance_eval(&@test_proc)
|
182
|
+
@generated = []
|
183
|
+
else
|
184
|
+
@result = @generated
|
185
|
+
@status = Status.interesting
|
186
|
+
end
|
187
|
+
rescue Minitest::Assertion
|
198
188
|
@result = @generated
|
199
189
|
@status = Status.interesting
|
190
|
+
rescue InvalidProperty
|
191
|
+
@generated = []
|
192
|
+
rescue => e
|
193
|
+
@result = @generated
|
194
|
+
@status = Status.invalid
|
195
|
+
@exception = e
|
200
196
|
end
|
201
197
|
|
202
198
|
# Clean up after we're done
|
@@ -215,6 +211,12 @@ module Minitest
|
|
215
211
|
candidates = @generated.map(&:shrink_candidates)
|
216
212
|
old_arbitrary = @arbitrary
|
217
213
|
|
214
|
+
# Using a TracePoint to determine variable assignments at the time of
|
215
|
+
# the failure only occurs within shrink! - this is a deliberate decision
|
216
|
+
# which eliminates all time lost in iterate! to optimize for the success
|
217
|
+
# case. The tradeoff is that if all shrinking fails, one additional
|
218
|
+
# cycle (with the values which produced the original failure) will be
|
219
|
+
# required.
|
218
220
|
local_variables = {}
|
219
221
|
tracepoint = TracePoint.new(:b_return) do |trace|
|
220
222
|
if trace.path == @filename && trace.method_id.to_s == @methodname
|
@@ -249,27 +251,28 @@ module Minitest
|
|
249
251
|
@valid_test_case = true
|
250
252
|
|
251
253
|
@generator = ::Minitest::Proptest::Gen.new(@random)
|
252
|
-
if to_test[run[:run]].map(&:first).reduce(&:+)
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
@excption = e
|
263
|
-
break
|
264
|
-
ensure
|
265
|
-
tracepoint.disable
|
266
|
-
end
|
267
|
-
|
268
|
-
if !success && @valid_test_case
|
269
|
-
# The first hit is guaranteed to be the best scoring since the
|
270
|
-
# shrink candidates are pre-sorted.
|
254
|
+
if to_test[run[:run]].map(&:first).reduce(&:+) <= best_score
|
255
|
+
begin
|
256
|
+
tracepoint.enable
|
257
|
+
unless instance_eval(&@test_proc)
|
258
|
+
# The first hit is guaranteed to be the best scoring since the
|
259
|
+
# shrink candidates are pre-sorted.
|
260
|
+
best_generated = @generated
|
261
|
+
break
|
262
|
+
end
|
263
|
+
rescue Minitest::Assertion
|
271
264
|
best_generated = @generated
|
272
265
|
break
|
266
|
+
rescue InvalidProperty
|
267
|
+
# Invalid test case generated- continue
|
268
|
+
rescue => e
|
269
|
+
next unless @valid_test_case
|
270
|
+
|
271
|
+
@status = Status.invalid
|
272
|
+
@excption = e
|
273
|
+
break
|
274
|
+
ensure
|
275
|
+
tracepoint.disable
|
273
276
|
end
|
274
277
|
end
|
275
278
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: minitest-proptest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tina Wuest
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-09-
|
11
|
+
date: 2024-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest
|