Better diff function for runTest

When running runTest and having failures, I’m having a hard time reading the output. One improvement IMO is providing an actual diff between the result and expected attributes. The following runTest function provides a very crude diff for strings. An example:

With the following:

runTests {
  testDiffSame = {
    expr = "abdef";
    expected = "abcccef";
  };
}

It outputs:

{ commonPrefix = "ab";
  commonSuffix = "ef";
  expected = "[... 2 omitted]ccc[... 2 omitted]";
  name = "testDiffSame";
  result = "[... 2 omitted]d[... 2 omitted]";
}

The function is:

  diff = testResult:
    with builtins;
    with lib.strings;
    if isString testResult.expected && isString testResult.result then
      let
        p = commonPrefixLength testResult.expected testResult.result;
        s = commonSuffixLength testResult.expected testResult.result;
        expectedSuffixLen = stringLength testResult.expected - s - p;
        resultSuffixLen = stringLength testResult.result - s - p;
        expectedDiff = substring p expectedSuffixLen testResult.expected;
        resultDiff = substring p resultSuffixLen testResult.result;
        omitted = len: if len == 0 then "" else "[... ${toString len} omitted]";
      in
        {inherit (testResult) name;
         commonPrefix = substring 0 p testResult.expected;
         commonSuffix = substring (stringLength testResult.expected - s) s testResult.expected;
         expected = "${omitted p}${expectedDiff}${omitted s}";
         result = "${omitted p}${resultDiff}${omitted s}";
        }
    else testResult;

  runTests = x: map diff (lib.runTests x);

If it interests anyone, I’d love to make a PR to make it available in nixpkgs somewhere.

1 Like