docs(6209): coverage, guidance-ownership, shape, warnings tests and shared fixtures
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m12s
CI & Build / Python tests (push) Successful in 1m56s
CI & Build / Build & push image (push) Successful in 13s
CI & Build / Python lint (push) Successful in 2s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m12s
CI & Build / Python tests (push) Successful in 1m56s
CI & Build / Build & push image (push) Successful in 13s
test_pattern_coverage, test_guidance_ownership, test_integration_shape_classify, test_instruction_surfaces_agree, test_retrieval_warnings, helpers.py and conftest.py state the property each test or fixture holds. The issue and milestone numbers, consolidation dates and one-install measurements that recorded how each was found are dropped; fixture dates and ids stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+24
-40
@@ -1,8 +1,7 @@
|
||||
"""Shared test helpers — the plain functions tests call, as opposed to the
|
||||
fixtures in conftest.py.
|
||||
|
||||
Each of these was copied into several test modules before #2825 consolidated
|
||||
them; a module imports what it needs with ``from tests.helpers import ...``.
|
||||
Each of these serves several test modules; a module imports what it needs with ``from tests.helpers import ...``.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -17,9 +16,7 @@ async def drive_update_note(note, **kwargs):
|
||||
|
||||
The patch stack is the point: update_note reaches for a version snapshot,
|
||||
an embedding refresh and a project reactivation on its way out, none of
|
||||
which a unit test has. Written twice — once for the snippet mirror
|
||||
(#3128) and once for the verification fields (#3182/317) — before being
|
||||
consolidated here.
|
||||
which a unit test has.
|
||||
|
||||
Returns whatever update_note returned; assert on the `note` you passed in.
|
||||
"""
|
||||
@@ -43,12 +40,11 @@ def tool_doc(module: str, name: str) -> str:
|
||||
|
||||
Flattened because these are hard-wrapped at ~76 characters, so any phrase
|
||||
worth asserting on is liable to straddle a line break — a property of the
|
||||
formatter, not of the guidance. The disambiguator guard (#3123) learned
|
||||
that on its own first run, matching raw text and reporting a phrase absent
|
||||
that was plainly there.
|
||||
formatter, not of the guidance. Matching raw text reports a phrase absent
|
||||
that is plainly there.
|
||||
|
||||
Used by every test that pins the docstring CONTRACT rather than its
|
||||
wording. The tool docstring is the agent-facing contract (rule 119), so
|
||||
wording. The tool docstring is the agent-facing contract, so
|
||||
these guards exist to catch it being tidied down to a parameter list.
|
||||
"""
|
||||
import importlib
|
||||
@@ -63,8 +59,7 @@ def compiled_sql(element, dialect=None) -> str:
|
||||
"""A SQLAlchemy clause or statement rendered as literal SQL text.
|
||||
|
||||
For asserting on the shape of a predicate without a database — which is how
|
||||
the visibility clauses and the knowledge facets are both tested. Was a
|
||||
private copy in each of those modules before #3128 needed a third.
|
||||
the visibility clauses and the knowledge facets are both tested.
|
||||
|
||||
Pass `dialect` when the assertion is about something only one backend
|
||||
renders — a Postgres row-lock mode, say. The generic dialect is enough for
|
||||
@@ -93,9 +88,8 @@ def session_returning(note):
|
||||
"""``make_mock_session`` whose every ``execute()`` yields `note` (or None).
|
||||
|
||||
The commonest shape above the bare session: a service that loads one
|
||||
record by id and acts on it. Two files had spelled this out identically
|
||||
before a third was about to (#3207 — derive before the third copy), and
|
||||
it belongs beside `make_mock_session` for the same reason that one does.
|
||||
record by id and acts on it, and it belongs beside `make_mock_session`
|
||||
for the same reason that one does.
|
||||
|
||||
For a service making SEVERAL different reads, set
|
||||
``session.execute.side_effect`` to a list of results instead.
|
||||
@@ -134,7 +128,7 @@ def fake_record(**attrs) -> MagicMock:
|
||||
"""A MagicMock record with REAL values on the attributes named, and a
|
||||
``to_dict()`` that mirrors them.
|
||||
|
||||
The hazard this exists for (note 2109): an auto-created MagicMock attribute
|
||||
The hazard this exists for: an auto-created MagicMock attribute
|
||||
is truthy and has a repr — so a bare MagicMock handed to the product reads
|
||||
as trashed, shared, a task, and owned by a MagicMock. Name every attribute
|
||||
the code under test will read; the per-model ``fake_*`` builders below
|
||||
@@ -180,10 +174,10 @@ def fake_note(**attrs) -> MagicMock:
|
||||
"note_type": "note", "is_task": False, "task_kind": "work",
|
||||
"status": "todo" if is_task else None,
|
||||
"data": None, "deleted_at": None,
|
||||
# Milestone 317: a truthy mock here reads as "this note carries a
|
||||
# A truthy mock here reads as "this note carries a
|
||||
# check", which trips the guard on records that may not have one.
|
||||
"verify_with": None, "expires_when": None, "verified_at": None,
|
||||
# Milestone 381: a truthy mock would read as a live claim.
|
||||
# A truthy mock would read as a live claim.
|
||||
"claimed_by": None, "claimed_at": None, "claim_touched_at": None,
|
||||
"claim_session": None,
|
||||
}, attrs)
|
||||
@@ -196,7 +190,7 @@ def fake_task(**attrs) -> MagicMock:
|
||||
"tags": [], "parent_id": None, "project_id": None, "is_task": True,
|
||||
"task_kind": "work", "user_id": 7, "deleted_at": None,
|
||||
"verify_with": None, "expires_when": None, "verified_at": None,
|
||||
# Milestone 381: a truthy mock would read as a live claim.
|
||||
# A truthy mock would read as a live claim.
|
||||
"claimed_by": None, "claimed_at": None, "claim_touched_at": None,
|
||||
"claim_session": None,
|
||||
}, attrs)
|
||||
@@ -219,9 +213,8 @@ def fake_lesson(**attrs) -> MagicMock:
|
||||
"""A stand-in lesson: a note whose `note_type` is what makes it one.
|
||||
|
||||
The title is the subject alone and the trigger lives in `data`, because
|
||||
that is the record the product creates (milestone 427) — the trigger joins
|
||||
the title only in the embedded document. A default whose title carried the
|
||||
trigger would be testing a row only an un-migrated database holds.
|
||||
that is the record the product creates — the trigger joins the title only
|
||||
in the embedded document.
|
||||
|
||||
The check fields and `arose_from_id` are explicitly None for the reason
|
||||
`fake_snippet`'s `data` is: `update_note` reads `verify_with` and
|
||||
@@ -310,8 +303,7 @@ def plain_rule_detail():
|
||||
the TOOL forwarded the right arguments, so the seam is stubbed the same
|
||||
way the create/update calls themselves already are.
|
||||
|
||||
Consolidated here on its second copy, per this module's own reason for
|
||||
existing (#2825) — two stubs for one seam drift apart quietly, and a test
|
||||
Shared here because two stubs for one seam drift apart quietly, and a test
|
||||
stubbing the seam slightly differently is a test asserting something
|
||||
slightly different than it appears to.
|
||||
"""
|
||||
@@ -356,8 +348,7 @@ def http_sink(reply: bytes = b'{"context":"","note_ids":[]}',
|
||||
(one dict per request, in order). Lets the shell be tested end to end —
|
||||
the extraction, the encoding, the URL — without a Scribe instance.
|
||||
|
||||
Three test modules each carried their own ``_Sink`` handler before #2904
|
||||
consolidated them here; pass ``reply`` for the body the hook should see.
|
||||
Pass ``reply`` for the body the hook should see.
|
||||
|
||||
``by_path`` is for a hook that calls more than one route: each request is
|
||||
answered with the reply for its path (``reply`` when none is listed), and
|
||||
@@ -406,10 +397,10 @@ def http_sink(reply: bytes = b'{"context":"","note_ids":[]}',
|
||||
|
||||
|
||||
def writepath_cfg(**over):
|
||||
"""A complete `get_writepath_config` stand-in, built from the registry (#4102).
|
||||
"""A complete `get_writepath_config` stand-in, built from the registry.
|
||||
|
||||
DERIVED, NOT LITERAL, and the reason is a failure mode this file already
|
||||
warned about in prose without being able to prevent: the write-path hint
|
||||
DERIVED, NOT LITERAL, because of a failure mode prose cannot prevent: the
|
||||
write-path hint
|
||||
drives three arms, each of which reads its numbers out of the config dict
|
||||
inside a fail-open `except`. A dict missing one key does not raise where a
|
||||
reader would see it — the arm silently becomes a no-op, which is
|
||||
@@ -417,9 +408,9 @@ def writepath_cfg(**over):
|
||||
|
||||
So the keys come from `retrieval_surfaces.SURFACES`. A seventh surface, or a
|
||||
rename, changes this helper for free and cannot quietly disable an arm in
|
||||
ten hand-written dicts that each looked complete on the day they were typed.
|
||||
hand-written dicts that each looked complete on the day they were typed.
|
||||
|
||||
NOT EVERY KEY IS A SURFACE, and that gap already bit once (#4214). The
|
||||
NOT EVERY KEY IS A SURFACE. The
|
||||
checkpoint bar has no entry in SURFACES on purpose — everything in that
|
||||
table is a floor/budget pair belonging to one QUERY, and the checkpoint
|
||||
runs none, it re-reads hits the rule arms already produced. Adding it there
|
||||
@@ -458,11 +449,7 @@ def need_tools(*tools):
|
||||
|
||||
A skip rather than a stub on purpose. Stubbing `jq` would test the stub —
|
||||
these tests exist precisely because the shell's behaviour is the thing in
|
||||
question (#2932), so anything short of the real tool proves nothing.
|
||||
|
||||
Consolidated 2026-09-21 from three byte-identical copies in
|
||||
test_contract_around_the_change, test_hook_json_reader and
|
||||
test_session_slippage_readout.
|
||||
question, so anything short of the real tool proves nothing.
|
||||
"""
|
||||
import shutil
|
||||
|
||||
@@ -482,14 +469,11 @@ async def rule_row(rule_id: int):
|
||||
map, which can hold a value the database never accepted — a column the
|
||||
write never reached, a default the ORM supplied rather than the schema.
|
||||
Opening a new session forces a real read and is the only way `verify_with`
|
||||
being NULL rather than "" is distinguishable at all (milestone 312).
|
||||
being NULL rather than "" is distinguishable at all.
|
||||
|
||||
Import is lazy because this module is imported by unit tests that have no
|
||||
database and must not pay for one — the same reason `plugin_config` defers
|
||||
its service imports.
|
||||
|
||||
Consolidated 2026-09-21 from two byte-identical copies in
|
||||
test_integration_rule_move and test_integration_rule_verification.
|
||||
"""
|
||||
from scribe.models import async_session
|
||||
from scribe.models.rulebook import Rule
|
||||
@@ -519,7 +503,7 @@ def skill_text(name: str) -> str:
|
||||
|
||||
A skill keeps what matters on most turns in SKILL.md and moves what matters
|
||||
at one moment into sibling files it links (Agent Skills progressive
|
||||
disclosure, #4398). Both are the skill's own statement, so a test asking
|
||||
disclosure). Both are the skill's own statement, so a test asking
|
||||
"does this skill still say X" reads them together rather than pinning X to
|
||||
whichever file it happens to sit in today.
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user