Coverage for glotter/project.py: 100%
40 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-03-01 21:54 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-03-01 21:54 +0000
1from typing import Annotated, ClassVar, Dict, List, Optional
3from glotter_core.project import AcronymScheme, CoreProjectMixin
4from pydantic import BaseModel, Field, ValidationInfo, field_validator
6from glotter.auto_gen_test import AutoGenTest, AutoGenUseTests
7from glotter.errors import raise_simple_validation_error, validate_str_dict, validate_str_list
10class Project(BaseModel, CoreProjectMixin):
11 VALID_REGEX: ClassVar[str] = "^[0-9a-zA-Z]+$"
13 words: Annotated[
14 List[Annotated[str, Field(min_length=1, pattern=VALID_REGEX, strict=True)]],
15 Field(min_length=1, strict=True),
16 ]
17 requires_parameters: bool = False
18 strings: Dict[str, str] = {}
19 acronyms: List[Annotated[str, Field(min_length=1, pattern=VALID_REGEX, strict=True)]] = []
20 acronym_scheme: AcronymScheme = AcronymScheme.two_letter_limit
21 use_tests: Optional[AutoGenUseTests] = None
22 tests: Dict[str, AutoGenTest] = {}
24 @field_validator("acronyms", mode="before")
25 @classmethod
26 def get_acronym(cls, values):
27 validate_str_list(cls, values)
28 return [value.upper() for value in values]
30 @field_validator("strings", mode="before")
31 @classmethod
32 def validate_strings(cls, values):
33 validate_str_dict(cls, values)
34 return values
36 @field_validator("tests", mode="before")
37 @classmethod
38 def get_tests(cls, value, info: ValidationInfo):
39 if not isinstance(value, dict) or not all(
40 isinstance(test, dict) for test in value.values()
41 ):
42 return value
44 if info.data.get("use_tests"):
45 raise_simple_validation_error(
46 cls, '"tests" and "use_tests" items are mutually exclusive', {"use_tests": "..."}
47 )
49 return {
50 test_name: {
51 **test,
52 "requires_parameters": info.data.get("requires_parameters") or False,
53 "strings": info.data.get("strings") or {},
54 "name": test_name,
55 }
56 for test_name, test in value.items()
57 }
59 def set_tests(self, project: "Project"):
60 """
61 If there is a "use_tests" item, then set the specified tests, renaming them
62 according to the "use_tests" item. The "use_tests" item is then removed
64 :params tests: Project with tests to use
65 """
67 if self.use_tests:
68 self.tests = {}
69 for test_name_, test in project.tests.items():
70 test_name = test_name_.replace(self.use_tests.search, self.use_tests.replace)
71 self.tests[test_name] = AutoGenTest(
72 **test.model_dump(exclude={"name"}), name=test_name
73 )
75 self.requires_parameters = project.requires_parameters
76 self.use_tests = None