Spaces:
Sleeping
Sleeping
| """M2 κ²°μ μ λ¦¬λ© λ£¨ν νκ· ν μ€νΈ β LLM μμ΄ μ 체 μμ¬κ° μ½λλ§μΌλ‘ λλ€.""" | |
| import pytest | |
| from engine.repositories.content import ContentError, ContentRepository | |
| from engine.services.state import HiddenState | |
| from engine.services.story import StoryEngine, eval_condition | |
| def repo(): | |
| return ContentRepository("content") | |
| def play(repo, policy: str) -> StoryEngine: | |
| engine = StoryEngine(repo) | |
| step = engine.start() | |
| while step.ending is None: | |
| if step.choices: | |
| idx = next((i for i, c in enumerate(step.choices) if c.axis == policy), | |
| next((i for i, c in enumerate(step.choices) | |
| if c.axis in (None, "neutral")), 0)) | |
| _, step = engine.choose(idx) | |
| else: | |
| step = engine.advance() | |
| return engine | |
| # ββ μλ© 3μ’ λλ¬ (μλ ΄ νκ·μ ν΅μ¬) βββββββββββββββββββββββββ | |
| def test_trust_policy_reaches_eternal(repo): | |
| e = play(repo, "trust") | |
| assert e.ending.id == "ending_eternal" | |
| def test_doubt_policy_reaches_reckoning(repo): | |
| e = play(repo, "doubt") | |
| assert e.ending.id == "ending_reckoning" | |
| assert e.ending.canonical # μ²λ¨μ΄ μμ μΊλ Ό | |
| def test_neutral_policy_reaches_release(repo): | |
| e = play(repo, "neutral") | |
| assert e.ending.id == "ending_release" | |
| # ββ μΊλ Ό 보μ₯ ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| def test_reach_point_visited_on_every_policy(repo): | |
| """E06-10(λ μ λ°κ²¬)μ μ΄λ€ μ±ν₯μ΄λ λ°λμ λλ¬ (νλ² 0λ²).""" | |
| for policy in ("trust", "doubt", "neutral"): | |
| e = play(repo, policy) | |
| assert "E06-10" in e.visited, policy | |
| assert e.state.frailty >= 1 # μ μ½λλ μ λ’°μ 무κ΄νκ² μ§ν | |
| def test_awareness_established_at_entry(repo): | |
| e = StoryEngine(repo) | |
| e.start() | |
| assert e.state.awareness_established # μμ§ A: λμ 1ν ν립 | |
| def test_trust_path_commits_hidden_branch(repo): | |
| """E06-09 λμ‘°(μ λ’°) β λλ¬μ ν΅κ³Ό ν E06-10C(μ¨κΉ) λΆκΈ°κ° μμ½λλ€.""" | |
| e = play(repo, "trust") | |
| assert "E06-10C" in e.visited | |
| assert "E06-10B" not in e.visited | |
| # ββ μ¨μ μν κ·μΉ βββββββββββββββββββββββββββββββββββββββββββ | |
| def test_frailty_is_monotonic(): | |
| s = HiddenState() | |
| s.advance_frailty() | |
| with pytest.raises(ValueError): | |
| s.advance_frailty(-1) | |
| def test_trust_levels(): | |
| s = HiddenState() | |
| assert s.trust_level == "neutral" | |
| s.trust_score = 40 | |
| assert s.trust_level == "trust_high" and s.deep_unlock | |
| s.doubt_score = 80 | |
| assert s.trust_level == "doubt_high" | |
| def test_condition_parser_rejects_arbitrary_code(): | |
| s = HiddenState() | |
| assert eval_condition("default", s) | |
| assert not eval_condition("doubt_score >= 30", s) | |
| s.doubt_score = 30 | |
| assert eval_condition("doubt_score >= 30", s) | |
| with pytest.raises(ValueError): | |
| eval_condition("__import__('os')", s) | |
| # ββ μ€ν¬μΌλ¬ νν° ββββββββββββββββββββββββββββββββββββββββββββ | |
| def test_spoiler_filter_blocks_future_cards(repo): | |
| with pytest.raises(ContentError): | |
| repo.get_card("E06-10", current_id="E01-01") | |
| assert repo.get_card("E01-01", current_id="E06-10").id == "E01-01" | |
| def test_deep_gate_hidden_until_trust_high(repo): | |
| """E06-09 μ¬μΈ΅ κ³ λ°±(μμ§ D)μ μ λ’°ι«μμλ§ λ ΈμΆ.""" | |
| card = repo.get_card("E06-09") | |
| gated = [b for b in card.narration if b.gate == "trust_high"] | |
| assert gated, "E06-09μ μ¬μΈ΅ κ²μ΄νΈ λΈλ‘μ΄ μμ΄μΌ ν¨" | |
| cold = StoryEngine(repo) | |
| cold.current_id = "E06-09" | |
| assert all(b.gate == "all" for b in cold.visible_narration(card)) | |
| warm = StoryEngine(repo, HiddenState(trust_score=60)) | |
| assert any(b.gate == "trust_high" for b in warm.visible_narration(card)) | |