fineprint-env / tests /test_env.py
vigneshmoovendhan's picture
Fine Print RL final
0b6a889
"""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
@pytest.fixture
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