aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorElvis Claros Castro <elvis@claros.ar>2026-10-03 19:47:45 -0300
committerElvis Claros Castro <elvis@claros.ar>2026-10-03 19:47:45 -0300
commita5896fe2e28eb1e9ff9affe5d47ccd443bee5fc2 (patch)
treed76155b2c6aed9b905fe1b04094b879420964177 /tests
parent60c586001cf4d21ef1351be8c8ad7a269a6f005a (diff)
downloadclaude-logbook-a5896fe2e28eb1e9ff9affe5d47ccd443bee5fc2.tar.gz
claude-logbook-a5896fe2e28eb1e9ff9affe5d47ccd443bee5fc2.zip
Use the /rename title, mark compactions, count active time
A title set with /rename (custom-title) now wins over Claude's. The summary Claude Code leaves when the context is compacted is a block of its own ("c"), shown as a "context compacted here" mark instead of a message of yours, and not counted. Duration is active time: pauses over 30 minutes between messages are left out.
Diffstat (limited to 'tests')
-rw-r--r--tests/test_sessions.py45
-rw-r--r--tests/test_terminal.py8
2 files changed, 53 insertions, 0 deletions
diff --git a/tests/test_sessions.py b/tests/test_sessions.py
index 1e10a48..7342058 100644
--- a/tests/test_sessions.py
+++ b/tests/test_sessions.py
@@ -97,6 +97,51 @@ class TestReadSession(TempRoot):
self.assertFalse(S.read_session(path)["n"])
+class TestTitlesCompactionDuration(TempRoot):
+ def test_rename_beats_the_claude_title(self):
+ path = write_session(self.root, "-p", "22222222-0000-0000-0000-000000000001", [
+ ai_title("What Claude thinks"),
+ user("hi there", at=ts(0)),
+ {"type": "custom-title", "customTitle": "Old name"},
+ {"type": "custom-title", "customTitle": "Lo grave"},
+ ai_title("A later Claude title"),
+ ])
+ rec = S.read_session(path)
+ self.assertEqual(rec["t"], "Lo grave")
+ self.assertTrue(rec["ai"])
+
+ def test_compact_summary_is_not_a_message_of_yours(self):
+ path = write_session(self.root, "-p", "22222222-0000-0000-0000-000000000002", [
+ {"type": "system", "subtype": "compact_boundary", "timestamp": ts(0)},
+ user("This session is being continued from a previous conversation. "
+ "Summary: we fixed the build.", at=ts(0), isCompactSummary=True,
+ isVisibleInTranscriptOnly=True),
+ user("now the tests", at=ts(2)),
+ assistant("On it.", at=ts(3)),
+ ])
+ rec = S.read_session(path)
+ self.assertEqual([m["r"] for m in rec["c"]], ["c", "u", "a"])
+ self.assertIn("we fixed the build", rec["c"][0]["x"])
+ self.assertEqual(rec["u"], 1)
+ self.assertEqual(rec["t"], "now the tests")
+ self.assertFalse(rec["n"])
+
+ def test_duration_leaves_out_long_pauses(self):
+ path = write_session(self.root, "-p", "22222222-0000-0000-0000-000000000003", [
+ user("start", at=ts(0)),
+ assistant("ok", at=ts(10)),
+ user("next day", at=ts(0, day=15)),
+ assistant("ok", at=ts(20, day=15)),
+ {"type": "system", "timestamp": ts(0, day=20)}, # not a message
+ ])
+ self.assertEqual(S.read_session(path)["d"], 30)
+
+ def test_active_minutes(self):
+ self.assertIsNone(S.active_minutes([]))
+ self.assertEqual(S.active_minutes([ts(0)]), 0)
+ self.assertEqual(S.active_minutes([ts(0), ts(30), ts(31, hour=11)]), 30)
+
+
class TestToolSummary(unittest.TestCase):
def test_uses_the_representative_parameter(self):
self.assertEqual(
diff --git a/tests/test_terminal.py b/tests/test_terminal.py
index 0446dda..e7e6d69 100644
--- a/tests/test_terminal.py
+++ b/tests/test_terminal.py
@@ -127,6 +127,14 @@ class TestOutput(unittest.TestCase):
T.print_chat(self.session_item(), T.Style(False), buf, show_tools=False)
self.assertNotIn("Bash: ls", buf.getvalue())
+ def test_compaction_is_a_mark_without_the_summary(self):
+ buf = io.StringIO()
+ c = [{"r": "c", "x": "SUMMARY TEXT"}, {"r": "u", "x": "hello"}]
+ T.print_chat(self.session_item(c=c), T.Style(False), buf)
+ out = buf.getvalue()
+ self.assertIn("context compacted here", out)
+ self.assertNotIn("SUMMARY TEXT", out)
+
def test_empty_session_says_so(self):
buf = io.StringIO()
T.print_chat(self.session_item(c=[], t=None), T.Style(False), buf)