Merge pull request 'test(tui): add TDD failing test for SQLite session persistence' (#10886) from tdd/m8-tui-sqlite-session-persistence into master
CI / lint (push) Successful in 1m7s
CI / typecheck (push) Successful in 2m12s
CI / push-validation (push) Successful in 41s
CI / build (push) Successful in 1m7s
CI / security (push) Successful in 2m14s
CI / helm (push) Successful in 1m10s
CI / quality (push) Successful in 1m14s
CI / e2e_tests (push) Successful in 1m38s
CI / unit_tests (push) Successful in 4m53s
CI / docker (push) Successful in 1m30s
CI / integration_tests (push) Successful in 9m57s
CI / coverage (push) Successful in 27m59s
CI / status-check (push) Successful in 3s
CI / benchmark-regression (push) Successful in 1h9m18s
CI / benchmark-publish (push) Successful in 1h28m15s
CI / lint (push) Successful in 1m7s
CI / typecheck (push) Successful in 2m12s
CI / push-validation (push) Successful in 41s
CI / build (push) Successful in 1m7s
CI / security (push) Successful in 2m14s
CI / helm (push) Successful in 1m10s
CI / quality (push) Successful in 1m14s
CI / e2e_tests (push) Successful in 1m38s
CI / unit_tests (push) Successful in 4m53s
CI / docker (push) Successful in 1m30s
CI / integration_tests (push) Successful in 9m57s
CI / coverage (push) Successful in 27m59s
CI / status-check (push) Successful in 3s
CI / benchmark-regression (push) Successful in 1h9m18s
CI / benchmark-publish (push) Successful in 1h28m15s
This commit was merged in pull request #10886.
This commit is contained in:
@@ -0,0 +1,152 @@
|
|||||||
|
"""Step definitions for TDD Bug #4739 — TUI SQLite session persistence not implemented.
|
||||||
|
|
||||||
|
These steps verify that ``cleveragents.tui.session_store`` exists and that
|
||||||
|
``TuiSessionStore`` can persist and retrieve session records from SQLite.
|
||||||
|
|
||||||
|
All scenarios are tagged ``@tdd_expected_fail`` so CI passes while the
|
||||||
|
module is absent. The expected-fail mechanism inverts the result: a
|
||||||
|
failing assertion means the bug is still present (CI passes); a passing
|
||||||
|
assertion means the fix has been applied (CI also passes after the
|
||||||
|
``@tdd_expected_fail`` tag is removed in the bugfix PR).
|
||||||
|
|
||||||
|
Failure mode: ``AssertionError`` (not ``ImportError`` or ``RuntimeError``).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
import types
|
||||||
|
from typing import Any, cast
|
||||||
|
|
||||||
|
from behave import given, then, when
|
||||||
|
from behave.runner import Context
|
||||||
|
|
||||||
|
|
||||||
|
@given("the tdd4739 test environment is set up")
|
||||||
|
def step_tdd4739_setup(context: Context) -> None:
|
||||||
|
"""Initialise context attributes used across tdd4739 steps."""
|
||||||
|
context.tdd4739_module: types.ModuleType | None = None
|
||||||
|
context.tdd4739_import_error: Exception | None = None
|
||||||
|
context.tdd4739_store: object | None = None
|
||||||
|
context.tdd4739_tmpdir: str | None = None
|
||||||
|
|
||||||
|
|
||||||
|
@given("the tdd4739 test environment is set up with a temp db path")
|
||||||
|
def step_tdd4739_setup_with_tmpdir(context: Context) -> None:
|
||||||
|
"""Initialise context and create a temporary directory for the SQLite db."""
|
||||||
|
context.tdd4739_module = None
|
||||||
|
context.tdd4739_import_error = None
|
||||||
|
context.tdd4739_store = None
|
||||||
|
|
||||||
|
tmpdir = tempfile.mkdtemp(prefix="tdd4739_")
|
||||||
|
context.tdd4739_tmpdir = tmpdir
|
||||||
|
context.tdd4739_db_path = os.path.join(tmpdir, "tui.db")
|
||||||
|
|
||||||
|
def _cleanup() -> None:
|
||||||
|
shutil.rmtree(tmpdir, ignore_errors=True)
|
||||||
|
|
||||||
|
context.add_cleanup(_cleanup)
|
||||||
|
|
||||||
|
|
||||||
|
@when("I attempt to import cleveragents.tui.session_store")
|
||||||
|
def step_tdd4739_import(context: Context) -> None:
|
||||||
|
"""Attempt to import the session_store module; capture any ImportError."""
|
||||||
|
try:
|
||||||
|
mod = importlib.import_module("cleveragents.tui.session_store")
|
||||||
|
context.tdd4739_module = mod
|
||||||
|
context.tdd4739_import_error = None
|
||||||
|
except ImportError as exc:
|
||||||
|
context.tdd4739_module = None
|
||||||
|
context.tdd4739_import_error = exc
|
||||||
|
|
||||||
|
|
||||||
|
@then("the tdd4739 import should succeed without errors")
|
||||||
|
def step_tdd4739_import_ok(context: Context) -> None:
|
||||||
|
"""Assert the import succeeded — fails via AssertionError if module is absent."""
|
||||||
|
assert context.tdd4739_import_error is None, (
|
||||||
|
f"cleveragents.tui.session_store could not be imported: "
|
||||||
|
f"{context.tdd4739_import_error}"
|
||||||
|
)
|
||||||
|
assert context.tdd4739_module is not None, (
|
||||||
|
"cleveragents.tui.session_store module is None after import"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@then("the tdd4739 module should expose a TuiSessionStore class")
|
||||||
|
def step_tdd4739_class_exists(context: Context) -> None:
|
||||||
|
"""Assert TuiSessionStore is present in the module."""
|
||||||
|
assert context.tdd4739_import_error is None, (
|
||||||
|
f"cleveragents.tui.session_store could not be imported: "
|
||||||
|
f"{context.tdd4739_import_error}"
|
||||||
|
)
|
||||||
|
mod = context.tdd4739_module
|
||||||
|
assert mod is not None, "session_store module is None"
|
||||||
|
assert hasattr(mod, "TuiSessionStore"), (
|
||||||
|
"cleveragents.tui.session_store does not expose a TuiSessionStore class"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@when("I create a TuiSessionStore pointing at the temp db path")
|
||||||
|
def step_tdd4739_create_store(context: Context) -> None:
|
||||||
|
"""Instantiate TuiSessionStore with the temp db path."""
|
||||||
|
try:
|
||||||
|
mod = importlib.import_module("cleveragents.tui.session_store")
|
||||||
|
except ImportError as exc:
|
||||||
|
raise AssertionError(
|
||||||
|
f"cleveragents.tui.session_store could not be imported: {exc}"
|
||||||
|
) from exc
|
||||||
|
|
||||||
|
assert hasattr(mod, "TuiSessionStore"), (
|
||||||
|
"cleveragents.tui.session_store does not expose a TuiSessionStore class"
|
||||||
|
)
|
||||||
|
context.tdd4739_store = mod.TuiSessionStore(db_path=context.tdd4739_db_path)
|
||||||
|
|
||||||
|
|
||||||
|
@when('I save a tdd4739 session record with id "{session_id}"')
|
||||||
|
def step_tdd4739_save_session(context: Context, session_id: str) -> None:
|
||||||
|
"""Save a minimal session record to the store."""
|
||||||
|
store = cast(Any, context.tdd4739_store)
|
||||||
|
assert store is not None, "TuiSessionStore was not created"
|
||||||
|
store.save(
|
||||||
|
session_id=session_id,
|
||||||
|
persona_name="default",
|
||||||
|
actor_identity="anthropic/claude-4-sonnet",
|
||||||
|
title=f"Test session {session_id}",
|
||||||
|
prompt_count=0,
|
||||||
|
total_cost=0.0,
|
||||||
|
created_at="2026-01-01T00:00:00Z",
|
||||||
|
last_used="2026-01-01T00:00:00Z",
|
||||||
|
project_path=None,
|
||||||
|
meta_json="{}",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@then('the tdd4739 session record should be retrievable by id "{session_id}"')
|
||||||
|
def step_tdd4739_get_session(context: Context, session_id: str) -> None:
|
||||||
|
"""Assert the session record can be retrieved by its id."""
|
||||||
|
store = cast(Any, context.tdd4739_store)
|
||||||
|
assert store is not None, "TuiSessionStore was not created"
|
||||||
|
record = store.get(session_id)
|
||||||
|
assert record is not None, (
|
||||||
|
f"TuiSessionStore.get('{session_id}') returned None — session was not persisted"
|
||||||
|
)
|
||||||
|
assert getattr(record, "id", None) == session_id or (
|
||||||
|
isinstance(record, dict) and record.get("id") == session_id
|
||||||
|
), (
|
||||||
|
f"Retrieved record id mismatch: expected '{session_id}', "
|
||||||
|
f"got {getattr(record, 'id', record)!r}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@then("the tdd4739 session store should list {count:d} sessions")
|
||||||
|
def step_tdd4739_list_sessions(context: Context, count: int) -> None:
|
||||||
|
"""Assert the store lists the expected number of sessions."""
|
||||||
|
store = cast(Any, context.tdd4739_store)
|
||||||
|
assert store is not None, "TuiSessionStore was not created"
|
||||||
|
sessions = store.list_all()
|
||||||
|
assert sessions is not None, "TuiSessionStore.list_all() returned None"
|
||||||
|
actual = len(sessions)
|
||||||
|
assert actual == count, f"Expected {count} sessions in store, got {actual}"
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
@tdd_issue @tdd_issue_4739
|
||||||
|
Feature: Bug #4739 — TUI SQLite session persistence not implemented
|
||||||
|
As a developer
|
||||||
|
I want to verify that the TUI session persistence layer exists
|
||||||
|
So that the bug is captured and will be caught by a regression test
|
||||||
|
|
||||||
|
The spec (§Session Persistence and Resume) requires TUI sessions to be
|
||||||
|
persisted in an SQLite database at ~/.local/state/cleveragents/tui.db
|
||||||
|
via a TuiSessionStore class in cleveragents.tui.session_store.
|
||||||
|
|
||||||
|
Currently no such module exists — the TUI hardcodes a single in-memory
|
||||||
|
session and has no SQLite persistence layer.
|
||||||
|
|
||||||
|
@tdd_issue @tdd_issue_4739 @tdd_expected_fail
|
||||||
|
Scenario: TuiSessionStore module can be imported from cleveragents.tui
|
||||||
|
Given the tdd4739 test environment is set up
|
||||||
|
When I attempt to import cleveragents.tui.session_store
|
||||||
|
Then the tdd4739 import should succeed without errors
|
||||||
|
|
||||||
|
@tdd_issue @tdd_issue_4739 @tdd_expected_fail
|
||||||
|
Scenario: TuiSessionStore class exists in the session_store module
|
||||||
|
Given the tdd4739 test environment is set up
|
||||||
|
When I attempt to import cleveragents.tui.session_store
|
||||||
|
Then the tdd4739 module should expose a TuiSessionStore class
|
||||||
|
|
||||||
|
@tdd_issue @tdd_issue_4739 @tdd_expected_fail
|
||||||
|
Scenario: TuiSessionStore can persist a session record to SQLite
|
||||||
|
Given the tdd4739 test environment is set up with a temp db path
|
||||||
|
When I create a TuiSessionStore pointing at the temp db path
|
||||||
|
And I save a tdd4739 session record with id "test-session-001"
|
||||||
|
Then the tdd4739 session record should be retrievable by id "test-session-001"
|
||||||
|
|
||||||
|
@tdd_issue @tdd_issue_4739 @tdd_expected_fail
|
||||||
|
Scenario: TuiSessionStore lists all persisted sessions
|
||||||
|
Given the tdd4739 test environment is set up with a temp db path
|
||||||
|
When I create a TuiSessionStore pointing at the temp db path
|
||||||
|
And I save a tdd4739 session record with id "sess-a"
|
||||||
|
And I save a tdd4739 session record with id "sess-b"
|
||||||
|
Then the tdd4739 session store should list 2 sessions
|
||||||
Reference in New Issue
Block a user