forked from openSUSE/docbuild
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_errors.py
More file actions
117 lines (84 loc) · 3.9 KB
/
test_errors.py
File metadata and controls
117 lines (84 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""Tests for the Pydantic error formatting utility."""
import tomllib
from typing import Any
from pydantic import BaseModel, Field, IPvAnyAddress, ValidationError, create_model
from rich.console import Console
from docbuild.constants import DEFAULT_ERROR_LIMIT
from docbuild.utils.errors import format_pydantic_error
class SubModel(BaseModel):
"""A sub-model for testing nested validation."""
name: str = Field(title="Sub Name", description="A sub description")
class MockModel(BaseModel):
"""A mock model for testing top-level validation."""
age: int = Field(title="User Age")
sub: SubModel
def test_format_pydantic_error_smoke(capsys):
"""Smoke test to ensure the formatter runs without crashing with injected console."""
invalid_data: dict[str, Any] = {"age": "not-an-int", "sub": {"name": 123}}
# Create a specific console to test dependency injection
test_console = Console(stderr=True, force_terminal=False)
try:
MockModel(**invalid_data)
except ValidationError as e:
format_pydantic_error(
e, MockModel, "test.toml", verbose=1, console=test_console
)
captured = capsys.readouterr()
assert "Validation error" in captured.err
assert "User Age" in captured.err
assert "A sub description" in captured.err
def test_format_pydantic_error_truncation(capsys):
"""Verify truncation message appears based on DEFAULT_ERROR_LIMIT."""
# Define a dictionary of fields: { 'a': (int, ...), 'b': (int, ...), ... }
# This creates exactly one more field than the allowed display limit.
field_definitions: dict[str, Any] = {
chr(97 + i): (int, ...)
for i in range(DEFAULT_ERROR_LIMIT + 1)
}
# Use create_model with explicit __base__ to satisfy type checkers.
# Renamed to dynamic_model (lowercase) to satisfy Ruff N806.
dynamic_model = create_model(
"DynamicModel",
__base__=BaseModel,
**field_definitions
)
# Create invalid input for all fields
invalid_input = {k: "not-an-int" for k in field_definitions.keys()}
try:
dynamic_model(**invalid_input)
except ValidationError as e:
format_pydantic_error(e, dynamic_model, "test.toml", verbose=0)
captured = capsys.readouterr()
# Check that the footer correctly identifies the hidden error
assert "... and 1 more errors" in captured.err
def test_format_pydantic_error_path_cleaning(capsys):
"""Verify that internal Pydantic tags like [..] are stripped from the path."""
class UnionModel(BaseModel):
# A union often causes Pydantic to add tags like 'function-plain[...]'
host: IPvAnyAddress | str = Field(pattern=r"^[a-z]+$")
# This will fail both IPvAnyAddress and the string regex
invalid_data: dict[str, Any] = {"host": "123-invalid-host"}
try:
UnionModel(**invalid_data)
except ValidationError as e:
format_pydantic_error(e, UnionModel, "test.toml")
captured = capsys.readouterr()
# We want to see 'In 'host'', NOT 'In 'host.function-plain...''
assert "In 'host':" in captured.err
# Verify no bracketed pydantic internals leaked in the path part
assert "[" not in captured.err.split("In '")[1].split("':")[0]
def test_format_toml_error_smoke(capsys):
"""Verify that the TOML syntax error formatter prints correctly."""
from docbuild.utils.errors import format_toml_error
# 1. Manually trigger a TOML syntax error
bad_toml_content = "enable_mail = True" # Invalid: Capital T
try:
tomllib.loads(bad_toml_content)
except tomllib.TOMLDecodeError as e:
# 2. Call our new formatter
format_toml_error(e, "env.devel.toml")
captured = capsys.readouterr()
# 3. Assertions to verify the "Rich" output content
assert "Syntax error in config file 'env.devel.toml'" in captured.err
assert "Invalid value" in captured.err
assert "Booleans must be lowercase" in captured.err