From 3ee8e45f8e28c90547e438b47f0d0bcda7fe6237 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Fri, 7 Nov 2025 00:27:39 +0100 Subject: [PATCH] tests: Replace fragile genericClosure unit tests We now have functional tests for these. The unit tests added negligible value while imposing a much higher maintenance cost. The maintenance cost is high: - No automatic accept option - They broke 5+ times during this session due to implementation changes (trace count, ordering) - They require understanding ANSI escape codes, Uncolored() wrappers, trace reversal - They test empty traces HintFmt("") from withTrace(pos, "") - pure implementation detail - They're fragile: adding any trace anywhere breaks the exact count assertions The additional value over functional tests is minimal: - Functional tests already verify the error message - Functional tests already show trace order and content (as users see it, helps review) - Unit tests verify "exactly 3 traces, not 2 or 4" - but users don't count traces - Unit tests verify empty traces exist - but users never see them The white-box testing catches the wrong things: - It catches "you added helpful context" as a failure - It doesn't catch "the context is confusing" (which functional tests would show) - It enforces implementation details that should be allowed to evolve --- src/libexpr-tests/error_traces.cc | 70 ------------------------------- 1 file changed, 70 deletions(-) diff --git a/src/libexpr-tests/error_traces.cc b/src/libexpr-tests/error_traces.cc index 974e4d281..e722cc484 100644 --- a/src/libexpr-tests/error_traces.cc +++ b/src/libexpr-tests/error_traces.cc @@ -139,76 +139,6 @@ TEST_F(ErrorTraceTest, NestedThrows) #define ASSERT_DERIVATION_TRACE3(args, type, message, context1, context2) \ ASSERT_TRACE4(args, type, message, context1, context2, DERIVATION_TRACE_HINTFMT("foo")) -TEST_F(ErrorTraceTest, genericClosure) -{ - ASSERT_TRACE2( - "genericClosure 1", - TypeError, - HintFmt("expected a set but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)), - HintFmt("while evaluating the first argument passed to builtins.genericClosure")); - - ASSERT_TRACE2( - "genericClosure {}", - TypeError, - HintFmt("attribute '%s' missing", "startSet"), - HintFmt("in the attrset passed as argument to builtins.genericClosure")); - - ASSERT_TRACE2( - "genericClosure { startSet = 1; }", - TypeError, - HintFmt("expected a list but found %s: %s", "an integer", Uncolored(ANSI_CYAN "1" ANSI_NORMAL)), - HintFmt("while evaluating the 'startSet' attribute passed as argument to builtins.genericClosure")); - - ASSERT_TRACE2( - "genericClosure { startSet = [{ key = 1;}]; operator = true; }", - TypeError, - HintFmt("expected a function but found %s: %s", "a Boolean", Uncolored(ANSI_CYAN "true" ANSI_NORMAL)), - HintFmt("while evaluating the 'operator' attribute passed as argument to builtins.genericClosure")); - - ASSERT_TRACE3( - "genericClosure { startSet = [{ key = 1;}]; operator = item: true; }", - TypeError, - HintFmt("expected a list but found %s: %s", "a Boolean", Uncolored(ANSI_CYAN "true" ANSI_NORMAL)), - HintFmt("while evaluating the return value of the `operator` passed to builtins.genericClosure"), - HintFmt( - "while calling %s on genericClosure element %s", - "operator", - Uncolored("{ key = " ANSI_CYAN "1" ANSI_NORMAL "; }"))); - - ASSERT_TRACE3( - "genericClosure { startSet = [{ key = 1;}]; operator = item: [ true ]; }", - TypeError, - HintFmt("expected a set but found %s: %s", "a Boolean", Uncolored(ANSI_CYAN "true" ANSI_NORMAL)), - HintFmt(""), - HintFmt("in genericClosure element %s", Uncolored(ANSI_CYAN "true" ANSI_NORMAL))); - - ASSERT_TRACE3( - "genericClosure { startSet = [{ key = 1;}]; operator = item: [ {} ]; }", - TypeError, - HintFmt("attribute '%s' missing", "key"), - HintFmt(""), - HintFmt("in genericClosure element %s", Uncolored("{ }"))); - - ASSERT_TRACE3( - "genericClosure { startSet = [{ key = 1;}]; operator = item: [{ key = ''a''; }]; }", - EvalError, - HintFmt( - "cannot compare %s with %s; values are %s and %s", - "a string", - "an integer", - Uncolored(ANSI_MAGENTA "\"a\"" ANSI_NORMAL), - Uncolored(ANSI_CYAN "1" ANSI_NORMAL)), - HintFmt("with element %s", Uncolored("{ key = " ANSI_CYAN "1" ANSI_NORMAL "; }")), - HintFmt("while comparing element %s", Uncolored("{ key = " ANSI_MAGENTA "\"a\"" ANSI_NORMAL "; }"))); - - ASSERT_TRACE3( - "genericClosure { startSet = [ true ]; operator = item: [{ key = ''a''; }]; }", - TypeError, - HintFmt("expected a set but found %s: %s", "a Boolean", Uncolored(ANSI_CYAN "true" ANSI_NORMAL)), - HintFmt(""), - HintFmt("in genericClosure element %s", Uncolored(ANSI_CYAN "true" ANSI_NORMAL))); -} - TEST_F(ErrorTraceTest, replaceStrings) { ASSERT_TRACE2(