package commons

  1. Overview
  2. Docs
Yet another set of common utilities

Install

Dune Dependency

Authors

Maintainers

Sources

commons_1.8.0.tar.gz
md5=00142d2d5f299c86ee44f19820bf9874
sha512=d25a57c434514ecb9adc5a129eeec9feca1cea2d1383e3bde74b52a05da174a09e0f46e7407f7b86ecdf1bf6faf7e0a66ef744d6fb389cb5f8398bc32e349555

doc/src/commons.tests/Unit_commons.ml.html

Source file Unit_commons.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
(*
   Test suite for this folder.
*)

open Printf

(*
   This only checks the correctness of the results of the map function.
   For a benchmark, we could use and adapt
   https://gist.github.com/mjambon/95cfc818b7d2cb93fe5212495c3ab885

   We check:
   - correctness of the map result
   - left-to-right order
*)
let test_common_map =
  let list_lengths =
    [
      0;
      1;
      2;
      3;
      4;
      5;
      6;
      7;
      8;
      9;
      10;
      (* Lengths over the threshold beyond which the implementation switches
         to not using the stack. *)
      10_000;
      10_001;
      10_002;
      10_003;
      10_004;
      10_005;
    ]
  in
  let test len =
    let input = List.init len (fun i -> i) in
    let f x = x + 1 in
    let acc = ref [] in
    let expected_output = List.map f input in
    let output =
      Common.map
        (fun x ->
          let res = f x in
          acc := res :: !acc;
          res)
        input
    in
    let order = List.rev !acc in
    assert (output = expected_output);
    assert (order = expected_output)
  in
  let tests =
    List.map
      (fun len ->
        let name = sprintf "list length = %i" len in
        let test () = test len in
        (name, test))
      list_lengths
  in
  tests

(*
   Check that both Windows (CRLF) and Unix line endings (LF) are removed
   when reading a line. This is a problem with Stdlib.input_line, which
   leaves a trailing '\r' when reading a file from Windows.
*)
let test_cat () =
  let contents = "hello\r\nworld\n!" in
  let file = Filename.temp_file "test_cat_" ".txt" in
  let oc = open_out_bin file in
  output_string oc contents;
  close_out oc;
  match Common.cat file with
  | [ "hello"; "world"; "!" ] -> ()
  | lines ->
      List.iteri (fun i line -> eprintf "line %i: %S\n" i line) lines;
      flush stderr;
      assert false

let test_readable () =
  Alcotest.(check string)
    "same string" "Bar.java"
    (Common.readable ~root:"." "./Bar.java");
  Alcotest.(check string)
    "same string" "Bar.java"
    (Common.readable ~root:"." "Bar.java");
  Alcotest.(check string)
    "same string" "a/b/Bar.java"
    (Common.readable ~root:"." "a/b/Bar.java");
  Alcotest.(check string)
    "same string" "Bar.java"
    (Common.readable ~root:"/a/b/" "/a/b/Bar.java");
  Alcotest.(check string)
    "same string" "Bar.java"
    (Common.readable ~root:"/a/b/" "/a/b//Bar.java");
  ()

let with_file contents f =
  let file, oc = Filename.open_temp_file "test_pfff_read_file_" ".dat" in
  Fun.protect
    ~finally:(fun () ->
      close_out_noerr oc;
      Sys.remove file)
    (fun () ->
      output_string oc contents;
      close_out oc;
      f file)

(* We don't have tests for reading from named pipes (FIFO) because it would
   too complicated (involves two processes) and name pipes are useful mostly
   with Bash's process substitution feature.
*)
let test_read_file () =
  (* test file smaller than one filesystem block (most likely) *)
  let data = String.make 200 'A' in
  with_file data (fun file -> assert (Common.read_file file = data));
  (* test file larger than one filesystem block (most likely) *)
  let data = String.make 100_000 'A' in
  with_file data (fun file -> assert (Common.read_file file = data));
  (* test empty file *)
  let data = "" in
  with_file data (fun file -> assert (Common.read_file file = data));
  (* test partial read *)
  let data = String.make 8192 'A' in
  let max_len = 100 in
  with_file data (fun file ->
      assert (Common.read_file ~max_len file = String.sub data 0 max_len));
  (* test 0-length read *)
  let data = String.make 8192 'A' in
  let max_len = 0 in
  with_file data (fun file ->
      assert (Common.read_file ~max_len file = String.sub data 0 max_len))

let tests =
  Testutil.pack_suites "commons"
    [
      Testutil.pack_suites "common"
        [
          Testutil.pack_tests "map" test_common_map;
          [ ("cat", test_cat) ];
          [ ("readable", test_readable) ];
          [ ("read_file", test_read_file) ];
        ];
    ]
OCaml

Innovation. Community. Security.