package bonsai

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file test_linter.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
open! Core
open! Import
open Bonsai.Let_syntax
open Bonsai.For_open
module Private = Bonsai.Private

(* Each test sets this ref to the location at which the test began, so that
   test output can be made resilient to adding or remove lines above the test. *)
let test_location_reference_point = ref [%here]
let test_start here = test_location_reference_point := here

let test_lint computation =
  let computation = Private.reveal_computation computation in
  List.iter (Private.Linter.list_warnings computation) ~f:(fun warning ->
    print_endline
      (Private.Linter.Warning.to_string
         (Private.Linter.Warning.relative_to !test_location_reference_point warning)))
;;

let constant_fold computation =
  computation
  |> Private.reveal_computation
  |> Private.Constant_fold.constant_fold
  |> Private.conceal_computation
;;

let%expect_test "map2_unfolded_constant_warnings" =
  test_start [%here];
  let c =
    let%arr a = Value.return 5
    and b = Value.return 3 in
    a + b
  in
  test_lint c;
  [%expect {|
    lib/bonsai/test/test_linter.ml:2:4: unfolded constant |}]
;;

let%expect_test "map2_optimized_gets_no_warnings" =
  test_start [%here];
  let c =
    let%arr a = Value.return 5
    and b = Value.return 3 in
    a + b
  in
  test_lint (constant_fold c);
  [%expect {| |}]
;;

let%expect_test "map2_two_unfolded_constants_warnings" =
  test_start [%here];
  let sum =
    let%map a = Value.return 5
    and b = Value.return 3 in
    a + b
  in
  let doubled =
    let%arr a = sum
    and b = sum in
    a + b
  in
  test_lint doubled;
  [%expect {| lib/bonsai/test/test_linter.ml:7:4: unfolded constant |}]
;;

let%expect_test "cutoff_unfolded_constants_warnings" =
  test_start [%here];
  let cutoff = return (Bonsai.Value.cutoff ~equal:( = ) (Value.return 3)) in
  test_lint cutoff;
  [%expect {| _none_:0:0: unfolded constant |}]
;;

let%expect_test "cutoff_optimized_gets_no_warnings" =
  test_start [%here];
  let cutoff = return (Value.cutoff ~equal:( = ) (Value.return 3)) in
  test_lint (constant_fold cutoff);
  [%expect {| |}]
;;

let%expect_test "sm1_with_const_input_gets_warning" =
  test_start [%here];
  let state_machine =
    Bonsai.state_machine1
      (module Int)
      (module Int)
      ~default_model:0
      ~apply_action:(fun ~inject:_ ~schedule_event:_ _ _ _ -> 3)
      (Value.return 5)
  in
  test_lint state_machine;
  [%expect {| _none_:0:0: state_machine1 can be optimized to a state_machine0 |}]
;;

let%expect_test "sm1_optimized_gets_no_warnings" =
  test_start [%here];
  let state_machine =
    Bonsai.state_machine1
      (module Int)
      (module Int)
      ~default_model:0
      ~apply_action:(fun ~inject:_ ~schedule_event:_ _ _ _ -> 3)
      (Value.return 5)
  in
  test_lint (constant_fold state_machine);
  [%expect {| |}]
;;

let%expect_test "map2_with_unfolded_constants_and_sm1_with_const_input_both_warned" =
  test_start [%here];
  let c =
    let%sub value, _inject =
      Bonsai.state_machine1
        (module Int)
        (module Int)
        ~default_model:0
        ~apply_action:(fun ~inject:_ ~schedule_event:_ _ _ _ -> 3)
        (Value.return 5)
    in
    let%arr value = value
    and sum =
      let%map a = Value.return 5
      and b = Value.return 3 in
      a + b
    in
    value + sum
  in
  test_lint c;
  [%expect
    {|
    lib/bonsai/test/test_linter.ml:2:4: state_machine1 can be optimized to a state_machine0
    lib/bonsai/test/test_linter.ml:10:4: unfolded constant |}]
;;
OCaml

Innovation. Community. Security.