Coverage for tests/factories.py: 100%
29 statements
« prev ^ index » next coverage.py v7.10.3, created at 2026-09-13 18:40 +0000
« prev ^ index » next coverage.py v7.10.3, created at 2026-09-13 18:40 +0000
1"""Polyfactory factories for the public data model.
3They keep property style tests honest: instead of hand writing a handful of settings objects we let
4polyfactory build many of them, with the ranges narrowed to values that make sense for a parser.
5"""
7import random
8import typing
10from polyfactory.factories import dataclass_factory
12from meta_tags_parser import structs
15FACTORY_RANDOM_SEED: typing.Final = 20260818
16MAX_GENERATED_LIMIT_CHARS: typing.Final = 8192
17MIN_GENERATED_LIMIT_CHARS: typing.Final = 16
18SHARED_RANDOM_SOURCE: typing.Final = random.Random(FACTORY_RANDOM_SEED)
19KNOWN_BOUNDARY_TAG_PAIRS: typing.Final[tuple[tuple[str, str], ...]] = (
20 ("</head>", "<body"),
21 ("</HEAD>", "<BODY"),
22 ("</head>", "<article"),
23 ("</title>", "<body"),
24)
27@typing.final
28class SettingsFromUserFactory(dataclass_factory.DataclassFactory[structs.SettingsFromUser]):
29 """Build settings objects covering every combination of what_to_parse and slicing limits."""
31 __model__ = structs.SettingsFromUser
32 __random__ = SHARED_RANDOM_SOURCE
34 @classmethod
35 def what_to_parse(cls) -> tuple[structs.WhatToParse, ...]: # noqa: COP009, COP007
36 possible_parts: typing.Final[list[structs.WhatToParse]] = list(structs.WhatToParse)
37 return tuple(cls.__random__.sample(possible_parts, k=cls.__random__.randint(1, len(possible_parts))))
39 @classmethod
40 def boundary_tags(cls) -> tuple[str, str]: # noqa: COP009, COP007
41 return cls.__random__.choice(KNOWN_BOUNDARY_TAG_PAIRS)
43 @classmethod
44 def fallback_limit_chars(cls) -> int: # noqa: COP009, COP007
45 return cls.__random__.randint(MIN_GENERATED_LIMIT_CHARS, MAX_GENERATED_LIMIT_CHARS)
47 @classmethod
48 def max_scan_chars(cls) -> int: # noqa: COP009, COP007
49 return cls.__random__.randint(MIN_GENERATED_LIMIT_CHARS, MAX_GENERATED_LIMIT_CHARS)
51 @classmethod
52 def hard_limit_chars(cls) -> int | None: # noqa: COP009, COP007
53 return cls.__random__.choice(
54 (None, cls.__random__.randint(MIN_GENERATED_LIMIT_CHARS, MAX_GENERATED_LIMIT_CHARS))
55 )