aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/control/remember.lux
blob: 5ad579363ecc3543dc8ca18bf565210db7926475 (plain)
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
(.require
 [library
  [lux (.except)
   ["_" test (.only Test)]
   [abstract
    ["[0]" monad (.only do)]]
   [control
    ["[0]" io]
    ["[0]" try (.only Try)]
    ["[0]" exception]]
   [data
    ["[0]" product]
    ["[0]" text (.only)
     ["%" \\format (.only format)]]]
   [math
    [number (.only hex)]
    ["[0]" random (.only Random) (.use "[1]#[0]" monad)]]
   ["[0]" meta (.only)
    ["[0]" code (.only)
     ["<[1]>" \\parser]]
    [macro
     ["[0]" syntax (.only syntax)]
     ["[0]" expansion]]]
   [world
    [time
     ["[0]" date (.only Date)]
     ["[0]" instant]
     ["[0]" duration]]]]]
 [\\library
  ["[0]" /]])

(def deadline (Random Date) random.date)
(def message (Random Text) (random#each %.bit random.bit))
(def focus (Random Code) (random#each code.bit random.bit))

(def (memory macro deadline message focus)
  (-> Symbol Date Text (Maybe Code) Code)
  (` ((, (code.symbol macro))
      (, (code.text (%.date deadline)))
      (, (code.text message))
      (,* (case focus
            {.#None} (list)
            {.#Some focus} (list focus))))))

(def (attempt computation)
  (All (_ a) (-> (Meta a) (Meta (Try a))))
  (function (_ compiler)
    (case (computation compiler)
      {try.#Success [compiler output]}
      {try.#Success [compiler {try.#Success output}]}

      {try.#Failure error}
      {try.#Success [compiler {try.#Failure error}]})))

(def (test_failure deadline message focus failure)
  (-> Date Text (Maybe Code) Text Bit)
  (and (text.contains? (%.date deadline) failure)
       (text.contains? message failure)
       (case focus
         {.#None}
         true
         
         {.#Some focus}
         (text.contains? (%.code focus) failure))))

(def test_macro
  (syntax (_ [macro <code>.symbol
              extra <code>.text])
    (let [now (io.run! instant.now)
          today (instant.date now)
          yesterday (instant.date (instant.after (duration.inverse duration.week) now))
          tomorrow (instant.date (instant.after duration.week now))
          prng (random.pcg_32 [(hex "0123456789ABCDEF")
                               (instant.millis now)])
          message (product.right (random.result prng ..message))
          expected (product.right (random.result prng ..focus))]
      (do meta.monad
        [should_fail0 (..attempt (expansion.complete (..memory macro yesterday message {.#None})))
         should_fail1 (..attempt (expansion.complete (..memory macro yesterday message {.#Some expected})))
         should_succeed0 (..attempt (expansion.complete (..memory macro tomorrow message {.#None})))
         should_succeed1 (..attempt (expansion.complete (..memory macro tomorrow message {.#Some expected})))]
        (in (list (code.bit (and (case should_fail0
                                   {try.#Failure error}
                                   (and (test_failure yesterday message {.#None} error)
                                        (text.contains? extra error))

                                   _
                                   false)
                                 (case should_fail1
                                   {try.#Failure error}
                                   (and (test_failure yesterday message {.#Some expected} error)
                                        (text.contains? extra error))

                                   _
                                   false)
                                 (case should_succeed0
                                   {try.#Success (list)}
                                   true

                                   _
                                   false)
                                 (case should_succeed1
                                   {try.#Success (list actual)}
                                   (same? expected actual)

                                   _
                                   false)
                                 ))))))))

(def .public test
  Test
  (<| (_.covering /._)
      (do random.monad
        [deadline ..deadline
         message ..message
         focus ..focus]
        (all _.and
             (_.coverage [/.must_remember]
               (and (test_failure deadline message {.#None}
                                  (exception.error /.must_remember [deadline deadline message {.#None}]))
                    (test_failure deadline message {.#Some focus}
                                  (exception.error /.must_remember [deadline deadline message {.#Some focus}]))))
             (_.coverage [/.remember]
               (..test_macro /.remember ""))
             (_.coverage [/.to_do]
               (..test_macro /.to_do "TODO"))
             (_.coverage [/.fix_me]
               (..test_macro /.fix_me "FIXME"))
             ))))