The Journal: comparing runs
Comparing finds what separates the runs that fail from the ones that pass, without reading any one run's story first. This lesson records all four of Orders' scenarios, then compares the one that fails with one that passes. Read Orders.ek9 first. To play it in the IDE: Help > Lessons > Debugging and the Journal…, or ek9 -ide -lesson journal-comparing.
Start from
The code the lesson starts from: copy it into a file of your own and follow the steps.
Orders.ek9
#!ek9 <?- debug-journal / orders: a defect that shows itself late. An order's total goes negative only when a refund FOLLOWS a discount: the refund is taken from what is left to pay (the discounted total) rather than from what was paid. Nothing fails at the refund; the invoice, later, refuses a negative total with a Panic. Scenario: 1 add, 2 +discount, 3 +discount +refund (fails), 4 +refund (passes). -?> defines module live.orders defines constant NOTHING <- 0 PERCENT <- 100 PRICE <- 100 HALF <- 50 REFUNDED <- 80 DISCOUNTS <- 2 REFUNDS <- 3 defines class Order total as Integer: 0 add() -> amount as Integer total += amount discount() -> percent as Integer saving <- total * percent / PERCENT total -= saving invoice() <- rtn as String? require total >= NOTHING rtn: `invoice for ${total}` refund() -> amount as Integer total -= amount default operator ? defines program Orders() -> scenario as Integer stdout <- Stdout() order <- Order() order.add(PRICE) if scenario == DISCOUNTS or scenario == REFUNDS order.discount(HALF) if scenario >= REFUNDS order.refund(REFUNDED) stdout.println(order.invoice()) //EOF
dev/orders_tests.ek9
#!ek9 <?- debug-journal / orders: the tests, for trying coverage in the IDE (-t, the coverage toggle Alt+Cmd+F6). They cover adding, a discount alone and a refund alone - each passes. The defect path (a refund AFTER a discount, which the invoice refuses with a Panic) and the Orders program itself are deliberately left untested, so coverage shows what the tests do not reach. -?> defines module live.orders.tests references live.orders::HALF live.orders::Order live.orders::PRICE live.orders::REFUNDED defines constant FULL_PRICE <- "invoice for 100" HALF_PRICE <- "invoice for 50" PRICE_LESS_REFUND <- "invoice for 20" defines program @Test AddOnly() order <- Order() order.add(PRICE) assert order.invoice() == FULL_PRICE @Test HalfDiscount() order <- Order() order.add(PRICE) order.discount(HALF) assert order.invoice() == HALF_PRICE @Test RefundWithoutDiscount() order <- Order() order.add(PRICE) order.refund(REFUNDED) assert order.invoice() == PRICE_LESS_REFUND //EOF
Step 1: A program with passing and failing runs
Orders runs scenario 1, 2, 3 or 4: an add, then (scenario 2 or 3) a discount, then (scenario 3 or 4) a refund. Scenario 3 - discount, then refund - is the only one that fails: the refund is taken from the discounted total, and the invoice refuses the negative result.
Step 2: Record several runs
Choose Run > New Journal Investigation…
Watch Order.total, and give all four scenarios - one input set per line: 1, 2, 3, 4. Choose Start.
The program runs four times, once per scenario, while the Journal records every change to Order.total. Three pass; scenario 3 fails - and all four show in the Journal tab, already selected and compared.
Step 3: Choose two to compare
Click the FAIL run (scenario 3) to select it alone, then ⌘-click the pass run for scenario 1: now exactly those two are selected, and compared - not all four.
Step 4: What only the failing run did
The side by side lines up the failing run against the passing one, step by step. "not in this run" under pass, for the discount and the refund, is what only the failing run did - read from the top: the add is the same in both, then the failing run alone discounts and refunds.
Step 5: The Journal Report
Choose Report…
Say what you think is wrong - citing the step and line that show it - and choose Write Report. It opens as a page: what was run, how each run ended, and the two side by side - with report.json beside it for a model to read.
The result
That is comparing: choose the runs, read what separates them, and hand the report to someone who has not seen the IDE. Trying a variation of one run - without filling the whole dialog again - is the next lesson.
Where this lesson comes from
- For AI assistants - the MCP tool
ek9_debug_inspect.









