let assert_equal ?ctxt ?(cmp = ( = )) ?printer ?pp_diff ?msg expected actual =
  let get_error_string () =
    let res =
      buff_format_printf
        (fun fmt ->
           Format.pp_open_vbox fmt 0;
           begin
             match msg with
               | Some s ->
                   Format.pp_open_box fmt 0;
                   Format.pp_print_string fmt s;
                   Format.pp_close_box fmt ();
                   Format.pp_print_cut fmt ()
               | None ->
                   ()
           end;

           begin
             match printer with
               | Some p ->
                   Format.fprintf fmt
                     "@[expected: @[%s@]@ but got: @[%s@]@]@,"
                     (p expected)
                     (p actual)

               | None ->
                   Format.fprintf fmt "@[not equal@]@,"
           end;

           begin
             match pp_diff with
               | Some d ->
                   Format.fprintf fmt
                     "@[differences: %a@]@,"
                      d (expected, actual)

               | None ->
                   ()
           end;
           Format.pp_close_box fmt ())
    in
    let len =
      String.length res
    in
      if len > 0 && res.[len - 1] = '\n' then
        String.sub res 0 (len - 1)
      else
        res
  in
  let logf fmt =
    match ctxt with
      | Some ctxt ->
          OUnitLogger.Test.logf ctxt.test_logger `Info fmt
      | None ->
          Printf.ksprintf ignore fmt
  in
    begin
      match msg with
        | Some str ->
            logf "%s" str;
        | _ ->
            ()
    end;
    begin
      match printer with
        | Some p ->
            logf "Expected: %s" (p expected);
            logf "Actual: %s" (p actual)
        | _ ->
            ()
    end;

    if not (cmp expected actual) then
      assert_failure (get_error_string ())