The unpac monorepo manager self-hosting as a monorepo using unpac

chore: port str tests to ppx_expect (#566)

authored by

Rudi Grinberg and committed by
GitHub
912e8ab9 e2308be8

+337 -373
+10
lib/dyn.ml
··· 14 14 let record fields = Record fields 15 15 let enum x = Enum x 16 16 let string s = String s 17 + 18 + let result ok err = function 19 + | Ok s -> variant "Ok" [ ok s ] 20 + | Error e -> variant "Error" [ err e ] 21 + ;; 22 + 23 + let option f = function 24 + | None -> enum "None" 25 + | Some s -> variant "Some" [ f s ] 26 + ;;
-10
lib/fmt.ml
··· 37 37 | Some i -> fprintf fmt "@ %d" i 38 38 ;; 39 39 40 - let quote fmt s = Format.fprintf fmt "\"%s\"" s 41 - 42 - let pp_olist pp_elem fmt = 43 - Format.fprintf 44 - fmt 45 - "@[<3>[@ %a@ ]@]" 46 - (pp_print_list ~pp_sep:(fun fmt () -> fprintf fmt ";@ ") pp_elem) 47 - ;; 48 - 49 40 let char fmt c = Format.fprintf fmt "%c" c 50 41 let bool = Format.pp_print_bool 51 - let pp_str_list = pp_olist quote 52 42 let lit s fmt () = pp_print_string fmt s 53 43 54 44 let to_to_string pp x =
-1
lib/fmt.mli
··· 1 1 type formatter := Format.formatter 2 2 type 'a t = formatter -> 'a -> unit 3 3 4 - val pp_str_list : string list t 5 4 val sexp : formatter -> string -> 'a t -> 'a -> unit 6 5 val str : string t 7 6 val optint : int option t
+1
lib_test/expect/dune
··· 8 8 ppx_expect.config_types 9 9 ppx_expect 10 10 base 11 + str 11 12 ppx_inline_test.config) 12 13 (inline_tests 13 14 (modes native js))
+1
lib_test/expect/import.ml
··· 1 1 module Re = Re_private.Re 2 2 include Re_private.Import 3 3 module Fmt = Re_private.Fmt 4 + module Dyn = Re_private.Dyn 4 5 5 6 let printf = Printf.printf 6 7
+325
lib_test/expect/test_str.ml
··· 1 + open Import 2 + 3 + module type Str_intf = module type of Str 4 + 5 + module Test_matches (R : Str_intf) = struct 6 + let groups () = 7 + let group i = 8 + try `Found (R.group_beginning i) with 9 + | Not_found -> `Not_found 10 + | Invalid_argument _ -> `Not_exists 11 + in 12 + let rec loop acc i = 13 + match group i with 14 + | `Found p -> loop ((p, R.group_end i) :: acc) (i + 1) 15 + | `Not_found -> loop ((-1, -1) :: acc) (i + 1) 16 + | `Not_exists -> List.rev acc 17 + in 18 + loop [] 0 19 + ;; 20 + 21 + let eq_match ?(pos = 0) ?(case = true) r s = 22 + let pat = if case then R.regexp r else R.regexp_case_fold r in 23 + try 24 + ignore (R.search_forward pat s pos); 25 + Some (groups ()) 26 + with 27 + | Not_found -> None 28 + ;; 29 + 30 + let eq_match' ?(pos = 0) ?(case = true) r s = 31 + let pat = if case then R.regexp r else R.regexp_case_fold r in 32 + try 33 + ignore (R.string_match pat s pos); 34 + Some (groups ()) 35 + with 36 + | Not_found -> None 37 + ;; 38 + end 39 + 40 + module T_str = Test_matches (Str) 41 + module T_re = Test_matches (Re.Str) 42 + 43 + let test dyn_of_ok str re args = 44 + let run f = 45 + match f () with 46 + | s -> Ok s 47 + | exception exn -> Error exn 48 + in 49 + let str = run (fun () -> str args) in 50 + let re = run (fun () -> re args) in 51 + if not (Poly.equal str re) 52 + then ( 53 + let printer x = 54 + let dyn = 55 + let open Dyn in 56 + result dyn_of_ok (fun x -> string (Printexc.to_string x)) x 57 + in 58 + sexp_of_dyn dyn |> Base.Sexp.to_string_hum 59 + in 60 + Printf.printf "str: %s\n" (printer str); 61 + Printf.printf "re: %s\n" (printer re)) 62 + ;; 63 + 64 + let dyn_of_pairs x = 65 + Dyn.option 66 + (fun x -> 67 + List.map x ~f:(fun (start, stop) -> 68 + let open Dyn in 69 + pair (int start) (int stop)) 70 + |> Dyn.list) 71 + x 72 + ;; 73 + 74 + let split_result_conv = 75 + List.map ~f:(function 76 + | Str.Delim x -> Re.Str.Delim x 77 + | Str.Text x -> Re.Str.Text x) 78 + ;; 79 + 80 + let dyn_split_result_list list = 81 + List.map 82 + list 83 + ~f: 84 + (let open Dyn in 85 + function 86 + | Re.Str.Delim x -> variant "Delim" [ string x ] 87 + | Text s -> variant "Text" [ string s ]) 88 + |> Dyn.list 89 + ;; 90 + 91 + type ('a, 'b) test = 92 + { name : string 93 + ; dyn_of_ok : 'b -> Dyn.t 94 + ; re_str : Re.Str.regexp -> 'a -> 'b 95 + ; str : Str.regexp -> 'a -> 'b 96 + } 97 + 98 + let bounded_split_t = 99 + { name = "bounded_split" 100 + ; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string)) 101 + ; re_str = (fun re (s, n) -> Re.Str.bounded_split re s n) 102 + ; str = (fun re (s, n) -> Str.bounded_split re s n) 103 + } 104 + ;; 105 + 106 + let bounded_full_split_t = 107 + { name = "bounded_full_split" 108 + ; dyn_of_ok = dyn_split_result_list 109 + ; re_str = (fun re (s, n) -> Re.Str.bounded_full_split re s n) 110 + ; str = (fun re (s, n) -> split_result_conv (Str.bounded_full_split re s n)) 111 + } 112 + ;; 113 + 114 + let full_split_t = 115 + { bounded_full_split_t with 116 + name = "full_split" 117 + ; re_str = (fun re s -> Re.Str.full_split re s) 118 + ; str = (fun re s -> split_result_conv (Str.full_split re s)) 119 + } 120 + ;; 121 + 122 + let split_delim_t = 123 + { name = "split_delim" 124 + ; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string)) 125 + ; re_str = Re.Str.split_delim 126 + ; str = Str.split_delim 127 + } 128 + ;; 129 + 130 + let split_t = 131 + { name = "split" 132 + ; dyn_of_ok = (fun x -> Dyn.list (List.map x ~f:Dyn.string)) 133 + ; re_str = Re.Str.split 134 + ; str = Str.split 135 + } 136 + ;; 137 + 138 + let global_replace_t = 139 + { name = "global_replace" 140 + ; dyn_of_ok = Dyn.string 141 + ; re_str = (fun re (r, s) -> Re.Str.global_replace re r s) 142 + ; str = (fun re (r, s) -> Str.global_replace re r s) 143 + } 144 + ;; 145 + 146 + let eq_match ?pos ?case re = 147 + test dyn_of_pairs (T_str.eq_match ?pos ?case re) (T_re.eq_match ?pos ?case re) 148 + ;; 149 + 150 + let eq_match' ?pos ?case re = 151 + test dyn_of_pairs (T_str.eq_match' ?pos ?case re) (T_re.eq_match' ?pos ?case re) 152 + ;; 153 + 154 + let test t re args = 155 + test t.dyn_of_ok (t.re_str (Re.Str.regexp re)) (t.str (Str.regexp re)) args 156 + ;; 157 + 158 + let split_delim re s = test split_delim_t re s 159 + let split re s = test split_t re s 160 + let full_split re s = test full_split_t re s 161 + let bounded_split re s n = test bounded_split_t re (s, n) 162 + let bounded_full_split re s n = test bounded_full_split_t re (s, n) 163 + let global_replace re r s = test global_replace_t re (r, s) 164 + 165 + let%expect_test "literal match" = 166 + eq_match "a" "a"; 167 + eq_match "a" "b"; 168 + [%expect {||}] 169 + ;; 170 + 171 + let%expect_test "alt" = 172 + eq_match "a\\|b" "a"; 173 + eq_match "a\\|b" "b"; 174 + eq_match "a\\|b" "c"; 175 + [%expect {||}] 176 + ;; 177 + 178 + let%expect_test "seq" = 179 + eq_match "ab" "ab"; 180 + eq_match "ab" "ac"; 181 + [%expect {||}] 182 + ;; 183 + 184 + let%expect_test "epsilon" = 185 + eq_match "" ""; 186 + eq_match "" "a"; 187 + [%expect {||}] 188 + ;; 189 + 190 + let%expect_test "rep" = 191 + eq_match "a*" ""; 192 + eq_match "a*" "a"; 193 + eq_match "a*" "aa"; 194 + eq_match "a*" "b"; 195 + [%expect {||}] 196 + ;; 197 + 198 + let%expect_test "rep1" = 199 + eq_match "a+" "a"; 200 + eq_match "a+" "aa"; 201 + eq_match "a+" ""; 202 + eq_match "a+" "b"; 203 + [%expect {| |}] 204 + ;; 205 + 206 + let%expect_test "opt" = 207 + eq_match "a?" ""; 208 + eq_match "a?" "a"; 209 + [%expect {| |}] 210 + ;; 211 + 212 + let%expect_test "bol" = 213 + eq_match "^a" "ab"; 214 + eq_match "^a" "b\na"; 215 + eq_match "^a" "ba"; 216 + [%expect {| |}] 217 + ;; 218 + 219 + let%expect_test "eol" = 220 + eq_match "a$" "ba"; 221 + eq_match "a$" "a\nb"; 222 + eq_match "a$" "ba\n"; 223 + eq_match "a$" "ab"; 224 + [%expect {| |}] 225 + ;; 226 + 227 + let%expect_test "start" = 228 + eq_match ~pos:1 "Za" "xab"; 229 + eq_match ~pos:1 "Za" "xb\na"; 230 + eq_match ~pos:1 "Za" "xba"; 231 + [%expect {||}] 232 + ;; 233 + 234 + let%expect_test "match semantics" = 235 + eq_match "\\(a\\|b\\)*b" "aabaab"; 236 + eq_match "aa\\|aaa" "aaaa"; 237 + eq_match "aaa\\|aa" "aaaa"; 238 + [%expect {||}] 239 + ;; 240 + 241 + let%expect_test "Group (or submatch)" = 242 + eq_match "\\(a\\)\\(a\\)?\\(b\\)" "ab"; 243 + [%expect {| |}] 244 + ;; 245 + 246 + let%expect_test "Character set" = 247 + eq_match "[0-9]+" "0123456789"; 248 + eq_match "[0-9]+" "a"; 249 + eq_match "[9-0]+" "2"; 250 + eq_match "[5-5]" "5"; 251 + eq_match "[5-4]" "1"; 252 + eq_match' "[]]" "]"; 253 + eq_match' "[a-]" "-"; 254 + eq_match' "[-a]" "-"; 255 + eq_match' "]" "]"; 256 + eq_match' "[^b-f]" "z"; 257 + eq_match' "[^b-f]" "a"; 258 + [%expect {||}]; 259 + (* These errors aren't correct *) 260 + eq_match' "[]" "x"; 261 + eq_match' "[" "["; 262 + [%expect 263 + {| 264 + str: (Error "Failure(\"[ class not closed by ]\")") 265 + re: (Error Re_private.Emacs.Parse_error) 266 + str: (Error "Failure(\"[ class not closed by ]\")") 267 + re: (Error Re_private.Emacs.Parse_error) 268 + |}] 269 + ;; 270 + 271 + let%expect_test "compl" = 272 + eq_match "[^0-9a-z]+" "A:Z+"; 273 + eq_match "[^0-9a-z]+" "0"; 274 + eq_match "[^0-9a-z]+" "a"; 275 + [%expect {||}] 276 + ;; 277 + 278 + let%expect_test "Word modifiers" = 279 + eq_match' "\\bfoo" "foo"; 280 + eq_match' "\\<foo" "foo"; 281 + eq_match' "foo\\>" "foo"; 282 + eq_match' "z\\Bfoo" "zfoo"; 283 + eq_match' "\\`foo" "foo"; 284 + eq_match' "foo\\'" "foo"; 285 + [%expect {||}] 286 + ;; 287 + 288 + let%expect_test "Case modifiers" = 289 + eq_match ~case:false "abc" "abc"; 290 + eq_match ~case:false "abc" "ABC"; 291 + [%expect {| |}] 292 + ;; 293 + 294 + let%expect_test "global_replace" = 295 + global_replace "needle" "test" "needlehaystack"; 296 + global_replace "needle" "" ""; 297 + global_replace "needle" "" "needle"; 298 + global_replace "xxx" "yyy" "zzz"; 299 + global_replace "test\\([0-9]*\\)" "\\1-foo-\\1" "test100 test200 test"; 300 + global_replace "test\\([0-9]*\\)" "'\\-0'" "test100 test200 test"; 301 + (* Regrssion test for #129 *) 302 + global_replace "\\(X+\\)" "A\\1YY" "XXXXXXZZZZ"; 303 + [%expect {||}] 304 + ;; 305 + 306 + let%expect_test "bounded_split, bounded_full_split" = 307 + [ ",", "foo,bar,baz", 5 308 + ; ",", "foo,bar,baz", 1 309 + ; ",", "foo,bar,baz", 0 310 + ; ",\\|", "foo,bar|baz", 4 311 + ] 312 + |> List.iter ~f:(fun (re, s, n) -> 313 + bounded_full_split re s n; 314 + bounded_split re s n); 315 + [%expect {||}] 316 + ;; 317 + 318 + let%expect_test "split, full_split, split_delim" = 319 + [ "re", ""; " ", "foo bar"; "\b", "one-two three"; "[0-9]", "One3TwoFive" ] 320 + |> List.iter ~f:(fun (re, s) -> 321 + split re s; 322 + full_split re s; 323 + split_delim re s); 324 + [%expect {||}] 325 + ;;
-7
lib_test/fort_unit/dune
··· 1 - (rule 2 - (copy %{project_root}/lib/fmt.ml fmt.ml)) 3 - 4 - (library 5 - (name fort_unit) 6 - (wrapped false) 7 - (libraries re ounit2))
-76
lib_test/fort_unit/fort_unit.ml
··· 1 - (* ounit compatibility layer for fort tests *) 2 - open OUnit2 3 - 4 - type ('a, 'b) either = 5 - | Left of 'a 6 - | Right of 'b 7 - 8 - let str_of_either f g = function 9 - | Left a -> f a 10 - | Right b -> g b 11 - ;; 12 - 13 - let try_with f = 14 - try Right (f ()) with 15 - | exn -> Left exn 16 - ;; 17 - 18 - let expect_equal_app ?printer ?msg f x g y = 19 - let fx = try_with (fun () -> f x) in 20 - let gy = try_with (fun () -> g y) in 21 - let printer = 22 - let right x = 23 - match printer with 24 - | None -> "<no printer>" 25 - | Some p -> p x 26 - in 27 - str_of_either Printexc.to_string right 28 - in 29 - assert_equal ~printer ?msg fx gy 30 - ;; 31 - 32 - let collected_tests = ref [] 33 - let id x = x 34 - let not_found () = raise Not_found 35 - let bool_printer i = Printf.sprintf "%b" i 36 - let int_printer i = Printf.sprintf "%d" i 37 - let str_printer s = "\"" ^ String.escaped s ^ "\"" 38 - let ofs_printer (i0, i1) = Printf.sprintf "(%d,%d)" i0 i1 39 - let list_printer f l = "[" ^ String.concat "; " (List.map f l) ^ "]" 40 - let arr_printer f a = "[|" ^ String.concat "; " (List.map f (Array.to_list a)) ^ "|]" 41 - 42 - let opt_printer f = function 43 - | None -> "<None>" 44 - | Some s -> "Some (" ^ f s ^ ")" 45 - ;; 46 - 47 - let arr_str_printer = arr_printer str_printer 48 - let arr_ofs_printer = arr_printer ofs_printer 49 - let list_ofs_printer = list_printer ofs_printer 50 - let fail = assert_failure 51 - let expect_eq_bool ?msg f x g y = expect_equal_app ?msg ~printer:string_of_bool f x g y 52 - let expect_eq_str ?msg f x g y = expect_equal_app ?msg ~printer:str_printer f x g y 53 - 54 - let expect_eq_str_opt ?msg f x g y = 55 - expect_equal_app ?msg ~printer:(opt_printer str_printer) f x g y 56 - ;; 57 - 58 - let expect_eq_ofs ?msg f x g y = expect_equal_app ?msg ~printer:ofs_printer f x g y 59 - 60 - let expect_eq_arr_str ?msg f x g y = 61 - expect_equal_app ?msg ~printer:arr_str_printer f x g y 62 - ;; 63 - 64 - let expect_eq_arr_ofs ?msg f x g y = 65 - expect_equal_app ?msg ~printer:arr_ofs_printer f x g y 66 - ;; 67 - 68 - let expect_eq_list_str ?msg f x g y = 69 - expect_equal_app ?msg ~printer:(list_printer str_printer) f x g y 70 - ;; 71 - 72 - let expect_pass name run = 73 - collected_tests := (name >:: fun _ -> run ()) :: !collected_tests 74 - ;; 75 - 76 - let run_test_suite suite_name = run_test_tt_main (suite_name >::: !collected_tests)
-3
lib_test/str/dune
··· 1 - (test 2 - (libraries re fort_unit str ounit2) 3 - (name test_str))
-276
lib_test/str/test_str.ml
··· 1 - open Fort_unit 2 - open OUnit2 3 - 4 - module type Str_intf = module type of Str 5 - 6 - module Test_matches (R : Str_intf) = struct 7 - let groups () = 8 - let group i = 9 - try `Found (R.group_beginning i) with 10 - | Not_found -> `Not_found 11 - | Invalid_argument _ -> `Not_exists 12 - in 13 - let rec loop acc i = 14 - match group i with 15 - | `Found p -> loop ((p, R.group_end i) :: acc) (i + 1) 16 - | `Not_found -> loop ((-1, -1) :: acc) (i + 1) 17 - | `Not_exists -> List.rev acc 18 - in 19 - loop [] 0 20 - ;; 21 - 22 - let eq_match ?(pos = 0) ?(case = true) r s = 23 - let pat = if case then R.regexp r else R.regexp_case_fold r in 24 - try 25 - ignore (R.search_forward pat s pos); 26 - Some (groups ()) 27 - with 28 - | Not_found -> None 29 - ;; 30 - 31 - let eq_match' ?(pos = 0) ?(case = true) r s = 32 - let pat = if case then R.regexp r else R.regexp_case_fold r in 33 - try 34 - ignore (R.string_match pat s pos); 35 - Some (groups ()) 36 - with 37 - | Not_found -> None 38 - ;; 39 - end 40 - 41 - module T_str = Test_matches (Str) 42 - module T_re = Test_matches (Re.Str) 43 - 44 - let eq_match ?pos ?case r s = 45 - expect_equal_app 46 - ~msg:(str_printer s) 47 - ~printer:(opt_printer (list_printer ofs_printer)) 48 - (fun () -> T_str.eq_match ?pos ?case r s) 49 - () 50 - (fun () -> T_re.eq_match ?pos ?case r s) 51 - () 52 - ;; 53 - 54 - let eq_match' ?pos ?case r s = 55 - expect_equal_app 56 - ~msg:(str_printer s) 57 - ~printer:(opt_printer (list_printer ofs_printer)) 58 - (fun () -> T_str.eq_match' ?pos ?case r s) 59 - () 60 - (fun () -> T_re.eq_match' ?pos ?case r s) 61 - () 62 - ;; 63 - 64 - let split_result_conv = 65 - List.map (function 66 - | Str.Delim x -> Re.Str.Delim x 67 - | Str.Text x -> Re.Str.Text x) 68 - ;; 69 - 70 - let pp_split_result_list = 71 - Fmt.pp_olist (fun fmt x -> 72 - let tag, arg = 73 - match x with 74 - | Re.Str.Delim x -> "Delim", x 75 - | Re.Str.Text x -> "Text", x 76 - in 77 - Fmt.fprintf fmt "%s@ (\"%s\")" tag arg) 78 - ;; 79 - 80 - let pp_fs pp_args pp_out fmt (name, re, args, ex, res) = 81 - let f fmt (mod_, r) = 82 - Fmt.fprintf fmt "%s.%s %a %a = %a" mod_ name Fmt.quote re pp_args args pp_out r 83 - in 84 - Fmt.fprintf fmt "@.%a@.%a" f ("Str", ex) f ("Re.Str", res) 85 - ;; 86 - 87 - type ('a, 'b) test = 88 - { name : string 89 - ; pp_args : 'a Fmt.t 90 - ; pp_out : 'b Fmt.t 91 - ; re_str : Re.Str.regexp -> 'a -> 'b 92 - ; str : Str.regexp -> 'a -> 'b 93 - } 94 - 95 - let bounded_split_t = 96 - { name = "bounded_split" 97 - ; pp_args = (fun fmt (s, n) -> Fmt.fprintf fmt "%a %d" Fmt.quote s n) 98 - ; pp_out = Fmt.pp_str_list 99 - ; re_str = (fun re (s, n) -> Re.Str.bounded_split re s n) 100 - ; str = (fun re (s, n) -> Str.bounded_split re s n) 101 - } 102 - ;; 103 - 104 - let bounded_full_split_t = 105 - { bounded_split_t with 106 - name = "bounded_full_split" 107 - ; pp_out = pp_split_result_list 108 - ; re_str = (fun re (s, n) -> Re.Str.bounded_full_split re s n) 109 - ; str = (fun re (s, n) -> split_result_conv (Str.bounded_full_split re s n)) 110 - } 111 - ;; 112 - 113 - let full_split_t = 114 - { bounded_full_split_t with 115 - name = "full_split" 116 - ; pp_args = (fun fmt s -> Fmt.fprintf fmt "%a" Fmt.quote s) 117 - ; re_str = (fun re s -> Re.Str.full_split re s) 118 - ; str = (fun re s -> split_result_conv (Str.full_split re s)) 119 - } 120 - ;; 121 - 122 - let split_delim_t = 123 - { full_split_t with 124 - name = "split_delim" 125 - ; pp_out = Fmt.pp_str_list 126 - ; re_str = (fun re s -> Re.Str.split_delim re s) 127 - ; str = (fun re s -> Str.split_delim re s) 128 - } 129 - ;; 130 - 131 - let split_t = 132 - { name = "split" 133 - ; pp_out = Fmt.pp_str_list 134 - ; pp_args = full_split_t.pp_args 135 - ; re_str = (fun re s -> Re.Str.split re s) 136 - ; str = (fun re s -> Str.split re s) 137 - } 138 - ;; 139 - 140 - let global_replace_t = 141 - { name = "global_replace" 142 - ; pp_out = Fmt.pp_print_string 143 - ; pp_args = (fun fmt (r, s) -> Fmt.fprintf fmt "%a %a" Fmt.quote r Fmt.quote s) 144 - ; re_str = (fun re (r, s) -> Re.Str.global_replace re r s) 145 - ; str = (fun re (r, s) -> Str.global_replace re r s) 146 - } 147 - ;; 148 - 149 - let test t re args = 150 - assert_equal 151 - ~pp_diff:(fun fmt (ex, act) -> 152 - pp_fs t.pp_args t.pp_out fmt (t.name, re, args, ex, act)) 153 - ~printer:(Fmt.to_to_string t.pp_out) 154 - (t.re_str (Re.Str.regexp re) args) 155 - (t.str (Str.regexp re) args) 156 - ;; 157 - 158 - let split_delim re s = test split_delim_t re s 159 - let split re s = test split_t re s 160 - let full_split re s = test full_split_t re s 161 - let bounded_split re s n = test bounded_split_t re (s, n) 162 - let bounded_full_split re s n = test bounded_full_split_t re (s, n) 163 - let global_replace re r s = test global_replace_t re (r, s) 164 - 165 - let _ = 166 - (* Literal Match *) 167 - expect_pass "str" (fun () -> 168 - eq_match "a" "a"; 169 - eq_match "a" "b"); 170 - (* Basic Operations *) 171 - expect_pass "alt" (fun () -> 172 - eq_match "a\\|b" "a"; 173 - eq_match "a\\|b" "b"; 174 - eq_match "a\\|b" "c"); 175 - expect_pass "seq" (fun () -> 176 - eq_match "ab" "ab"; 177 - eq_match "ab" "ac"); 178 - expect_pass "epsilon" (fun () -> 179 - eq_match "" ""; 180 - eq_match "" "a"); 181 - expect_pass "rep" (fun () -> 182 - eq_match "a*" ""; 183 - eq_match "a*" "a"; 184 - eq_match "a*" "aa"; 185 - eq_match "a*" "b"); 186 - expect_pass "rep1" (fun () -> 187 - eq_match "a+" "a"; 188 - eq_match "a+" "aa"; 189 - eq_match "a+" ""; 190 - eq_match "a+" "b"); 191 - expect_pass "opt" (fun () -> 192 - eq_match "a?" ""; 193 - eq_match "a?" "a"); 194 - (* String, line, word *) 195 - expect_pass "bol" (fun () -> 196 - eq_match "^a" "ab"; 197 - eq_match "^a" "b\na"; 198 - eq_match "^a" "ba"); 199 - expect_pass "eol" (fun () -> 200 - eq_match "a$" "ba"; 201 - eq_match "a$" "a\nb"; 202 - eq_match "a$" "ba\n"; 203 - eq_match "a$" "ab"); 204 - expect_pass "start" (fun () -> 205 - eq_match ~pos:1 "Za" "xab"; 206 - eq_match ~pos:1 "Za" "xb\na"; 207 - eq_match ~pos:1 "Za" "xba"); 208 - (* Match semantics *) 209 - expect_pass "match semantics" (fun () -> 210 - eq_match "\\(a\\|b\\)*b" "aabaab"; 211 - eq_match "aa\\|aaa" "aaaa"; 212 - eq_match "aaa\\|aa" "aaaa"); 213 - (* Group (or submatch) *) 214 - 215 - (* TODO: infinite loop *) 216 - expect_pass "group" (fun () -> eq_match "\\(a\\)\\(a\\)?\\(b\\)" "ab"); 217 - (* Character set *) 218 - expect_pass "rg" (fun () -> 219 - eq_match "[0-9]+" "0123456789"; 220 - eq_match "[0-9]+" "a"; 221 - eq_match "[9-0]+" "2"; 222 - eq_match "[5-5]" "5"; 223 - eq_match "[5-4]" "1"; 224 - eq_match' "[]]" "]"; 225 - eq_match' "[a-]" "-"; 226 - eq_match' "[-a]" "-"; 227 - eq_match' "]" "]"; 228 - eq_match' "[^b-f]" "z"; 229 - eq_match' "[^b-f]" "a" 230 - (* These errors aren't correct *) 231 - (* eq_match' "[]" "x" *) 232 - (* eq_match' "[" "[" *)); 233 - expect_pass "compl" (fun () -> 234 - eq_match "[^0-9a-z]+" "A:Z+"; 235 - eq_match "[^0-9a-z]+" "0"; 236 - eq_match "[^0-9a-z]+" "a"); 237 - (* Word modifiers *) 238 - expect_pass "word boundaries" (fun () -> 239 - eq_match' "\\bfoo" "foo"; 240 - eq_match' "\\<foo" "foo"; 241 - eq_match' "foo\\>" "foo"; 242 - eq_match' "z\\Bfoo" "zfoo"; 243 - eq_match' "\\`foo" "foo"; 244 - eq_match' "foo\\'" "foo"); 245 - (* Case modifiers *) 246 - expect_pass "no_case" (fun () -> 247 - eq_match ~case:false "abc" "abc"; 248 - eq_match ~case:false "abc" "ABC"); 249 - expect_pass "global_replace" (fun () -> 250 - global_replace "needle" "test" "needlehaystack"; 251 - global_replace "needle" "" ""; 252 - global_replace "needle" "" "needle"; 253 - global_replace "xxx" "yyy" "zzz"; 254 - global_replace "test\\([0-9]*\\)" "\\1-foo-\\1" "test100 test200 test"; 255 - global_replace "test\\([0-9]*\\)" "'\\-0'" "test100 test200 test"; 256 - (* Regrssion test for #129 *) 257 - global_replace "\\(X+\\)" "A\\1YY" "XXXXXXZZZZ"); 258 - expect_pass "bounded_split, bounded_full_split" (fun () -> 259 - List.iter 260 - (fun (re, s, n) -> 261 - bounded_full_split re s n; 262 - bounded_split re s n) 263 - [ ",", "foo,bar,baz", 5 264 - ; ",", "foo,bar,baz", 1 265 - ; ",", "foo,bar,baz", 0 266 - ; ",\\|", "foo,bar|baz", 4 267 - ]); 268 - expect_pass "split, full_split, split_delim" (fun () -> 269 - List.iter 270 - (fun (re, s) -> 271 - split re s; 272 - full_split re s; 273 - split_delim re s) 274 - [ "re", ""; " ", "foo bar"; "\b", "one-two three"; "[0-9]", "One3TwoFive" ]); 275 - run_test_suite "test_str" 276 - ;;