From f76db6c8fe80297fc474615b69bcdcb3fe7374e5 Mon Sep 17 00:00:00 2001 From: Thom Lamb Date: Fri, 21 Aug 2026 18:21:11 -0500 Subject: [PATCH] fix(test): make the compose guard survive a CRLF checkout (#107) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guard added for #107 finds nothing on a checkout with CRLF line endings, which is every fresh clone on Windows. Splitting on a bare newline leaves a trailing carriage return, the end-of-line anchor in the entry pattern then cannot match, and all ten assertions in the file fail together. Worth being precise about why this shipped, because the process that was supposed to prevent it ran and did not. That guard was fired deliberately before committing: the UPLOADS_DIR line was removed, two tests failed, the line was restored, ten passed. What the exercise never varied was the file's line endings — and by then the working copy happened to be LF, because the backup-and-restore used to fire the guard had rewritten it that way. So the deliberate firing proved the guard catches a missing variable, on a file shaped exactly as the test run had shaped it, and proved nothing about the shape it meets in a clean clone. The failure mode is the one the file already worried about: parsing that matches nothing makes every other assertion vacuously true. Here it failed loudly instead only because the "parsed some entries at all" case exists — which is the case that turned a silent pass into a visible failure, and is the reason this was noticed at all rather than sitting green and checking nothing. Splitting on an optional carriage return fixes it. 172 unit tests pass on the CRLF checkout that was failing. Found while verifying #106, whose branch could not go green until this was fixed, which is why the fix lands there rather than on its own. Refs #107 Co-Authored-By: Claude Opus 5 --- backend/tests/unit/composeEnvironment.test.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/tests/unit/composeEnvironment.test.ts b/backend/tests/unit/composeEnvironment.test.ts index add172a..b90926c 100644 --- a/backend/tests/unit/composeEnvironment.test.ts +++ b/backend/tests/unit/composeEnvironment.test.ts @@ -28,7 +28,13 @@ const compose = readFileSync(COMPOSE_PATH, 'utf8'); // A mention inside a comment cannot match, because a comment line starts with #. function environmentEntries(source: string): Map { const entries = new Map(); - for (const line of source.split('\n')) { + // The split pattern tolerates carriage returns. A checkout with CRLF line + // endings, which is every fresh clone on Windows, otherwise leaves a stray + // carriage return that the end-of-line anchor below cannot match, and every + // assertion in this file then silently finds nothing at all. That is exactly + // the failure the "parsed some entries" case exists to catch, and it is how + // this guard was found to be broken. + for (const line of source.split(/\r?\n/)) { const match = /^\s+- ([A-Z_0-9]+)=(.*)$/.exec(line); if (match) { entries.set(match[1], match[2].trim());