From 17af2ecfe17dcfd7791b2fbcfe948bc3a3e3255f Mon Sep 17 00:00:00 2001 From: hotragn Date: Tue, 18 Aug 2026 22:04:32 -0400 Subject: [PATCH] test: make three fixtures portable so they test the code, not the host platform Five tests fail on Windows because of how their fixtures build input, not because of the code under test. In each case the source is already correct. 1. `test_tagging.py` (3 failures). Five page fixtures write content through `write_text`, which translates "\n" to os.linesep, then assert byte-exact round-tripping via `read_bytes()`. On Windows the intended "\r\n" lands as "\r\r\n", which is not a valid frontmatter fence, so the page appears to have no frontmatter, a second block is prepended and the original is absorbed into the body. Passing `newline=""` writes what the test actually wrote. `rewrite_page_topics` is not at fault: it reads bytes, detects the ending and preserves it. 2. `test_transcript_discovery.py` (1 failure). The Claude fixture hand-builds JSONL with an f-string, so a Windows path embeds invalid escapes ("cwd":"C:\Users\...") and the line fails to parse, yielding 0 candidates. Its Codex sibling in the same file already uses `json.dumps` and passes on Windows for exactly that reason, so this just adopts the established pattern. `json` was already imported. 3. `test_build_workflow.py` (1 failure). The expected value mixes separators by interpolating a native path and appending "/almanac/manual", and does not account for the prompt being JSON-encoded. Building it with `json.dumps` and pathlib joins compares like with like. Windows goes from 13 failed / 550 passed to 8 failed / 555 passed. The remaining 8 are the 5 macOS-only `launchd` tests plus 3 covered by #64 and #65; with those merged, the only Windows failures left are the `launchd` ones, which is the point at which a Windows CI job could be added and mean something. No behaviour change on macOS or Linux: every edit changes only how a fixture serializes its input. --- tests/test_build_workflow.py | 4 +++- tests/test_tagging.py | 7 +++++-- tests/test_transcript_discovery.py | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/tests/test_build_workflow.py b/tests/test_build_workflow.py index e2897640..771c0826 100644 --- a/tests/test_build_workflow.py +++ b/tests/test_build_workflow.py @@ -1,3 +1,4 @@ +import json import shutil import subprocess from pathlib import Path @@ -209,7 +210,8 @@ def test_queued_build_uses_harness_prompt_and_records_build_operation( assert adapter.requests[0].agent is HarnessAgentKind.BUILD assert adapter.requests[0].prompt.startswith("Runtime context:\n{") assert "Build Operation" not in adapter.requests[0].prompt - assert f'"manual_root": "{repo}/almanac/manual"' in adapter.requests[0].prompt + manual_root = json.dumps(str(repo / "almanac" / "manual")) + assert f'"manual_root": {manual_root}' in adapter.requests[0].prompt assert '"manual_documents"' not in adapter.requests[0].prompt assert "Write the smallest useful first wiki." in adapter.requests[0].prompt diff --git a/tests/test_tagging.py b/tests/test_tagging.py index b4f121f9..438550e4 100644 --- a/tests/test_tagging.py +++ b/tests/test_tagging.py @@ -15,6 +15,7 @@ def test_tag_adds_topic_preserves_body_and_frontmatter_comment( page.write_text( f"---\ntitle: Auth Flow\n# keep this comment\ntopics: [auth]\n---\n{body}", encoding="utf-8", + newline="", ) app = create_app( AppConfig(database_path=isolated_home / ".codealmanac/codealmanac.db") @@ -43,6 +44,7 @@ def test_untag_removes_topic_and_allows_orphan_page( page.write_text( "---\ntitle: Auth Flow\ntopics: [auth]\n---\n# Auth Flow\n", encoding="utf-8", + newline="", ) app = create_app( AppConfig(database_path=isolated_home / ".codealmanac/codealmanac.db") @@ -63,7 +65,7 @@ def test_tag_adds_frontmatter_when_page_has_none( ): repo = make_repo(tmp_path) page = repo / "almanac/note.md" - page.write_text("# Note\n\nBody.\n", encoding="utf-8") + page.write_text("# Note\n\nBody.\n", encoding="utf-8", newline="") app = create_app( AppConfig(database_path=isolated_home / ".codealmanac/codealmanac.db") ) @@ -81,7 +83,7 @@ def test_tag_handles_frontmatter_closing_fence_at_eof( ): repo = make_repo(tmp_path) page = repo / "almanac/note.md" - page.write_text("---\ntitle: Note\n---", encoding="utf-8") + page.write_text("---\ntitle: Note\n---", encoding="utf-8", newline="") app = create_app( AppConfig(database_path=isolated_home / ".codealmanac/codealmanac.db") ) @@ -104,6 +106,7 @@ def test_tag_preserves_crlf_frontmatter_and_body( page.write_text( f"---\r\ntitle: Auth Flow\r\ntopics:\r\n - auth\r\n---\r\n{body}", encoding="utf-8", + newline="", ) app = create_app( AppConfig(database_path=isolated_home / ".codealmanac/codealmanac.db") diff --git a/tests/test_transcript_discovery.py b/tests/test_transcript_discovery.py index a6a4288b..24ed1257 100644 --- a/tests/test_transcript_discovery.py +++ b/tests/test_transcript_discovery.py @@ -73,13 +73,13 @@ def test_claude_transcript_discovery_reads_metadata_and_skips_subagents( projects.mkdir(parents=True) transcript = projects / "session.jsonl" transcript.write_text( - f'{{"sessionId":"claude-1","cwd":"{repo}"}}\n', + json.dumps({"sessionId": "claude-1", "cwd": str(repo)}) + "\n", encoding="utf-8", ) subagents = projects / "subagents" subagents.mkdir() (subagents / "session.jsonl").write_text( - f'{{"sessionId":"claude-2","cwd":"{repo}"}}\n', + json.dumps({"sessionId": "claude-2", "cwd": str(repo)}) + "\n", encoding="utf-8", )