chat
This commit is contained in:
parent
646afaad64
commit
cb8dddc326
@ -57438,3 +57438,141 @@ defmodule TupleTestHelpers do
|
||||
|
||||
> Tokens: 25k sent, 457 received. Cost: $0.04 message, $0.08 session.
|
||||
> Applied edit to test.exs
|
||||
|
||||
#### /clear
|
||||
|
||||
#### /ask I've got a problem with debugging this thing. In some test cases I need to access a detailed trace of whats going on. Most of the time I don't care, because they pass. We need to add detailed logs which i can enable only for a select test case via a Process switch. Lets design it
|
||||
|
||||
#### I've got a problem with debugging this thing. In some test cases I need to access a detailed trace of whats going on. Most of the time I don't care, because they pass. We need to add detailed logs which i can enable only for a select test case via a Process switch. Lets design it
|
||||
|
||||
Okay, let's design a conditional logging mechanism for detailed tracing.
|
||||
|
||||
**Design Proposal: Conditional Debug Tracing**
|
||||
|
||||
We'll introduce a tracing facility within the existing `Tdd.Debug` module. This facility will be controlled by a flag in the process dictionary, allowing tests to enable detailed logging on demand.
|
||||
|
||||
**1. Control Mechanism (in `Tdd.Debug` module):**
|
||||
|
||||
* **Process Flag:** A key, for example, `@trace_flag :tdd_debug_trace_enabled`, will be used with `Process.put/2` and `Process.get/2`.
|
||||
* **Control Functions:**
|
||||
* `enable_trace/0`: Sets the process flag to `true`.
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
@trace_flag :tdd_debug_trace_enabled
|
||||
def enable_trace, do: Process.put(@trace_flag, true)
|
||||
```
|
||||
* `disable_trace/0`: Sets the process flag to `false` (or removes it).
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
def disable_trace, do: Process.put(@trace_flag, false)
|
||||
```
|
||||
* `trace_enabled?/0`: Checks the state of the flag. This can be private if only used by the macros.
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
defp trace_enabled?, do: Process.get(@trace_flag, false) == true
|
||||
```
|
||||
|
||||
**2. Logging Macros (in `Tdd.Debug` module):**
|
||||
|
||||
To ensure that potentially expensive operations (like data inspection or string formatting) are only performed when tracing is active, the macros will accept zero-arity functions that produce the content to be logged.
|
||||
|
||||
* `dlog_msg(message_producer_fun)`: For logging simple string messages.
|
||||
* `message_producer_fun`: A `fn -> "message string" end`.
|
||||
* *Behavior*: If tracing is enabled, it executes `message_producer_fun.()` and prints the result using `IO.puts/1`.
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
defmacro dlog_msg(message_producer_fun) do
|
||||
quote do
|
||||
if Tdd.Debug.trace_enabled?() do
|
||||
IO.puts(unquote(message_producer_fun).())
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
* `dlog(label, data_producer_fun)`: For inspecting data with a label.
|
||||
* `label`: An atom or string for `IO.inspect/2`.
|
||||
* `data_producer_fun`: A `fn -> data_to_inspect end`.
|
||||
* *Behavior*: If tracing is enabled, it executes `data_producer_fun.()` and inspects the result using `IO.inspect(result, label: label)`.
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
defmacro dlog(label, data_producer_fun) do
|
||||
quote do
|
||||
if Tdd.Debug.trace_enabled?() do
|
||||
IO.inspect(unquote(data_producer_fun).(), label: unquote(label))
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
* `dlog_action(action_producer_fun)`: For executing an action (like calling `Tdd.Debug.print/1`) only when tracing is enabled.
|
||||
* `action_producer_fun`: A `fn -> perform_io_action() end`.
|
||||
* *Behavior*: If tracing is enabled, it executes `action_producer_fun.()`.
|
||||
```elixir
|
||||
# In Tdd.Debug
|
||||
defmacro dlog_action(action_producer_fun) do
|
||||
quote do
|
||||
if Tdd.Debug.trace_enabled?() do
|
||||
unquote(action_producer_fun).()
|
||||
:ok # Ensure the macro expression has a consistent return value
|
||||
end
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
**3. Usage Example:**
|
||||
|
||||
* **In a specific test case:**
|
||||
```elixir
|
||||
defmodule MyProblematicTest do
|
||||
use ExUnit.Case
|
||||
alias Tdd.Debug
|
||||
|
||||
setup do
|
||||
Debug.enable_trace()
|
||||
on_exit(fn -> Debug.disable_trace() end) # Ensure cleanup
|
||||
:ok
|
||||
end
|
||||
|
||||
test "scenario requiring detailed trace" do
|
||||
# ... test code that calls into TDD modules ...
|
||||
assert true # placeholder
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
* **In core logic (e.g., `Tdd.Compiler.loop_until_stable/3`):**
|
||||
The existing `IO.puts` and `IO.inspect` calls can be converted.
|
||||
```elixir
|
||||
# In Tdd.Compiler, after aliasing or requiring Tdd.Debug
|
||||
# alias Tdd.Debug
|
||||
|
||||
defp loop_until_stable(prev_id, step_function, iteration \\ 0) do
|
||||
Debug.dlog_msg(fn -> "\n--- Fixed-Point Iteration: #{iteration} ---" end)
|
||||
Debug.dlog("prev_id", fn -> prev_id end)
|
||||
Debug.dlog_action(fn -> Tdd.Debug.print(prev_id) end) # For detailed graph view
|
||||
|
||||
raw_next_id = step_function.(prev_id)
|
||||
Debug.dlog("raw_next_id (after step_function)", fn -> raw_next_id end)
|
||||
Debug.dlog_action(fn -> Tdd.Debug.print(raw_next_id) end)
|
||||
|
||||
next_id = Algo.simplify(raw_next_id)
|
||||
Debug.dlog("next_id (after simplify)", fn -> next_id end)
|
||||
Debug.dlog_action(fn -> Tdd.Debug.print(next_id) end)
|
||||
|
||||
if next_id == prev_id do
|
||||
Debug.dlog_msg(fn -> "--- Fixed-Point Reached! ---" end)
|
||||
next_id
|
||||
else
|
||||
# ... existing safety break and recursive call ...
|
||||
if iteration > 2 do # Example existing condition
|
||||
# ...
|
||||
end
|
||||
loop_until_stable(next_id, step_function, iteration + 1)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
This design provides a flexible way to get detailed traces for specific scenarios without affecting the performance or output of regular test runs. The use of functions ensures lazy evaluation of potentially costly debug message formatting.
|
||||
|
||||
> Tokens: 32k sent, 1.3k received. Cost: $0.05 message, $0.12 session.
|
||||
|
||||
@ -4185,3 +4185,9 @@
|
||||
|
||||
# 2025-06-16 11:51:48.065221
|
||||
+n
|
||||
|
||||
# 2025-06-19 10:22:37.019564
|
||||
+/clear
|
||||
|
||||
# 2025-06-19 10:25:14.825350
|
||||
+/ask I've got a problem with debugging this thing. In some test cases I need to access a detailed trace of whats going on. Most of the time I don't care, because they pass. We need to add detailed logs which i can enable only for a select test case via a Process switch. Lets design it
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user