This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
330
unikernel/duniverse/ocaml-re/lib_test/expect/test_str.ml
Normal file
330
unikernel/duniverse/ocaml-re/lib_test/expect/test_str.ml
Normal file
|
|
@ -0,0 +1,330 @@
|
|||
open Import
|
||||
|
||||
module type Str_intf = module type of Str
|
||||
|
||||
module Test_matches (R : Str_intf) = struct
|
||||
let groups () =
|
||||
let group i =
|
||||
try `Found (R.group_beginning i) with
|
||||
| Not_found -> `Not_found
|
||||
| Invalid_argument _ -> `Not_exists
|
||||
in
|
||||
let rec loop acc i =
|
||||
match group i with
|
||||
| `Found p -> loop ((p, R.group_end i) :: acc) (i + 1)
|
||||
| `Not_found -> loop ((-1, -1) :: acc) (i + 1)
|
||||
| `Not_exists -> List.rev acc
|
||||
in
|
||||
loop [] 0
|
||||
;;
|
||||
|
||||
let eq_match ?(pos = 0) ?(case = true) r s =
|
||||
let pat = if case then R.regexp r else R.regexp_case_fold r in
|
||||
try
|
||||
ignore (R.search_forward pat s pos);
|
||||
Some (groups ())
|
||||
with
|
||||
| Not_found -> None
|
||||
;;
|
||||
|
||||
let eq_match' ?(pos = 0) ?(case = true) r s =
|
||||
let pat = if case then R.regexp r else R.regexp_case_fold r in
|
||||
try
|
||||
ignore (R.string_match pat s pos);
|
||||
Some (groups ())
|
||||
with
|
||||
| Not_found -> None
|
||||
;;
|
||||
end
|
||||
|
||||
module T_str = Test_matches (Str)
|
||||
module T_re = Test_matches (Re.Str)
|
||||
|
||||
let test dyn_of_ok str re args =
|
||||
let run f =
|
||||
match f () with
|
||||
| s -> Ok s
|
||||
| exception exn -> Error exn
|
||||
in
|
||||
let str = run (fun () -> str args) in
|
||||
let re = run (fun () -> re args) in
|
||||
if not (Poly.equal str re)
|
||||
then (
|
||||
let printer x =
|
||||
let dyn =
|
||||
let open Dyn in
|
||||
result dyn_of_ok (fun x -> string (Printexc.to_string x)) x
|
||||
in
|
||||
sexp_of_dyn dyn |> Base.Sexp.to_string_hum
|
||||
in
|
||||
Printf.printf "str: %s\n" (printer str);
|
||||
Printf.printf "re: %s\n" (printer re))
|
||||
;;
|
||||
|
||||
let dyn_of_pairs x =
|
||||
Dyn.option
|
||||
(fun x ->
|
||||
List.map x ~f:(fun (start, stop) ->
|
||||
let open Dyn in
|
||||
pair (int start) (int stop))
|
||||
|> Dyn.list)
|
||||
x
|
||||
;;
|
||||
|
||||
let split_result_conv =
|
||||
List.map ~f:(function
|
||||
| Str.Delim x -> Re.Str.Delim x
|
||||
| Str.Text x -> Re.Str.Text x)
|
||||
;;
|
||||
|
||||
let dyn_split_result_list list =
|
||||
List.map
|
||||
list
|
||||
~f:
|
||||
(let open Dyn in
|
||||
function
|
||||
| Re.Str.Delim x -> variant "Delim" [ string x ]
|
||||
| Text s -> variant "Text" [ string s ])
|
||||
|> Dyn.list
|
||||
;;
|
||||
|
||||
type ('a, 'b) test =
|
||||
{ name : string
|
||||
; dyn_of_ok : 'b -> Dyn.t
|
||||
; re_str : Re.Str.regexp -> 'a -> 'b
|
||||
; str : Str.regexp -> 'a -> 'b
|
||||
}
|
||||
|
||||
let bounded_split_t =
|
||||
{ name = "bounded_split"
|
||||
; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string))
|
||||
; re_str = (fun re (s, n) -> Re.Str.bounded_split re s n)
|
||||
; str = (fun re (s, n) -> Str.bounded_split re s n)
|
||||
}
|
||||
;;
|
||||
|
||||
let bounded_full_split_t =
|
||||
{ name = "bounded_full_split"
|
||||
; dyn_of_ok = dyn_split_result_list
|
||||
; re_str = (fun re (s, n) -> Re.Str.bounded_full_split re s n)
|
||||
; str = (fun re (s, n) -> split_result_conv (Str.bounded_full_split re s n))
|
||||
}
|
||||
;;
|
||||
|
||||
let full_split_t =
|
||||
{ bounded_full_split_t with
|
||||
name = "full_split"
|
||||
; re_str = (fun re s -> Re.Str.full_split re s)
|
||||
; str = (fun re s -> split_result_conv (Str.full_split re s))
|
||||
}
|
||||
;;
|
||||
|
||||
let split_delim_t =
|
||||
{ name = "split_delim"
|
||||
; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string))
|
||||
; re_str = Re.Str.split_delim
|
||||
; str = Str.split_delim
|
||||
}
|
||||
;;
|
||||
|
||||
let split_t =
|
||||
{ name = "split"
|
||||
; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string))
|
||||
; re_str = Re.Str.split
|
||||
; str = Str.split
|
||||
}
|
||||
;;
|
||||
|
||||
let global_replace_t =
|
||||
{ name = "global_replace"
|
||||
; dyn_of_ok = Dyn.string
|
||||
; re_str = (fun re (r, s) -> Re.Str.global_replace re r s)
|
||||
; str = (fun re (r, s) -> Str.global_replace re r s)
|
||||
}
|
||||
;;
|
||||
|
||||
let eq_match ?pos ?case re =
|
||||
test dyn_of_pairs (T_str.eq_match ?pos ?case re) (T_re.eq_match ?pos ?case re)
|
||||
;;
|
||||
|
||||
let eq_match' ?pos ?case re =
|
||||
test dyn_of_pairs (T_str.eq_match' ?pos ?case re) (T_re.eq_match' ?pos ?case re)
|
||||
;;
|
||||
|
||||
let test t re args =
|
||||
test t.dyn_of_ok (t.re_str (Re.Str.regexp re)) (t.str (Str.regexp re)) args
|
||||
;;
|
||||
|
||||
let split_delim re s = test split_delim_t re s
|
||||
let split re s = test split_t re s
|
||||
let full_split re s = test full_split_t re s
|
||||
let bounded_split re s n = test bounded_split_t re (s, n)
|
||||
let bounded_full_split re s n = test bounded_full_split_t re (s, n)
|
||||
let global_replace re r s = test global_replace_t re (r, s)
|
||||
|
||||
let%expect_test "literal match" =
|
||||
eq_match "a" "a";
|
||||
eq_match "a" "b";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "alt" =
|
||||
eq_match "a\\|b" "a";
|
||||
eq_match "a\\|b" "b";
|
||||
eq_match "a\\|b" "c";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "seq" =
|
||||
eq_match "ab" "ab";
|
||||
eq_match "ab" "ac";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "epsilon" =
|
||||
eq_match "" "";
|
||||
eq_match "" "a";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "rep" =
|
||||
eq_match "a*" "";
|
||||
eq_match "a*" "a";
|
||||
eq_match "a*" "aa";
|
||||
eq_match "a*" "b";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "rep1" =
|
||||
eq_match "a+" "a";
|
||||
eq_match "a+" "aa";
|
||||
eq_match "a+" "";
|
||||
eq_match "a+" "b";
|
||||
[%expect {| |}]
|
||||
;;
|
||||
|
||||
let%expect_test "opt" =
|
||||
eq_match "a?" "";
|
||||
eq_match "a?" "a";
|
||||
[%expect {| |}]
|
||||
;;
|
||||
|
||||
let%expect_test "bol" =
|
||||
eq_match "^a" "ab";
|
||||
eq_match "^a" "b\na";
|
||||
eq_match "^a" "ba";
|
||||
[%expect {| |}]
|
||||
;;
|
||||
|
||||
let%expect_test "eol" =
|
||||
eq_match "a$" "ba";
|
||||
eq_match "a$" "a\nb";
|
||||
eq_match "a$" "ba\n";
|
||||
eq_match "a$" "ab";
|
||||
[%expect {| |}]
|
||||
;;
|
||||
|
||||
let%expect_test "start" =
|
||||
eq_match ~pos:1 "Za" "xab";
|
||||
eq_match ~pos:1 "Za" "xb\na";
|
||||
eq_match ~pos:1 "Za" "xba";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "match semantics" =
|
||||
eq_match "\\(a\\|b\\)*b" "aabaab";
|
||||
eq_match "aa\\|aaa" "aaaa";
|
||||
eq_match "aaa\\|aa" "aaaa";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "Group (or submatch)" =
|
||||
eq_match "\\(a\\)\\(a\\)?\\(b\\)" "ab";
|
||||
[%expect {| |}];
|
||||
eq_match "\\(foo" "foo";
|
||||
[%expect {|
|
||||
str: (Error "Failure(\"\\\\( group not closed by \\\\)\")")
|
||||
re: (Error Re_private.Emacs.Parse_error)
|
||||
|}]
|
||||
;;
|
||||
|
||||
let%expect_test "Character set" =
|
||||
eq_match "[0-9]+" "0123456789";
|
||||
eq_match "[0-9]+" "a";
|
||||
eq_match "[9-0]+" "2";
|
||||
eq_match "[5-5]" "5";
|
||||
eq_match "[5-4]" "1";
|
||||
eq_match' "[]]" "]";
|
||||
eq_match' "[a-]" "-";
|
||||
eq_match' "[-a]" "-";
|
||||
eq_match' "]" "]";
|
||||
eq_match' "[^b-f]" "z";
|
||||
eq_match' "[^b-f]" "a";
|
||||
[%expect {||}];
|
||||
(* These errors aren't correct *)
|
||||
eq_match' "[]" "x";
|
||||
eq_match' "[" "[";
|
||||
[%expect
|
||||
{|
|
||||
str: (Error "Failure(\"[ class not closed by ]\")")
|
||||
re: (Error Re_private.Emacs.Parse_error)
|
||||
str: (Error "Failure(\"[ class not closed by ]\")")
|
||||
re: (Error Re_private.Emacs.Parse_error)
|
||||
|}]
|
||||
;;
|
||||
|
||||
let%expect_test "compl" =
|
||||
eq_match "[^0-9a-z]+" "A:Z+";
|
||||
eq_match "[^0-9a-z]+" "0";
|
||||
eq_match "[^0-9a-z]+" "a";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "Word modifiers" =
|
||||
eq_match' "\\bfoo" "foo";
|
||||
eq_match' "\\<foo" "foo";
|
||||
eq_match' "foo\\>" "foo";
|
||||
eq_match' "z\\Bfoo" "zfoo";
|
||||
eq_match' "\\`foo" "foo";
|
||||
eq_match' "foo\\'" "foo";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "Case modifiers" =
|
||||
eq_match ~case:false "abc" "abc";
|
||||
eq_match ~case:false "abc" "ABC";
|
||||
[%expect {| |}]
|
||||
;;
|
||||
|
||||
let%expect_test "global_replace" =
|
||||
global_replace "needle" "test" "needlehaystack";
|
||||
global_replace "needle" "" "";
|
||||
global_replace "needle" "" "needle";
|
||||
global_replace "xxx" "yyy" "zzz";
|
||||
global_replace "test\\([0-9]*\\)" "\\1-foo-\\1" "test100 test200 test";
|
||||
global_replace "test\\([0-9]*\\)" "'\\-0'" "test100 test200 test";
|
||||
(* Regrssion test for #129 *)
|
||||
global_replace "\\(X+\\)" "A\\1YY" "XXXXXXZZZZ";
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "bounded_split, bounded_full_split" =
|
||||
[ ",", "foo,bar,baz", 5
|
||||
; ",", "foo,bar,baz", 1
|
||||
; ",", "foo,bar,baz", 0
|
||||
; ",\\|", "foo,bar|baz", 4
|
||||
]
|
||||
|> List.iter ~f:(fun (re, s, n) ->
|
||||
bounded_full_split re s n;
|
||||
bounded_split re s n);
|
||||
[%expect {||}]
|
||||
;;
|
||||
|
||||
let%expect_test "split, full_split, split_delim" =
|
||||
[ "re", ""; " ", "foo bar"; "\b", "one-two three"; "[0-9]", "One3TwoFive" ]
|
||||
|> List.iter ~f:(fun (re, s) ->
|
||||
split re s;
|
||||
full_split re s;
|
||||
split_delim re s);
|
||||
[%expect {||}]
|
||||
;;
|
||||
Loading…
Add table
Add a link
Reference in a new issue