This commit is contained in:
swrup 2025-11-11 02:07:51 +01:00
parent aa2ff7b2f0
commit 2f3113f55d
11742 changed files with 1223940 additions and 0 deletions

View file

@ -0,0 +1,326 @@
open Stdune
let dyn_of_pp tag pp =
let rec conv =
let open Dyn in
function
| Pp.Ast.Nop -> variant "Nop" []
| Seq (x, y) -> variant "Seq" [ conv x; conv y ]
| Concat (x, y) -> variant "Concat" [ conv x; list conv y ]
| Box (i, x) -> variant "Box" [ int i; conv x ]
| Vbox (i, x) -> variant "Vbox" [ int i; conv x ]
| Hbox x -> variant "Hbox" [ conv x ]
| Hvbox (i, x) -> variant "Hvbox" [ int i; conv x ]
| Hovbox (i, x) -> variant "Hovbox" [ int i; conv x ]
| Verbatim s -> variant "Verbatim" [ string s ]
| Char c -> variant "Char" [ char c ]
| Break (x, y) ->
let f = triple string int string in
variant "Break" [ f x; f y ]
| Newline -> variant "Newline" []
| Tag (ta, t) -> variant "Tag" [ tag ta; conv t ]
| Text s -> variant "Text" [ string s ]
in
conv (Pp.to_ast pp)
;;
let%expect_test "reproduce #2664" =
(* https://github.com/ocaml/dune/issues/2664 *)
let b = Buffer.create 100 in
let f s = Buffer.add_string b ("\027[34m" ^ s ^ "\027[39m") in
for i = 1 to 20 do
f (string_of_int i)
done;
let string_with_ansi_colors = Buffer.contents b in
let pp = Ansi_color.parse string_with_ansi_colors in
let ansi_colors_from_pp =
let b = Buffer.create 16 in
let ppf = Format.formatter_of_buffer b in
Staged.unstage (Ansi_color.make_printer (lazy true) ppf) pp;
Buffer.contents b
in
printfn "Original : %S" string_with_ansi_colors;
printfn "From PP : %S" ansi_colors_from_pp;
[%expect
{|
Original : "\027[34m1\027[39m\027[34m2\027[39m\027[34m3\027[39m\027[34m4\027[39m\027[34m5\027[39m\027[34m6\027[39m\027[34m7\027[39m\027[34m8\027[39m\027[34m9\027[39m\027[34m10\027[39m\027[34m11\027[39m\027[34m12\027[39m\027[34m13\027[39m\027[34m14\027[39m\027[34m15\027[39m\027[34m16\027[39m\027[34m17\027[39m\027[34m18\027[39m\027[34m19\027[39m\027[34m20\027[39m"
From PP : "\027[34m1\027[0m\027[34m2\027[0m\027[34m3\027[0m\027[34m4\027[0m\027[34m5\027[0m\027[34m6\027[0m\027[34m7\027[0m\027[34m8\027[0m\027[34m9\027[0m\027[34m10\027[0m\027[34m11\027[0m\027[34m12\027[0m\027[34m13\027[0m\027[34m14\027[0m\027[34m15\027[0m\027[34m16\027[0m\027[34m17\027[0m\027[34m18\027[0m\027[34m19\027[0m\027[34m20\027[0m" |}];
let pp = dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn) pp |> Dyn.pp in
Format.printf "%a@.%!" Pp.to_fmt pp;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Nop,
Tag
([ Fg_blue ],
Verbatim
"1")),
Tag
([ Fg_blue ],
Verbatim "2")),
Tag
([ Fg_blue ],
Verbatim "3")),
Tag
([ Fg_blue ],
Verbatim "4")),
Tag
([ Fg_blue ],
Verbatim "5")),
Tag
([ Fg_blue ], Verbatim "6")),
Tag ([ Fg_blue ], Verbatim "7")),
Tag ([ Fg_blue ], Verbatim "8")),
Tag ([ Fg_blue ], Verbatim "9")),
Tag ([ Fg_blue ], Verbatim "10")),
Tag ([ Fg_blue ], Verbatim "11")),
Tag ([ Fg_blue ], Verbatim "12")),
Tag ([ Fg_blue ], Verbatim "13")),
Tag ([ Fg_blue ], Verbatim "14")),
Tag ([ Fg_blue ], Verbatim "15")),
Tag ([ Fg_blue ], Verbatim "16")),
Tag ([ Fg_blue ], Verbatim "17")),
Tag ([ Fg_blue ], Verbatim "18")),
Tag ([ Fg_blue ], Verbatim "19")),
Tag ([ Fg_blue ], Verbatim "20"))) |}]
;;
let%expect_test "Ansi_color.strip" =
print_string
(String.concat
~sep:"\n"
(List.map
~f:Ansi_color.strip
[ "\027[34mthe lazy fox\027[39m jumps over the brown dog\027[0m"
; "the lazy fox \027[34mjumps over\027[39m the brown dog\027[0m"
; "\027[34mthe lazy fox\027[39m jumps over \027[0mthe brown dog"
; "\027[34mthe lazy fox \027[39mjumps over\027[0thebrown dog"
]));
[%expect
{|
the lazy fox jumps over the brown dog
the lazy fox jumps over the brown dog
the lazy fox jumps over the brown dog
the lazy fox jumps over|}]
;;
let%expect_test "parse fg and bg colors" =
let example =
"This is a \027[34mblue\027[39m string with \027[31mred\027[39m and \
\027[32mgreen\027[39m together with strings of a \027[44mblue blackground\027[49m \
and \027[41mred background\027[49m and \027[42mgreen background\027[49m"
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This is a "),
Tag ([ Fg_blue ], Verbatim "blue")),
Verbatim " string with "),
Tag ([ Fg_red ], Verbatim "red")),
Verbatim " and "),
Tag ([ Fg_green ], Verbatim "green")),
Verbatim " together with strings of a "),
Tag ([ Bg_blue ], Verbatim "blue blackground")),
Verbatim " and "),
Tag ([ Bg_red ], Verbatim "red background")),
Verbatim " and "),
Tag ([ Bg_green ], Verbatim "green background"))) |}]
;;
let%expect_test "parse multiple fg and bg colors" =
let example =
"This text is \027[34;41mblue string with a red background\027[0m and \
\027[32;44mgreen string with a blue background\027[0m"
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This text is "),
Tag
([ Fg_blue; Bg_red ],
Verbatim "blue string with a red background")),
Verbatim " and "),
Tag
([ Fg_green; Bg_blue ],
Verbatim "green string with a blue background"))) |}]
;;
let%expect_test "fg default overrides" =
let example =
"This text has a \027[34mblue foreground\027[39m but here it becomes the default \
foreground,\027[34;39m even together with another foreground modifier."
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This text has a "),
Tag ([ Fg_blue ], Verbatim "blue foreground")),
Verbatim " but here it becomes the default foreground,"),
Verbatim " even together with another foreground modifier.")) |}]
;;
let%expect_test "bg default overrides" =
let example =
"This text has a \027[44mblue background\027[49m but here it becomes the default \
background,\027[44;49m even together with another background modifier."
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This text has a "),
Tag ([ Bg_blue ], Verbatim "blue background")),
Verbatim " but here it becomes the default background,"),
Verbatim " even together with another background modifier.")) |}]
;;
let%expect_test "parse 8-bit colors" =
let example =
"This is a \027[38;5;33mblue\027[39m string with \027[38;5;196mred\027[39m and \
\027[38;5;46mgreen\027[39m together with strings of a \027[48;5;33mblue \
blackground\027[49m and \027[48;5;196mred background\027[49m and \027[48;5;46mgreen \
background\027[49m"
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This is a "),
Tag
([ Fg_8_bit_color 33 ], Verbatim "blue")),
Verbatim " string with "),
Tag ([ Fg_8_bit_color 196 ], Verbatim "red")),
Verbatim " and "),
Tag ([ Fg_8_bit_color 46 ], Verbatim "green")),
Verbatim " together with strings of a "),
Tag ([ Bg_8_bit_color 33 ], Verbatim "blue blackground")),
Verbatim " and "),
Tag ([ Bg_8_bit_color 196 ], Verbatim "red background")),
Verbatim " and "),
Tag ([ Bg_8_bit_color 46 ], Verbatim "green background"))) |}]
;;
let%expect_test "parse 24-bit colors" =
let example =
"This is a \027[38;2;255;0;0mblue\027[39m string with \027[38;2;0;255;0mred\027[39m \
and \027[38;2;0;0;255mgreen\027[39m together with strings of a \
\027[48;2;255;0;0mblue blackground\027[49m and \027[48;2;0;255;0mred \
background\027[49m and \027[48;2;0;0;255mgreen background\027[49m"
in
Ansi_color.parse example
|> dyn_of_pp (Dyn.list Ansi_color.Style.to_dyn)
|> Dyn.pp
|> Format.printf "%a@.%!" Pp.to_fmt;
[%expect
{|
Vbox
(0,
Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq
(Seq (Nop, Verbatim "This is a "),
Tag
([ Fg_24_bit_color [ 255; 0; 0 ] ],
Verbatim "blue")),
Verbatim " string with "),
Tag
([ Fg_24_bit_color [ 0; 255; 0 ] ],
Verbatim "red")),
Verbatim " and "),
Tag
([ Fg_24_bit_color [ 0; 0; 255 ] ],
Verbatim "green")),
Verbatim " together with strings of a "),
Tag
([ Bg_24_bit_color [ 255; 0; 0 ] ],
Verbatim "blue blackground")),
Verbatim " and "),
Tag
([ Bg_24_bit_color [ 0; 255; 0 ] ], Verbatim "red background")),
Verbatim " and "),
Tag ([ Bg_24_bit_color [ 0; 0; 255 ] ], Verbatim "green background")))
|}]
;;

View file

@ -0,0 +1,75 @@
open Stdune
module Al = Appendable_list
let print xs = List.iter (Al.to_list xs) ~f:print_endline
let%expect_test "empty" =
print Al.empty;
[%expect {| |}]
;;
let%expect_test "singleton" =
print (Al.singleton "abc");
[%expect {| abc |}]
;;
let%expect_test "cons" =
print (List.fold_right [ "a"; "b"; "c"; "d" ] ~init:Al.empty ~f:Al.cons);
[%expect
{|
a
b
c
d |}]
;;
let%expect_test "append" =
print
Al.(singleton "a" @ (singleton "b" @ singleton "c") @ singleton "d" @ singleton "e");
[%expect
{|
a
b
c
d
e |}];
print Al.(cons "a" (cons "b" (cons "c" empty)) @ cons "d" (cons "e" (cons "f" empty)));
[%expect
{|
a
b
c
d
e
f |}]
;;
let%expect_test "concat" =
print (Al.concat (List.init 10 ~f:(fun i -> Al.singleton (Int.to_string i))));
[%expect
{|
0
1
2
3
4
5
6
7
8
9 |}]
;;
let%expect_test "is_empty" =
let assert_empty l = assert (Al.is_empty l) in
assert_empty Al.empty;
[%expect {||}];
assert_empty @@ Al.concat [];
[%expect {||}];
assert_empty @@ Al.concat [ Al.empty ];
[%expect {||}];
assert_empty @@ Al.concat [ Al.empty; Al.empty ];
[%expect {||}];
assert_empty @@ Al.of_list [];
[%expect {||}]
;;

View file

@ -0,0 +1,70 @@
open Stdune
let () =
(* We assert some properties of the conversion table here. It should be sorted
by the values in the second component and the suffix list must be
non-empty. *)
let rec loop = function
| [] -> ()
| [ (units, _) ] -> assert (List.length units >= 1)
| (units, value) :: ((_, value') :: _ as l) ->
assert (List.length units >= 1);
assert (value <= value');
loop l
in
loop Bytes_unit.conversion_table
;;
let test bytes = List.iter ~f:(fun x -> Bytes_unit.pp x |> print_endline) bytes
let%expect_test "Testing significant digit boundaries" =
test
[ 0L
; 1L
; 12L
; 123L
; 1234L
; 12345L
; 123456L
; 1234567L
; 12345678L
; 123456789L
; 1234567890L
; 12345678901L
; 123456789012L
; 1234567890123L
; 12345678901234L
; 123456789012345L
; 1234567890123456L
];
[%expect
{|
0B
1B
12B
123B
1.23kB
12.35kB
123.46kB
1.23MB
12.35MB
123.46MB
1.23GB
12.35GB
123.46GB
1.23TB
12.35TB
123.46TB
1234.57TB |}]
;;
(* CR-someday alizter: we should raise an exception here rather than giving a meaningless value. *)
(* Negative units get truncated but still printed as a negative. *)
let%expect_test "Negative units" =
test [ -1L; -10L ];
[%expect
{|
-0.00TB
-0.00TB
|}]
;;

View file

@ -0,0 +1,29 @@
open Stdune
module Position = Lexbuf.Position
module Compact_position = For_tests.Compact_position
let test (pos : Position.t) =
match Compact_position.For_tests.small_enough pos with
| false -> print_endline "position too large"
| true ->
let t = Compact_position.of_position pos in
let pos' = Compact_position.to_position t ~fname:pos.pos_fname in
if Position.equal pos pos'
then print_endline "[PASS]"
else (
print_endline "[FAIL]";
printfn "expected:\n%s" (Dyn.to_string (Position.to_dyn_no_file pos));
printfn "received:\n%s" (Dyn.to_string (Position.to_dyn_no_file pos')))
;;
let%expect_test "round trip tests" =
let base = Position.none in
test base;
[%expect {| [PASS] |}];
test { base with pos_cnum = 1; pos_lnum = 2; pos_bol = 3 };
[%expect {| [PASS] |}];
test { base with pos_cnum = 1_000; pos_lnum = 2_200; pos_bol = 300 };
[%expect {| [PASS] |}];
test { base with pos_cnum = 1 lsl 32; pos_lnum = 2_200; pos_bol = 300 };
[%expect {| position too large |}]
;;

View file

@ -0,0 +1,18 @@
(library
(name stdune_unit_tests)
(inline_tests
(deps
(source_tree ../unit-tests/findlib-db)
(source_tree ../unit-tests/toolchain.d)))
(libraries
stdune
dune_tests_common
unix
;; This is because of the (implicit_transitive_deps false)
;; in dune-project
ppx_expect.config
ppx_expect.config_types
base
ppx_inline_test.config)
(preprocess
(pps ppx_expect)))

View file

@ -0,0 +1,73 @@
open Stdune
open Dune_tests_common
let () = init ()
let extension s = print (Pp.text (Filename.extension s))
let%expect_test _ =
extension "toto.titi";
[%expect
{|
.titi
|}]
;;
let%expect_test _ =
extension "toto.";
[%expect
{|
.
|}]
;;
let%expect_test _ =
extension ".";
[%expect {| |}]
;;
let%expect_test _ =
extension ".titi";
[%expect {| |}]
;;
let%expect_test _ =
extension ".a";
[%expect {| |}]
;;
let%expect_test _ =
extension "a.";
[%expect
{|
.
|}]
;;
let%expect_test _ =
extension "a.a";
[%expect
{|
.a
|}]
;;
let%expect_test _ =
extension "truc/a.a";
[%expect
{|
.a
|}]
;;
let%expect_test _ =
extension "truc/.a";
[%expect {| |}]
;;
let%expect_test _ =
extension "truc/a.";
[%expect
{|
.
|}]
;;

View file

@ -0,0 +1,13 @@
open Stdune
let%expect_test "is_root" =
[ ""; "."; "/"; "foo/bar"; "/foo" ]
|> List.iter ~f:(fun path -> printfn "Fpath.is_root %S = %b" path (Fpath.is_root path));
[%expect
{|
Fpath.is_root "" = false
Fpath.is_root "." = true
Fpath.is_root "/" = true
Fpath.is_root "foo/bar" = false
Fpath.is_root "/foo" = false |}]
;;

View file

@ -0,0 +1,93 @@
open Stdune
let temp_dir () = Temp.create Dir ~prefix:"copyfile" ~suffix:"test"
let%expect_test "copy file simple" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
Io.write_file src "foobarbaz";
Io.copy_file ~src ~dst ();
print_endline (Io.read_file dst);
[%expect {| foobarbaz |}]
;;
let%expect_test "copy file overwrite" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
Io.write_file src "foobarbaz";
Io.write_file dst "xxx";
Io.copy_file ~src ~dst ();
print_endline (Io.read_file dst);
[%expect {| foobarbaz |}]
;;
let%expect_test "copy file chmod" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
Io.write_file src "foobarbaz";
Io.copy_file ~chmod:(fun _ -> 428) ~src ~dst ();
print_endline (Io.read_file dst);
Printf.printf "permissions: %d\n" (Path.stat_exn dst).st_perm;
[%expect
{|
foobarbaz
permissions: 428 |}]
;;
let%expect_test "copy file - no src" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
match Io.copy_file ~src ~dst () with
| () -> assert false
| exception Sys_error s ->
let s =
let _, exn = String.lsplit2_exn s ~on:':' in
sprintf "$PATH:%s" exn
in
print_endline s;
[%expect {| $PATH: No such file or directory |}]
;;
let%expect_test "copy file - src is a directory" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
Unix.mkdir (Path.to_string src) 0o755;
Io.copy_file ~src ~dst ();
[%expect.unreachable]
[@@expect.uncaught_exn {| (Sys_error "Is a directory") |}]
;;
let%expect_test "copy file - dst is a directory" =
let dir = temp_dir () in
let src = Path.relative dir "initial" in
let dst = Path.relative dir "final" in
Io.write_file src "foobarbaz";
Unix.mkdir (Path.to_string dst) 0o755;
Unix.sleepf 0.5;
match Io.copy_file ~src ~dst () with
| _ -> assert false
| exception Sys_error s ->
let s =
let _, exn = String.lsplit2_exn s ~on:':' in
sprintf "$DIR:%s" exn
in
print_endline s;
[%expect {| $DIR: Is a directory |}]
;;
let%expect_test "making a directory for an existing file" =
let dir = temp_dir () in
let fn = Path.relative dir "foo" in
Io.write_file fn "";
(* This does not error, but it will if it ends with a "/" on MacOS *)
ignore (Fpath.mkdir (Path.to_string fn));
[%expect {| |}];
Path.mkdir_p fn;
(* This in turn does not error *)
[%expect {| |}]
;;

View file

@ -0,0 +1,20 @@
open! Stdune
open Dyn
open Dune_tests_common
let intersperse t ~sep = List.intersperse t ~sep |> list string |> print_dyn
let%expect_test _ =
intersperse [] ~sep:"sep";
[%expect {| [] |}]
;;
let%expect_test _ =
intersperse [ "foo" ] ~sep:"sep";
[%expect {| [ "foo" ] |}]
;;
let%expect_test _ =
intersperse [ "foo"; "bar"; "baz" ] ~sep:"sep";
[%expect {| [ "foo"; "sep"; "bar"; "sep"; "baz" ] |}]
;;

View file

@ -0,0 +1,28 @@
open Stdune
let%expect_test "#7905 - inverted char offsets" =
let dir = Temp.create Dir ~prefix:"" ~suffix:"loc" in
let file = Path.relative dir "file.ml" in
Io.write_file
file
{|
type t = A | B
let f () () = function
| A -> ()
|};
let pos_fname = Path.to_string file in
let start = { Lexing.pos_fname; pos_lnum = 4; pos_bol = 0; pos_cnum = 14 } in
let stop = { start with pos_lnum = 5; pos_cnum = 11 } in
let loc = Loc.create ~start ~stop in
Format.printf "%a@." Pp.to_fmt (Loc.pp loc);
let output =
[%expect.output] |> String.split_lines |> List.tl |> String.concat ~sep:"\n"
in
Temp.destroy Dir file;
print_endline output;
[%expect
{|
4 | let f () () = function
5 | | A -> () |}]
;;

View file

@ -0,0 +1,16 @@
open Stdune
open Dune_tests_common
let () = init ()
(* Check that [of_alist_multi] groups elements in the right order *)
let%expect_test _ =
let open Dyn in
String.Map.of_list_multi [ "a", 1; "b", 1; "a", 2; "a", 3; "b", 2 ]
|> String.Map.to_dyn (list int)
|> print_dyn;
[%expect
{|
map { "a" : [ 1; 2; 3 ]; "b" : [ 1; 2 ] }
|}]
;;

View file

@ -0,0 +1,653 @@
open! Stdune
open Path
open Dune_tests_common
let () = Dune_tests_common.init ()
let r = Path.(relative root)
let e = Path.of_filename_relative_to_initial_cwd
let pp_path_local fmt l = Format.pp_print_string fmt (Path.Local.to_string l)
let of_filename_relative_to_initial_cwd s =
Path.of_filename_relative_to_initial_cwd s |> Path.to_dyn |> print_dyn
;;
let descendant p ~of_ = Dyn.option Path.to_dyn (Path.descendant p ~of_) |> print_dyn
let is_descendant p ~of_ = Dyn.bool (Path.is_descendant p ~of_) |> print_dyn
let reach p ~from =
let p = Path.of_string p in
let from = Path.of_string from in
let open Dyn in
let reach = Path.reach p ~from in
string reach |> print_dyn
;;
let reach_for_running p ~from = Path.reach_for_running p ~from |> Dyn.string |> print_dyn
let relative p s = Path.to_dyn (Path.relative p s) |> print_dyn
let append_source x y = Path.append_source x y |> Path.to_dyn |> print_dyn
let drop_build_context p =
let open Dyn in
Path.drop_build_context p |> option Path.Source.to_dyn |> print_dyn
;;
let local_part p = Path.local_part p |> Path.Local.to_dyn |> print_dyn
let%expect_test _ =
let p = Path.(relative root) "foo" in
descendant p ~of_:p;
[%expect
{|
Some (In_source_tree ".")
|}]
;;
let%expect_test _ =
(* different strings but same length *)
descendant (r "foo") ~of_:(r "bar");
[%expect
{|
None
|}]
;;
let%expect_test _ =
is_descendant (r "foo") ~of_:(r "foo");
[%expect
{|
true
|}]
;;
let%expect_test _ =
is_descendant (r "foo") ~of_:(r "foo/");
[%expect
{|
true
|}]
;;
let%expect_test _ =
is_descendant (r "foo/") ~of_:(r "foo");
[%expect
{|
true
|}]
;;
let%expect_test _ =
is_descendant (r "foo") ~of_:(r "bar");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (r "foo") ~of_:(r "bar/");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (r "foo/") ~of_:(r "bar");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (r "glob/foo") ~of_:(r "glob");
[%expect
{|
true
|}]
;;
let%expect_test _ =
is_descendant (r "glob/foo") ~of_:(r "glob/");
[%expect
{|
true
|}]
;;
let%expect_test _ =
is_descendant (e "/foo/bar") ~of_:(e "/foo");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (e "/foo/bar") ~of_:(e "/foo/bar");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (e "/foo/bar") ~of_:(e "/foo/bar/");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (e "/foo/bar/") ~of_:(e "/foo/bar");
[%expect
{|
false
|}]
;;
let%expect_test _ =
is_descendant (e "/foo/bar") ~of_:(e "/");
[%expect
{|
false
|}]
;;
let%expect_test _ =
descendant (r "foo") ~of_:(r "foo/");
[%expect
{|
Some (In_source_tree ".")
|}]
;;
let%expect_test _ =
descendant (r "foo/") ~of_:(r "foo");
[%expect
{|
Some (In_source_tree ".")
|}]
;;
let%expect_test _ =
descendant (r "foo/bar") ~of_:(r "foo");
[%expect
{|
Some (In_source_tree "bar")
|}]
;;
let%expect_test _ =
descendant Path.root ~of_:(r "foo");
[%expect
{|
None
|}]
;;
let%expect_test _ =
descendant Path.root ~of_:Path.root;
[%expect
{|
Some (In_source_tree ".")
|}]
;;
let%expect_test _ =
descendant (r "foo") ~of_:Path.root;
[%expect
{|
Some (In_source_tree "foo")
|}]
;;
let%expect_test _ =
descendant (Path.relative build_dir "foo") ~of_:root;
[%expect
{|
None
|}]
;;
let%expect_test _ =
descendant (Path.relative build_dir "foo") ~of_:(Path.of_string "/foo/bar");
[%expect
{|
None
|}]
;;
let%expect_test _ =
descendant (Path.relative build_dir "foo/bar") ~of_:build_dir;
[%expect
{|
Some (In_source_tree "foo/bar")
|}]
;;
let%expect_test _ =
descendant (Path.relative build_dir "foo/bar") ~of_:(Path.relative build_dir "foo");
[%expect
{|
Some (In_source_tree "bar")
|}]
;;
let%expect_test _ =
descendant (Path.relative build_dir "foo/bar") ~of_:(Path.relative build_dir "foo");
[%expect
{|
Some (In_source_tree "bar")
|}]
;;
let%expect_test _ =
descendant (Path.of_string "/foo/bar") ~of_:(Path.of_string "/foo");
[%expect
{|
None
|}]
;;
let%expect_test _ =
reach "/foo/baz" ~from:"/foo/bar";
[%expect
{|
"/foo/baz"
|}]
;;
let%expect_test _ =
reach "/foo/bar" ~from:"baz";
[%expect
{|
"/foo/bar"
|}]
;;
let%expect_test _ =
reach "bar/foo" ~from:"bar/baz/y";
[%expect
{|
"../../foo"
|}]
;;
let%expect_test _ =
reach "foo" ~from:"foo";
[%expect
{|
"."
|}]
;;
let%expect_test _ =
reach "bar/foo" ~from:"bar/foo";
[%expect
{|
"."
|}]
;;
let%expect_test _ =
reach "a/b/x" ~from:"a/b/y";
[%expect
{|
"../x"
|}]
;;
let%expect_test _ =
reach "a/b" ~from:"a/b/x";
[%expect
{|
".."
|}]
;;
let%expect_test _ =
reach "a/b/x" ~from:"a/b";
[%expect
{|
"x"
|}]
;;
let%expect_test _ =
reach "a/b/x/z" ~from:"a/b/y";
[%expect
{|
"../x/z"
|}]
;;
let%expect_test _ =
reach "a/b/y" ~from:"a/b/x/z";
[%expect
{|
"../../y"
|}]
;;
let%expect_test _ =
reach "a/bbb" ~from:"a/b";
[%expect
{|
"../bbb"
|}]
;;
let%expect_test _ =
reach "" ~from:"";
[%expect
{|
"."
|}]
;;
let%expect_test _ =
reach "" ~from:"foo";
[%expect
{|
".."
|}]
;;
let%expect_test _ =
reach "foo" ~from:"";
[%expect
{|
"foo"
|}]
;;
let%expect_test _ =
reach "x/foo" ~from:"bar/x";
[%expect
{|
"../../x/foo"
|}]
;;
let%expect_test _ =
reach "a/x" ~from:"x/b";
[%expect
{|
"../../a/x"
|}]
;;
let%expect_test _ =
reach "default/META.foo" ~from:"default";
[%expect
{|
"META.foo"
|}]
;;
let%expect_test _ =
reach "default/av" ~from:"default/avdevice";
[%expect
{|
"../av"
|}]
;;
let%expect_test _ =
relative (Path.of_string "relative") "/absolute/path";
[%expect
{|
External "/absolute/path"
|}]
;;
let%expect_test _ =
relative (Path.of_string "/abs1") "/abs2";
[%expect
{|
External "/abs2"
|}]
;;
let%expect_test _ =
relative (of_string "/abs1") "";
[%expect
{|
External "/abs1"
|}]
;;
let%expect_test _ =
relative root "/absolute/path";
[%expect
{|
External "/absolute/path"
|}]
;;
let%expect_test _ =
of_filename_relative_to_initial_cwd "/absolute/path";
[%expect
{|
External "/absolute/path"
|}]
;;
let%expect_test _ =
Path.is_managed (e "relative/path") |> Dyn.bool |> print_dyn;
[%expect
{|
false
|}]
;;
let%expect_test _ =
append_source Path.build_dir (Path.Source.relative Path.Source.root "foo");
[%expect
{|
In_build_dir "foo"
|}]
;;
let%expect_test _ =
append_source Path.root (Path.Source.relative Path.Source.root "foo");
[%expect
{|
In_source_tree "foo"
|}]
;;
let%expect_test _ =
append_source (Path.of_string "/root") (Path.Source.relative Path.Source.root "foo");
[%expect
{|
External "/root/foo"
|}]
;;
let%expect_test _ =
Path.rm_rf (Path.of_string "/does/not/exist/foo/bar/baz") |> Dyn.unit |> print_dyn;
[%expect.unreachable]
[@@expect.uncaught_exn
{|
( "(\"Path.rm_rf called on external dir\",\
\n { t = External \"/does/not/exist/foo/bar/baz\" })") |}]
;;
let%expect_test _ =
drop_build_context (Path.relative Path.build_dir "foo/bar");
[%expect
{|
Some (In_source_tree "bar")
|}]
;;
let%expect_test _ =
drop_build_context (Path.of_string "foo/bar");
[%expect
{|
None
|}]
;;
let%expect_test _ =
drop_build_context (e "/foo/bar");
[%expect
{|
None
|}]
;;
let%expect_test _ =
drop_build_context Path.build_dir;
[%expect
{|
None
|}]
;;
let%expect_test _ =
Path.is_in_build_dir Path.build_dir |> Dyn.bool |> print_dyn;
[%expect
{|
true
|}]
;;
let%expect_test _ =
Path.is_strict_descendant_of_build_dir Path.build_dir |> Dyn.bool |> print_dyn;
[%expect
{|
false
|}]
;;
let%expect_test _ =
Path.reach_for_running Path.build_dir ~from:Path.root |> Dyn.string |> print_dyn;
[%expect
{|
"./_build"
|}]
;;
let%expect_test _ =
reach_for_running
(Path.relative build_dir "foo/baz")
~from:(Path.relative build_dir "foo/bar/baz");
[%expect
{|
"../../baz"
|}]
;;
let%expect_test _ =
reach_for_running (e "/fake/path") ~from:(Path.relative build_dir "foo/bar/baz");
[%expect
{|
"/fake/path"
|}]
;;
let%expect_test _ =
reach_for_running (Path.relative root "foo") ~from:(Path.relative root "foo");
[%expect
{|
"./."
|}]
;;
let%expect_test _ =
relative Path.root "_build";
[%expect
{|
In_build_dir "."
|}]
;;
let%expect_test _ =
(* This is not right, but kind of annoying to fix :/ *)
relative (r "foo") "../_build";
[%expect
{|
In_build_dir "."
|}]
;;
let%expect_test _ =
local_part (Path.of_string "/c/d");
[%expect
{|
"c/d"
|}]
;;
let%expect_test _ =
local_part (r "c/d");
[%expect
{|
"c/d"
|}]
;;
let%expect_test _ =
Path.Build.extract_first_component Path.Build.root
|> Dyn.(option (pair string Local.to_dyn))
|> print_dyn;
[%expect
{|
None
|}]
;;
let%expect_test "drop prefix" =
Path.drop_prefix ~prefix:(r "foo/bar") (r "foo/bar/baz")
|> Dyn.option Path.Local.to_dyn
|> print_dyn;
[%expect {| Some "baz" |}]
;;
let%expect_test "drop external prefix" =
Path.drop_prefix
~prefix:(Path.of_filename_relative_to_initial_cwd "foo/bar")
(Path.of_filename_relative_to_initial_cwd "foo/bar/baz")
|> Dyn.option Path.Local.to_dyn
|> print_dyn;
[%expect {| Some "baz" |}]
;;
let%expect_test "drop prefix as substring" =
Path.drop_prefix ~prefix:(r "foo/bar") (r "foo/barbaz")
|> Dyn.option Path.Local.to_dyn
|> print_dyn;
[%expect {| None |}]
;;
let%expect_test "drop external prefix as substring" =
Path.drop_prefix
~prefix:(Path.of_filename_relative_to_initial_cwd "foo/bar")
(Path.of_filename_relative_to_initial_cwd "foo/barbaz")
|> Dyn.option Path.Local.to_dyn
|> print_dyn;
[%expect {| None |}]
;;
let%expect_test "drop entire path" =
let path = r "foo/bar" in
Path.drop_prefix ~prefix:path path |> Dyn.option Path.Local.to_dyn |> print_dyn;
[%expect {| Some "." |}]
;;
let%expect_test "drop entire external path" =
let path = Path.of_filename_relative_to_initial_cwd "foo/bar" in
Path.drop_prefix ~prefix:path path |> Dyn.option Path.Local.to_dyn |> print_dyn;
[%expect {| Some "." |}]
;;
let%expect_test "drop prefix with a trailing /" =
Path.drop_prefix ~prefix:(Path.of_string "/a/b/c/") (Path.of_string "/a/b/c/d/e")
|> Dyn.option Path.Local.to_dyn
|> print_dyn;
[%expect {| Some "d/e" |}]
;;

View file

@ -0,0 +1,209 @@
open! Stdune
open Dyn
open Dune_tests_common
let () = init ()
let take s n = String.take s n |> string |> print_dyn
let drop s n = String.drop s n |> string |> print_dyn
let split_n s n = String.split_n s n |> pair string string |> print_dyn
let split s ~on = String.split s ~on |> list string |> print_dyn
let%expect_test _ =
take "foobar" 3;
[%expect
{|
"foo"
|}]
;;
let%expect_test _ =
take "foobar" 0;
[%expect
{|
""
|}]
;;
let%expect_test _ =
take "foo" 10;
[%expect
{|
"foo"
|}]
;;
let%expect_test _ =
take "" 10;
[%expect
{|
""
|}]
;;
let%expect_test _ =
take "" 0;
[%expect
{|
""
|}]
;;
let%expect_test _ =
drop "" 0;
[%expect
{|
""
|}]
;;
let%expect_test _ =
drop "foo" 0;
[%expect
{|
"foo"
|}]
;;
let%expect_test _ =
drop "foo" 5;
[%expect
{|
""
|}]
;;
let%expect_test _ =
drop "foobar" 3;
[%expect
{|
"bar"
|}]
;;
let%expect_test _ =
split_n "foobar" 3;
[%expect
{|
("foo", "bar")
|}]
;;
let%expect_test _ =
split_n "foobar" 10;
[%expect
{|
("foobar", "")
|}]
;;
let%expect_test _ =
split_n "foobar" 0;
[%expect
{|
("", "foobar")
|}]
;;
let%expect_test _ =
split_n "foobar" 6;
[%expect
{|
("foobar", "")
|}]
;;
let%expect_test _ =
split_n "" 0;
[%expect
{|
("", "")
|}]
;;
let%expect_test _ =
split_n "" 10;
[%expect
{|
("", "")
|}]
;;
let%expect_test _ =
String.longest_prefix [ "food"; "foo"; "foo-bar" ] |> string |> print_dyn;
[%expect
{|
"foo"
|}]
;;
let%expect_test _ =
String.drop_suffix "foobar" ~suffix:"bar" |> option string |> print_dyn;
[%expect
{|
Some "foo"
|}]
;;
let%expect_test _ =
String.drop_suffix "foobar" ~suffix:"foobar" |> option string |> print_dyn;
[%expect
{|
Some ""
|}]
;;
let%expect_test _ =
String.drop_suffix "foobar" ~suffix:"" |> option string |> print_dyn;
[%expect
{|
Some "foobar"
|}]
;;
let%expect_test _ =
String.drop_suffix "foobar" ~suffix:"foo" |> option string |> print_dyn;
[%expect
{|
None
|}]
;;
let%expect_test _ =
split "a" ~on:':';
[%expect {| [ "a" ] |}]
;;
let%expect_test _ =
split "" ~on:':';
[%expect {| [ "" ] |}]
;;
let%expect_test _ =
split "a:" ~on:':';
[%expect {| [ "a"; "" ] |}]
;;
let%expect_test _ =
split ":a" ~on:':';
[%expect {| [ ""; "a" ] |}]
;;
let%expect_test _ =
split "a:b" ~on:':';
[%expect {| [ "a"; "b" ] |}]
;;
let%expect_test _ =
split ":" ~on:':';
[%expect {| [ ""; "" ] |}]
;;
let%expect_test _ =
split "::" ~on:':';
[%expect {| [ ""; ""; "" ] |}]
;;
let%expect_test _ =
split ":::" ~on:':';
[%expect {| [ ""; ""; ""; "" ] |}]
;;

View file

@ -0,0 +1,21 @@
open Stdune
open Dune_tests_common
open Dyn
let () = init ()
let%expect_test "Temp.clear_dir works" =
let path = Temp.create Dir ~prefix:"dune" ~suffix:"unit_test" in
Io.write_file (Path.relative path "foo") "";
let print () =
Path.readdir_unsorted path |> Result.to_dyn (list string) opaque |> print_dyn
in
print ();
Temp.clear_dir path;
print ();
[%expect
{|
Ok [ "foo" ]
Ok []
|}]
;;

View file

@ -0,0 +1,30 @@
open! Stdune
let deps_of_list list dep = List.assoc_opt dep list |> Option.value ~default:[]
let top list ~deps =
let dyn =
let res = Top_closure.String.top_closure list ~key:Fun.id ~deps:(deps_of_list deps) in
let f = Dyn.(list string) in
Result.to_dyn f f res
in
print_endline (Dyn.to_string dyn)
;;
let%expect_test "trivial" =
top [ "entry" ] ~deps:[ "entry", [] ];
[%expect {| Ok [ "entry" ] |}]
;;
let%expect_test "no cycle" =
top [ "deps"; "entry" ] ~deps:[ "entry", []; "deps", [ "entry" ] ];
[%expect {| Ok [ "entry"; "deps" ] |}]
;;
let%expect_test "cycle" =
let top = top ~deps:[ "foo", [ "bar" ]; "bar", [ "foo" ] ] in
top [ "foo" ];
[%expect {| Error [ "foo"; "bar"; "foo" ] |}];
top [ "bar" ];
[%expect {| Error [ "bar"; "foo"; "bar" ] |}]
;;

View file

@ -0,0 +1,13 @@
open Stdune
let () = Printexc.record_backtrace false
let%expect_test "user errors are serializable" =
let loc = Loc.none in
let annots =
User_message.Annots.singleton User_message.Annots.has_embedded_location ()
in
let error = User_error.make ~loc ~annots [ Pp.text "testing" ] in
let (_ : string) = Marshal.to_string error [] in
[%expect {||}]
;;