open! Import open! Blit (* This unit test checks that when [blit] calls [unsafe_blit], the slices are valid. It also checks that [blit] doesn't call [unsafe_blit] when there is a range error. *) let%test_module _ = (module struct let blit_was_called = ref false let slices_are_valid = ref (Ok ()) module B = Make (struct type t = bool array let create ~len = Array.create false ~len let length = Array.length let unsafe_blit ~src ~src_pos ~dst ~dst_pos ~len = blit_was_called := true; slices_are_valid := Or_error.try_with (fun () -> assert (len >= 0); assert (src_pos >= 0); assert (src_pos + len <= Array.length src); assert (dst_pos >= 0); assert (dst_pos + len <= Array.length dst)); Array.blit ~src ~src_pos ~dst ~dst_pos ~len ;; end) let%test_module "Bool" = (module Test_blit.Test (struct type t = bool let equal = Bool.equal let of_bool = Fn.id end) (struct type t = bool array [@@deriving sexp_of] let create ~len = Array.create false ~len let length = Array.length let get = Array.get let set = Array.set end) (B)) ;; let%test_unit _ = let opts = [ None; Some (-1); Some 0; Some 1; Some 2 ] in List.iter [ 0; 1; 2 ] ~f:(fun src -> List.iter [ 0; 1; 2 ] ~f:(fun dst -> List.iter opts ~f:(fun src_pos -> List.iter opts ~f:(fun src_len -> List.iter opts ~f:(fun dst_pos -> try let check f = blit_was_called := false; slices_are_valid := Ok (); match Or_error.try_with f with | Error _ -> assert (not !blit_was_called) | Ok () -> ok_exn !slices_are_valid in check (fun () -> B.blito ~src:(Array.create ~len:src false) ?src_pos ?src_len ~dst:(Array.create ~len:dst false) ?dst_pos ()); check (fun () -> ignore (B.subo (Array.create ~len:src false) ?pos:src_pos ?len:src_len : bool array)) with | exn -> raise_s [%message "failure" (exn : exn) (src : int) (src_pos : int option) (src_len : int option) (dst : int) (dst_pos : int option)]))))) ;; end) ;;