Files
Jyotisha/tests/test_flexible_birth_time_profile.py
T
Jesse_Chen 814c924e4a
Independent Staging Quality Gate / validate (push) Successful in 9m20s
Independent Staging Quality Gate / publish (push) Successful in 6m51s
fix(rectification): exhaustion exit, explain layer, range reading, unknown-time scan (BUG-565–568)
Keep askable cards after exhaustion, explain each probe, read the adopted credible range in reports and chat, and compare declared periods before the minute grid when the clock is unknown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 09:10:37 +08:00

87 lines
3.2 KiB
Python

#!/usr/bin/env python3
"""Focused contracts for unresolved birth-time candidate profiles."""
from __future__ import annotations
import json
import os
import sys
import pytest
SCRIPTS = os.path.join(os.path.dirname(__file__), "..", "scripts")
if SCRIPTS not in sys.path:
sys.path.insert(0, SCRIPTS)
from flexible_birth_time_profile import ( # noqa: E402
FlexibleBirthTimeProfileError,
build_flexible_birth_time_profile,
)
def _candidate(index: int, count: int) -> dict:
candidate_time = f"08:{index:02d}"
return {
"candidate_id": f"fictional-{index}",
"candidate_time": candidate_time,
"evidence": {
"D1.ascendant": "Aries",
"D10.ascendant": "Capricorn" if index < count - 1 else "Aquarius",
},
"trace": [{"kind": "fictional_candidate", "reference": f"fixture://{candidate_time}"}],
}
@pytest.mark.parametrize("count", [2, 15, 31])
def test_profile_supports_two_to_thirty_one_candidates_with_real_minute_variation(count: int) -> None:
candidates = [_candidate(index, count) for index in range(count)]
profile = build_flexible_birth_time_profile(
candidates,
source_reference={"review_id": "fictional-review"},
)
reversed_profile = build_flexible_birth_time_profile(
list(reversed(candidates)),
source_reference={"review_id": "fictional-review"},
)
assert profile == reversed_profile
assert profile["birth_time_window"]["candidate_count"] == count
assert profile["stable_evidence"] == {"D1.ascendant": "Aries"}
assert set(profile["sensitive_evidence"]) == {"D10.ascendant"}
for minute_values in profile["sensitive_evidence"].values():
assert len({json.dumps(value, sort_keys=True) for value in minute_values.values()}) > 1
@pytest.mark.parametrize("count", [1, 32])
def test_profile_rejects_candidate_counts_outside_two_to_thirty_one(count: int) -> None:
with pytest.raises(FlexibleBirthTimeProfileError, match="candidate_count_must_be_two_to_thirty_one"):
build_flexible_birth_time_profile(
[_candidate(index, max(count, 2)) for index in range(count)],
source_reference={"review_id": "fictional-review"},
)
@pytest.mark.parametrize("status", ["approved", "confirmed"])
def test_profile_rejects_approved_or_confirmed_source_reference(status: str) -> None:
with pytest.raises(FlexibleBirthTimeProfileError, match="approved_or_confirmed_source_reference_forbidden"):
build_flexible_birth_time_profile(
[_candidate(0, 2), _candidate(1, 2)],
source_reference={"review_id": "fictional-review", "status": status},
)
@pytest.mark.parametrize(
"field",
["approved_birth_time", "final_birth_time", "winner", "approval", "approval_authority"],
)
def test_profile_rejects_birth_minute_authority_fields(field: str) -> None:
candidates = [_candidate(0, 2), _candidate(1, 2)]
candidates[0]["evidence"][field] = "08:00"
with pytest.raises(FlexibleBirthTimeProfileError, match="candidate_window_authority_forbidden"):
build_flexible_birth_time_profile(
candidates,
source_reference={"review_id": "fictional-review"},
)