As the new QCheck.Shrink.string unit tests document, on a failure path (going through all shrinking candidates without luck) the current approach may be a bit too exhaustive:
|
("string \"vi5x92xgG\"", "vi5x92xgG", (* A less exhaustive string shrinker would be preferable *) |
|
["vi5x9"; "vi52xgG"; "vix92xgG"; "5x92xgG"; |
|
"v5x92xgG"; "i5x92xgG"; "li5x92xgG"; "qi5x92xgG"; "ti5x92xgG"; "ui5x92xgG"; |
|
"ve5x92xgG"; "vg5x92xgG"; "vh5x92xgG"; |
|
"viKx92xgG"; "vi@x92xgG"; "vi:x92xgG"; "vi7x92xgG"; "vi6x92xgG"; |
|
"vi5m92xgG"; "vi5s92xgG"; "vi5v92xgG"; "vi5w92xgG"; |
|
"vi5xM2xgG"; "vi5xC2xgG"; "vi5x>2xgG"; "vi5x;2xgG"; "vi5x:2xgG"; |
|
"vi5x9IxgG"; "vi5x9=xgG"; "vi5x97xgG"; "vi5x94xgG"; "vi5x93xgG"; |
|
"vi5x92mgG"; "vi5x92sgG"; "vi5x92vgG"; "vi5x92wgG"; |
|
"vi5x92xdG"; "vi5x92xfG"; |
|
"vi5x92xgT"; "vi5x92xgM"; "vi5x92xgJ"; "vi5x92xgH"]); |
By falling back on Shrink.list_spine we get a nice and short candidate sequence when we stay clear of element reduction:
# Shrink.string ~shrink:Shrink.nil "zzzzz" (fun xs -> Printf.printf "%s\n" Print.(string xs));;
zzz
zzzz
zzz
zzzz
However, exhaustively trying to reduce all O(n) entries, say O(log n) times, brings this to O(n log n) which may be a bit much:
# Shrink.string ~shrink:Shrink.char "zzzzz" (fun xs -> Printf.printf "%s\n" Print.(string xs));;
zzz
zzzz
zzz
zzzz
nzzzz
tzzzz
wzzzz
yzzzz
znzzz
ztzzz
zwzzz
zyzzz
zznzz
zztzz
zzwzz
zzyzz
zzznz
zzztz
zzzwz
zzzyz
zzzzn
zzzzt
zzzzw
zzzzy
We are getting bitten by this in ocaml-multicore/multicoretests, as remarked by @edwintorok here: ocaml-multicore/multicoretests#329 (comment)
As an alternative to avoiding character-shrinks above a certain threshold, one could consider alternative approaches, e.g.
- reducing only the first non-
'a' char
- reducing several
chars simultaneously "zzzzz" -> "aaazz"
- ...
As the new
QCheck.Shrink.stringunit tests document, on a failure path (going through all shrinking candidates without luck) the current approach may be a bit too exhaustive:qcheck/test/core/QCheck_unit_tests.ml
Lines 93 to 103 in f37621a
By falling back on
Shrink.list_spinewe get a nice and short candidate sequence when we stay clear of element reduction:However, exhaustively trying to reduce all O(n) entries, say O(log n) times, brings this to O(n log n) which may be a bit much:
We are getting bitten by this in ocaml-multicore/multicoretests, as remarked by @edwintorok here: ocaml-multicore/multicoretests#329 (comment)
As an alternative to avoiding character-shrinks above a certain threshold, one could consider alternative approaches, e.g.
'a'charchars simultaneously"zzzzz"-> "aaazz"