Skip to content

Commit f750ccf

Browse files
authored
Merge pull request #160 from jmid/QCheck2.Gen.list_size-fix-stack_overflow
Fix `QCheck2.gen.list_size Stack overflow`
2 parents 2ad6a0f + ce76651 commit f750ccf

File tree

5 files changed

+28
-33
lines changed

5 files changed

+28
-33
lines changed

src/core/QCheck2.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,14 +528,16 @@ module Gen = struct
528528

529529
let ui64 : int64 t = map Int64.abs int64
530530

531+
(* A tail-recursive implementation over Tree.t *)
531532
let list_size (size : int t) (gen : 'a t) : 'a list t =
532-
size >>= fun size ->
533-
let rec loop n =
533+
fun st ->
534+
Tree.bind (size st) @@ fun size ->
535+
let rec loop n acc =
534536
if n <= 0
535-
then pure []
536-
else liftA2 List.cons gen (loop (n - 1))
537+
then acc
538+
else (loop [@tailcall]) (n - 1) (Tree.liftA2 List.cons (gen st) acc)
537539
in
538-
loop size
540+
loop size (Tree.pure [])
539541

540542
let list (gen : 'a t) : 'a list t = list_size nat gen
541543

test/core/QCheck2_expect_test.ml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ module Shrink = struct
182182

183183
let strings_are_empty =
184184
Test.make ~name:"strings are empty" ~count:1000 ~print:Print.string
185-
Gen.string (fun s -> (*Printf.printf "\"%s\"\n" (String.escaped s);*) s = "")
185+
Gen.string (fun s -> s = "")
186186

187187
let string_never_has_000_char =
188188
Test.make ~name:"string never has a \\000 char" ~count:1000 ~print:Print.string
@@ -203,7 +203,7 @@ module Shrink = struct
203203

204204
let list_shorter_10 =
205205
Test.make ~name:"lists shorter than 10" ~print:Print.(list int)
206-
Gen.(list small_int) (fun xs -> (*print_list xs;*) List.length xs < 10)
206+
Gen.(list small_int) (fun xs -> List.length xs < 10)
207207

208208
let length_printer xs =
209209
Printf.sprintf "[...] list length: %i" (List.length xs)
@@ -212,17 +212,17 @@ module Shrink = struct
212212

213213
let list_shorter_432 =
214214
Test.make ~name:"lists shorter than 432" ~print:length_printer
215-
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
216-
(fun xs -> (*print_list xs;*) List.length xs < 432)
215+
Gen.(list_size size_gen small_int)
216+
(fun xs -> List.length xs < 432)
217217

218218
let list_shorter_4332 =
219219
Test.make ~name:"lists shorter than 4332" ~print:length_printer
220-
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
221-
(fun xs -> (*print_list xs;*) List.length xs < 4332)
220+
Gen.(list_size size_gen small_int)
221+
(fun xs -> List.length xs < 4332)
222222

223223
let list_equal_dupl =
224-
Test.make ~name:"lists equal to duplication" ~print:length_printer
225-
Gen.(list_size size_gen small_int) (*Gen.(list small_int)*)
224+
Test.make ~name:"lists equal to duplication" ~print:Print.(list int)
225+
Gen.(list_size size_gen small_int)
226226
(fun xs -> try xs = xs @ xs
227227
with Stack_overflow -> false)
228228

test/core/QCheck_expect_test.ml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ module Shrink = struct
178178

179179
let strings_are_empty =
180180
Test.make ~name:"strings are empty" ~count:1000
181-
string (fun s -> (*Printf.printf "\"%s\"\n" (String.escaped s);*) s = "")
181+
string (fun s -> s = "")
182182

183183
let string_never_has_000_char =
184184
Test.make ~name:"string never has a \\000 char" ~count:1000
@@ -198,7 +198,7 @@ module Shrink = struct
198198

199199
let list_shorter_10 =
200200
Test.make ~name:"lists shorter than 10"
201-
(list small_int) (fun xs -> (*print_list xs;*) List.length xs < 10)
201+
(list small_int) (fun xs -> List.length xs < 10)
202202

203203
let length_printer xs =
204204
Printf.sprintf "[...] list length: %i" (List.length xs)
@@ -207,18 +207,17 @@ module Shrink = struct
207207

208208
let list_shorter_432 =
209209
Test.make ~name:"lists shorter than 432"
210-
(set_print length_printer (list_of_size size_gen small_int)) (*(list small_int)*)
211-
(fun xs -> (*print_list xs;*) List.length xs < 432)
210+
(set_print length_printer (list_of_size size_gen small_int))
211+
(fun xs -> List.length xs < 432)
212212

213213
let list_shorter_4332 =
214214
Test.make ~name:"lists shorter than 4332"
215215
(set_shrink Shrink.list_spine (set_print length_printer (list_of_size size_gen small_int)))
216-
(fun xs -> (*print_list xs;*) List.length xs < 4332)
216+
(fun xs -> List.length xs < 4332)
217217

218218
let list_equal_dupl =
219219
Test.make ~name:"lists equal to duplication"
220-
(set_print length_printer (list_of_size size_gen small_int))
221-
(*(set_print length_printer (list small_int))*)
220+
(list_of_size size_gen small_int)
222221
(fun xs -> try xs = xs @ xs
223222
with Stack_overflow -> false)
224223

test/core/qcheck2_output.txt.expected

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -318,27 +318,21 @@ Test lists shorter than 10 failed (16 shrink steps):
318318

319319
--- Failure --------------------------------------------------------------------
320320

321-
Test lists shorter than 432 failed:
321+
Test lists shorter than 432 failed (412 shrink steps):
322322

323-
ERROR: uncaught exception in generator for test lists shorter than 432 after 100 steps:
324-
Exception: Stack overflow
325-
Backtrace:
323+
[...] list length: 432
326324

327325
--- Failure --------------------------------------------------------------------
328326

329-
Test lists shorter than 4332 failed:
327+
Test lists shorter than 4332 failed (4022 shrink steps):
330328

331-
ERROR: uncaught exception in generator for test lists shorter than 4332 after 100 steps:
332-
Exception: Stack overflow
333-
Backtrace:
329+
[...] list length: 4332
334330

335331
--- Failure --------------------------------------------------------------------
336332

337-
Test lists equal to duplication failed:
333+
Test lists equal to duplication failed (4 shrink steps):
338334

339-
ERROR: uncaught exception in generator for test lists equal to duplication after 100 steps:
340-
Exception: Stack overflow
341-
Backtrace:
335+
[0]
342336

343337
--- Failure --------------------------------------------------------------------
344338

test/core/qcheck_output.txt.expected

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ Test lists shorter than 4332 failed (13 shrink steps):
267267

268268
Test lists equal to duplication failed (20 shrink steps):
269269

270-
[...] list length: 1
270+
[0]
271271

272272
--- Failure --------------------------------------------------------------------
273273

0 commit comments

Comments
 (0)