lib.debug.throwTestFailures: init

`lib.debug.runTests` provides a unit test evaluator for Nix, but its
results are returned in a raw and difficult-to-read form.

Currently, different callers output the results in various ways:
`builtins.throw (builtins.toJSON failures)` and `builtins.throw ("Tests
failed: " + lib.generators.toPretty { } failures)` are both used.

This change adds a new `lib.debug.throwTestFailures` function which
displays the results nicely before throwing an exception (or returns
`null` if no failures are given), unifying these disparate call-sites.

First, each failing test is pretty-printed in a `trace` message:

```
trace: FAIL testDerivation:
  Expected: <derivation a>
    Result: <derivation b>
```

Then, an exception is thrown containing the number of tests that failed
(and their names), followed by the raw JSON of the results (for parity
with previous usage, and because `lib.generators.toPretty` sometimes
omits information that `builins.toJSON` includes):

```
error:
       … while evaluating the file '...':

       … caused by explicit throw
         at /nix/store/.../lib/debug.nix:528:7:
          527|       in
          528|       throw (
             |       ^
          529|         builtins.seq traceFailures (

       error: 1 tests failed:
       - testDerivation

       [{"expected":"/nix/store/xh7kyqp69mxkwspmi81a94m9xx74r8dr-a","name":"testDerivation","result":"/nix/store/503l84nir4zw57d1shfhai25bxxn16c6-b"}]
```
This commit is contained in:
Rebecca Turner
2025-06-12 10:30:07 -07:00
parent 975870c486
commit dc4cf16993
5 changed files with 164 additions and 13 deletions

View File

@@ -15,7 +15,7 @@ let
# This is not allowed generally, but we're in the tests here, so we'll allow ourselves.
storeDirPath = /. + builtins.storeDir;
cases = lib.runTests {
failures = lib.runTests {
# Test examples from the lib.path.append documentation
testAppendExample1 = {
expr = append /foo "bar/baz";
@@ -326,7 +326,6 @@ let
};
};
in
if cases == [ ] then
"Unit tests successful"
else
throw "Path unit tests failed: ${lib.generators.toPretty { } cases}"
lib.debug.throwTestFailures {
inherit failures;
}