Current section
Files
Jump to
Current section
Files
lib/nldoc/test/logs.ex
defmodule NLdoc.Test.Logs do
@moduledoc """
This module helps with capturing log output in tests.
"""
@doc """
Captures logs produced by the given function and returns them as a string.
The logs could be formatted using the formatter settings as set in `config/config.exs`,
`config/config_test.exs` plus what is configured at runtime. By default, that means
the logs could be formatted as Elastic Common Schema (ECS) JSON. Use `decode/1` to
JSON decode the logs.
## Examples
iex> require Logger
iex> logs = :info |> NLdoc.Test.Logs.capture(fn -> Logger.info("Hello") end)
iex> logs |> String.contains?("[info] Hello")
true
"""
@spec capture(Logger.level(), (-> any())) :: String.t()
def capture(level \\ :debug, fun) do
current_level = Logger.level()
try do
Logger.configure(level: level)
ExUnit.CaptureIO.capture_io(:user, fn ->
fun.()
Logger.flush()
end)
after
Logger.configure(level: current_level)
end
end
@doc """
Captures logs produced by the given function and returns them as a string,
alongside the return value of the given function.
The logs could be formatted using the formatter settings as set in `config/config.exs`,
`config/config_test.exs` plus what is configured at runtime. By default, that means
the logs could be formatted as Elastic Common Schema (ECS) JSON. Use `decode/1` to
JSON decode these logs.
## Examples
iex> require Logger
iex> {result, logs} = NLdoc.Test.Logs.with_capture(:info, fn ->
...> Logger.info("Hello")
...> 2 + 2
...> end)
iex> result
4
iex> logs |> String.contains?("[info] Hello")
true
"""
@spec with_capture(Logger.level(), (-> return)) :: {return, String.t()} when return: var
def with_capture(level \\ :debug, fun) do
current_level = Logger.level()
try do
Logger.configure(level: level)
ExUnit.CaptureIO.with_io(:user, fn ->
return = fun.()
Logger.flush()
return
end)
after
Logger.configure(level: current_level)
end
end
@doc """
Decodes each line in the given log string with `Jason.decode/1`.
## Examples
iex> logs = "{\\"message\\": \\"test\\"}\\n{\\"message\\": \\"another test\\"}\\n\\n"
iex> logs |> NLdoc.Test.Logs.decode()
[%{"message" => "test"}, %{"message" => "another test"}]
iex> [%{"message" => "test"}] |> match?(logs |> NLdoc.Test.Logs.decode())
"""
@spec decode(String.t()) :: [map()]
def decode(logs) do
logs |> String.split("\n", trim: true) |> Enum.map(&Jason.decode!/1)
end
end