Spaces:
Sleeping
Sleeping
| """Tests for the FinePrint environment.""" | |
| import sys | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) | |
| import pytest | |
| import numpy as np | |
| from fineprint.env import FinePrintEnv, ACTION_TYPES | |
| def env(): | |
| policies_path = str(Path(__file__).resolve().parent.parent / "policies") | |
| e = FinePrintEnv(policies_dir=policies_path) | |
| yield e | |
| e.close() | |
| class TestReset: | |
| def test_reset_returns_obs_and_info(self, env): | |
| obs, info = env.reset(seed=42) | |
| assert isinstance(obs, dict) | |
| assert isinstance(info, dict) | |
| def test_reset_obs_keys(self, env): | |
| obs, _ = env.reset(seed=42) | |
| expected_keys = { | |
| "current_workflow", | |
| "current_step", | |
| "workflow_progress", | |
| "user_message", | |
| "conversation_history", | |
| "user_satisfaction", | |
| "agent_believed_version", | |
| "cached_policies", | |
| "steps_since_last_verify", | |
| "system_notification", | |
| "contradiction_detected", | |
| "user_expressed_confusion", | |
| "last_action_compliant", | |
| "last_compliance_note", | |
| } | |
| assert set(obs.keys()) == expected_keys | |
| def test_reset_initial_values(self, env): | |
| obs, info = env.reset(seed=42) | |
| assert obs["agent_believed_version"] == "v1_base" | |
| assert obs["steps_since_last_verify"][0] == 0 | |
| assert obs["user_satisfaction"][0] == 1.0 | |
| assert obs["contradiction_detected"] == 0 | |
| assert obs["user_expressed_confusion"] == 0 | |
| def test_reset_info_contains_version(self, env): | |
| _, info = env.reset(seed=42) | |
| assert info["active_version"] == "v1_base" | |
| assert info["total_versions"] == 8 | |
| def test_reset_reproducibility(self, env): | |
| obs1, _ = env.reset(seed=42) | |
| obs2, _ = env.reset(seed=42) | |
| assert obs1["current_workflow"] == obs2["current_workflow"] | |
| class TestStep: | |
| def test_step_returns_5_tuple(self, env): | |
| env.reset(seed=42) | |
| result = env.step({"action_type": 5, "message": "Hello"}) | |
| assert len(result) == 5 | |
| obs, reward, terminated, truncated, info = result | |
| assert isinstance(obs, dict) | |
| assert isinstance(reward, float) | |
| assert isinstance(terminated, bool) | |
| assert isinstance(truncated, bool) | |
| assert isinstance(info, dict) | |
| def test_step_without_reset_raises(self, env): | |
| with pytest.raises(RuntimeError): | |
| env.step({"action_type": 5}) | |
| def test_request_verification(self, env): | |
| env.reset(seed=42) | |
| obs, reward, _, _, info = env.step({"action_type": 0}) | |
| assert info["compliance"]["compliant"] is True | |
| assert "Verified" in info["compliance"]["reason"] | |
| def test_quote_policy_correct(self, env): | |
| env.reset(seed=42) | |
| # First verify to ensure cache is fresh | |
| env.step({"action_type": 0}) | |
| # Quote a known v1_base value | |
| obs, reward, _, _, info = env.step({ | |
| "action_type": 1, | |
| "policy_field": "return.window_days", | |
| "quoted_value": "30", | |
| }) | |
| assert info["compliance"]["compliant"] is True | |
| assert reward > 0 | |
| def test_quote_policy_incorrect(self, env): | |
| env.reset(seed=42) | |
| obs, reward, _, _, info = env.step({ | |
| "action_type": 1, | |
| "policy_field": "return.window_days", | |
| "quoted_value": "999", | |
| }) | |
| assert info["compliance"]["compliant"] is False | |
| def test_episode_terminates(self, env): | |
| env.reset(seed=42) | |
| done = False | |
| steps = 0 | |
| while not done and steps < 100: | |
| _, _, terminated, truncated, _ = env.step( | |
| {"action_type": 5, "message": "OK"} | |
| ) | |
| done = terminated or truncated | |
| steps += 1 | |
| assert done | |
| def test_info_contains_metrics(self, env): | |
| env.reset(seed=42) | |
| _, _, _, _, info = env.step({"action_type": 5, "message": "Hi"}) | |
| assert "compliance_failures" in info | |
| assert "drift_detections" in info | |
| assert "user_satisfaction" in info | |
| assert "active_version" in info | |
| assert "agent_version" in info | |
| class TestRender: | |
| def test_render_ansi(self, env): | |
| env.reset(seed=42) | |
| output = env.render(mode="ansi") | |
| assert isinstance(output, str) | |
| assert "FINEPRINT" in output | |
| def test_render_before_reset(self, env): | |
| result = env.render(mode="ansi") | |
| assert result is None | |
| class TestClose: | |
| def test_close(self, env): | |
| env.reset(seed=42) | |
| env.close() | |
| assert env.state is None | |