Coverage for src / competitive_verifier / documents / render_data.py: 96%
49 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-05 16:00 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-03-05 16:00 +0000
1import datetime
2import enum
3from collections.abc import Sequence
4from typing import Annotated, Any
6from pydantic import BaseModel, ConfigDict, PlainSerializer, model_validator
7from pydantic.alias_generators import to_camel
9from competitive_verifier.models import ForcePosixPath, SortedPathList, TestcaseResult
12class StatusIcon(str, enum.Enum):
13 @property
14 def is_failed(self) -> bool:
15 return not self.is_success
17 @property
18 def is_success(self) -> bool:
19 return self in (
20 self.LIBRARY_ALL_AC,
21 self.LIBRARY_PARTIAL_AC,
22 self.LIBRARY_NO_TESTS,
23 self.TEST_ACCEPTED,
24 self.TEST_WAITING_JUDGE,
25 )
27 @property
28 def is_test(self) -> bool:
29 return not self.is_library
31 @property
32 def is_library(self) -> bool:
33 return self in (
34 self.LIBRARY_ALL_AC,
35 self.LIBRARY_PARTIAL_AC,
36 self.LIBRARY_SOME_WA,
37 self.LIBRARY_ALL_WA,
38 self.LIBRARY_NO_TESTS,
39 )
41 LIBRARY_ALL_AC = "LIBRARY_ALL_AC"
42 LIBRARY_PARTIAL_AC = "LIBRARY_PARTIAL_AC"
43 LIBRARY_SOME_WA = "LIBRARY_SOME_WA"
44 LIBRARY_ALL_WA = "LIBRARY_ALL_WA"
45 LIBRARY_NO_TESTS = "LIBRARY_NO_TESTS"
46 TEST_ACCEPTED = "TEST_ACCEPTED"
47 TEST_WRONG_ANSWER = "TEST_WRONG_ANSWER"
48 TEST_WAITING_JUDGE = "TEST_WAITING_JUDGE"
51class RenderBaseModel(BaseModel):
52 model_config = ConfigDict(
53 alias_generator=to_camel,
54 populate_by_name=True,
55 extra="allow",
56 )
59class RenderLink(RenderBaseModel):
60 path: ForcePosixPath
61 filename: str
62 icon: StatusIcon
63 title: str | None = None
65 @model_validator(mode="after")
66 def validate_title(self: "RenderLink") -> "RenderLink":
67 if self.path.as_posix() == self.title: 67 ↛ 68line 67 didn't jump to line 68 because the condition on line 67 was never true
68 self.title = None
69 return self
72class Dependency(RenderBaseModel):
73 type: str
74 files: list[RenderLink]
77class EmbeddedCode(RenderBaseModel):
78 name: str
79 code: str
82class EnvTestcaseResult(RenderBaseModel, TestcaseResult):
83 environment: str | None
86class CategorizedIndex(RenderBaseModel):
87 name: str
88 pages: list[RenderLink]
91class IndexFiles(RenderBaseModel):
92 type: str
93 categories: list[CategorizedIndex]
96class PageRenderData(RenderBaseModel):
97 path: ForcePosixPath
98 path_extension: str
99 title: str | None
100 embedded: list[EmbeddedCode]
102 timestamp: Annotated[
103 datetime.datetime,
104 PlainSerializer(lambda x: str(x), return_type=str, when_used="json"),
105 ]
106 attributes: dict[str, Any]
107 testcases: list[EnvTestcaseResult] | None = None
109 is_failed: bool
110 is_verification_file: bool
111 verification_status: StatusIcon
113 depends_on: SortedPathList
114 required_by: SortedPathList
115 verified_with: SortedPathList
117 document_path: ForcePosixPath | None = None
118 dependencies: list[Dependency]
121class CodePageData(PageRenderData):
122 document_content: str | None
125class MultiCodePageData(RenderBaseModel):
126 path: ForcePosixPath
127 verification_status: StatusIcon
128 is_failed: bool
129 codes: Sequence[CodePageData]
130 dependencies: list[Dependency]
133class IndexRenderData(RenderBaseModel):
134 top: list[IndexFiles]