Coverage for structured_tutorials / models / tests.py: 100%
24 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-23 20:24 +0100
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-23 20:24 +0100
1# Copyright (c) 2025 Mathias Ertl
2# Licensed under the MIT License. See LICENSE file for details.
4"""Test specifications for commands."""
6import re
7from typing import Annotated, Literal
9from pydantic import BaseModel, BeforeValidator, ConfigDict, Field, model_validator
11from structured_tutorials.models.base import CommandBaseModel, CommandType, TestSpecificationMixin
12from structured_tutorials.models.validators import validate_regex
13from structured_tutorials.typing import COUNT_TYPE, Self
16class TestCommandModel(TestSpecificationMixin, CommandBaseModel):
17 """Test a command by running another command."""
19 model_config = ConfigDict(extra="forbid")
21 command: CommandType = Field(description="The command to run.")
24class TestPortModel(TestSpecificationMixin, BaseModel):
25 """Test a command by checking if a port is open."""
27 model_config = ConfigDict(extra="forbid")
29 host: str = Field(description="The host to connect to.")
30 port: Annotated[int, Field(ge=0, le=65535)] = Field(description="The port to connect to.")
33class TestOutputModel(BaseModel):
34 """Test a command by checking the output of a command."""
36 model_config = ConfigDict(extra="forbid")
38 stream: Literal["stdout", "stderr"] = Field(default="stdout", description="The output stream to use.")
39 regex: Annotated[re.Pattern[bytes], BeforeValidator(validate_regex)] | None = Field(
40 default=None, description="A regular expression to test."
41 )
42 line_count: COUNT_TYPE = Field(default=None, description="Test for the given line count.")
43 character_count: COUNT_TYPE = Field(default=None, description="Test for the given character count.")
45 @model_validator(mode="after")
46 def validate_tests(self) -> Self:
47 if not self.regex and not self.line_count and not self.character_count:
48 raise ValueError("At least one test must be specified.")
49 return self