0 | ||| In-memory logging for testing.
 1 | |||
 2 | ||| `TestLog` captures log messages in an `IORef` so tests can assert
 3 | ||| on what was logged without IO side effects like writing to stdout.
 4 | module Log4Types.Core.TestLog
 5 |
 6 | import Data.IORef
 7 | import Log4Types.Core.Action
 8 |
 9 | %default total
10 |
11 | ||| An in-memory log sink that accumulates messages.
12 | public export
13 | record TestLog (msg : Type) where
14 |   constructor MkTestLog
15 |   messages : IORef (List msg)
16 |
17 | ||| Create a new empty TestLog.
18 | public export
19 | newTestLog : HasIO io => io (TestLog msg)
20 | newTestLog = MkTestLog <$> newIORef []
21 |
22 | ||| Retrieve captured messages in the order they were logged.
23 | public export
24 | getMessages : HasIO io => TestLog msg -> io (List msg)
25 | getMessages tl = reverse <$> readIORef tl.messages
26 |
27 | ||| A LogAction that appends messages to a TestLog.
28 | public export
29 | testLogAction : HasIO io => TestLog msg -> LogAction io msg
30 | testLogAction tl = MkLogAction $ \msg => modifyIORef tl.messages (msg ::)
31 |
32 | ||| Create a TestLog, run an action with it, and return captured messages.
33 | public export
34 | withTestLog : HasIO io => (LogAction io msg -> io a) -> io (a, List msg)
35 | withTestLog f = do
36 |   tl <- newTestLog
37 |   result <- f (testLogAction tl)
38 |   msgs <- getMessages tl
39 |   pure (result, msgs)
40 |