Skip to content

Commit 5cedce4

Browse files
authored
Enable running tests in CI / PR 8
Enable running tests in CI
2 parents b59c76d + 9b68808 commit 5cedce4

File tree

5 files changed

+51
-14
lines changed

5 files changed

+51
-14
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,5 @@ jobs:
3434
- name: Lint with ruff
3535
run: make lint
3636

37-
# TODO: enable this once all the tests pass
38-
# - name: Run tests
39-
# run: make tests
37+
- name: Run tests
38+
run: make tests

src/guardrails/types.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ class GuardrailResult:
7171
original_exception (Exception | None): The original exception if execution failed.
7272
info (dict[str, Any]): Additional structured data about the check result,
7373
such as error details, matched patterns, or diagnostic messages.
74-
Must include 'checked_text' field containing the processed/validated text.
75-
Defaults to an empty dict.
74+
Implementations may include a 'checked_text' field containing the
75+
processed/validated text when applicable. Defaults to an empty dict.
7676
"""
7777

7878
tripwire_triggered: bool
@@ -82,9 +82,6 @@ class GuardrailResult:
8282

8383
def __post_init__(self) -> None:
8484
"""Validate required fields and consistency."""
85-
if "checked_text" not in self.info:
86-
raise ValueError("GuardrailResult.info must contain 'checked_text' field")
87-
8885
# Ensure consistency: if execution_failed=True, original_exception should be present
8986
if self.execution_failed and self.original_exception is None:
9087
raise ValueError(
@@ -108,5 +105,4 @@ def __post_init__(self) -> None:
108105
TCfg (TypeVar): The configuration type, usually a Pydantic model.
109106
Returns:
110107
GuardrailResult or Awaitable[GuardrailResult]: The outcome of the guardrail check.
111-
The result must include 'checked_text' in the info dict.
112108
"""

tests/unit/test_registry.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,12 @@ def check(_ctx: CtxProto, _value: str, _config: int) -> GuardrailResult:
3737
return GuardrailResult(tripwire_triggered=False)
3838

3939
model = _resolve_ctx_requirements(check)
40-
fields = getattr(model, "model_fields", getattr(model, "__fields__", {}))
40+
# Prefer Pydantic v2 API without eagerly touching deprecated v1 attributes
41+
fields = (
42+
model.model_fields
43+
if hasattr(model, "model_fields")
44+
else getattr(model, "__fields__", {})
45+
)
4146
assert issubclass(model, BaseModel) # noqa: S101
4247
assert set(fields) == {"foo"} # noqa: S101
4348

tests/unit/test_runtime.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,36 @@
2929

3030
@pytest.fixture(autouse=True)
3131
def stub_openai_module(monkeypatch: pytest.MonkeyPatch) -> Iterator[types.ModuleType]:
32-
"""Provide a stub ``openai.AsyncOpenAI`` for modules under test."""
32+
"""Provide a stub ``openai.AsyncOpenAI`` and patch imports in guardrails.*.
33+
34+
Ensures tests don't require real OPENAI_API_KEY or networked clients.
35+
"""
3336
module = types.ModuleType("openai")
3437

35-
class AsyncOpenAI:
38+
class AsyncOpenAI: # noqa: D401 - simple stub
39+
"""Stubbed AsyncOpenAI client."""
40+
3641
pass
3742

3843
module.__dict__["AsyncOpenAI"] = AsyncOpenAI
44+
# Ensure any downstream import finds our stub module
3945
monkeypatch.setitem(sys.modules, "openai", module)
46+
# Also patch already-imported symbols on guardrails modules
47+
try:
48+
import guardrails.runtime as gr_runtime # type: ignore
49+
50+
monkeypatch.setattr(gr_runtime, "AsyncOpenAI", AsyncOpenAI, raising=False)
51+
except Exception:
52+
pass
53+
try:
54+
import guardrails.types as gr_types # type: ignore
55+
56+
monkeypatch.setattr(gr_types, "AsyncOpenAI", AsyncOpenAI, raising=False)
57+
except Exception:
58+
pass
59+
# Provide dummy API key to satisfy any code paths that inspect env
60+
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
61+
4062
yield module
4163
monkeypatch.delitem(sys.modules, "openai", raising=False)
4264

tests/unit/test_types.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,29 @@
1010

1111
@pytest.fixture(autouse=True)
1212
def stub_openai_module(monkeypatch: pytest.MonkeyPatch) -> Iterator[types.ModuleType]:
13-
"""Provide a stub ``openai.AsyncOpenAI`` for modules under test."""
13+
"""Provide a stub ``openai.AsyncOpenAI`` and patch guardrails types symbol.
14+
15+
Ensures tests don't require real OPENAI_API_KEY or networked clients.
16+
"""
1417
module = types.ModuleType("openai")
1518

16-
class AsyncOpenAI:
19+
class AsyncOpenAI: # noqa: D401 - simple stub
20+
"""Stubbed AsyncOpenAI client."""
21+
1722
pass
1823

1924
module.__dict__["AsyncOpenAI"] = AsyncOpenAI
2025
monkeypatch.setitem(sys.modules, "openai", module)
26+
# Patch already-imported symbol in guardrails.types if present
27+
try:
28+
import guardrails.types as gr_types # type: ignore
29+
30+
monkeypatch.setattr(gr_types, "AsyncOpenAI", AsyncOpenAI, raising=False)
31+
except Exception:
32+
pass
33+
# Provide dummy API key in case any code inspects env
34+
monkeypatch.setenv("OPENAI_API_KEY", "test-key")
35+
2136
yield module
2237
monkeypatch.delitem(sys.modules, "openai", raising=False)
2338

0 commit comments

Comments
 (0)