Coverage for tests/random_model.py: 79%
75 statements
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-10 03:02 +0300
« prev ^ index » next coverage.py v7.6.2, created at 2024-10-10 03:02 +0300
1import datetime
2import random
3import string
4from enum import Enum
5from types import NoneType
6from typing import Any, get_args
7from uuid import UUID, uuid4
9from bson import ObjectId
10from pydantic import BaseModel, EmailStr
11from pydantic_extra_types.phone_numbers import PhoneNumber
12from sotrans_models.models._base import BaseIdModel
13from sotrans_models.utils.type_checks import (
14 is_list_type,
15 is_not_generic_alias,
16 is_union,
17)
20def generate_random_string(length):
21 return "".join(
22 random.choices(string.ascii_letters + string.digits + " ", k=length)
23 )
26def primitive_types(field_type):
27 if field_type == int:
28 random_value = random.randint(0, 100)
29 elif field_type == float:
30 random_value = random.uniform(0, 1)
31 elif field_type == str: 31 ↛ 34line 31 didn't jump to line 34 because the condition on line 31 was always true
32 random_value = generate_random_string(10)
33 else:
34 random_value = random.choice([True, False])
35 return random_value
38def generate_random_model_dict(model: type[BaseModel]) -> dict[str, Any]:
39 result = {}
41 for field_name, field_info in model.model_fields.items():
42 field_type = field_info.annotation
43 if field_name == "inn": 43 ↛ 44line 43 didn't jump to line 44 because the condition on line 43 was never true
44 result[field_name] = "1234567890"
45 continue
47 if is_union(field_type):
48 args = get_args(field_type)
49 field_type = random.choice(args)
51 if is_list_type(field_type):
52 random_value: Any = []
53 elif is_not_generic_alias(field_type): 53 ↛ 83line 53 didn't jump to line 83 because the condition on line 53 was always true
54 if field_type in (int, float, str, bool):
55 random_value = primitive_types(field_type)
56 elif field_type == dict: 56 ↛ 57line 56 didn't jump to line 57 because the condition on line 56 was never true
57 random_value = {}
58 elif issubclass(field_type, ObjectId): 58 ↛ 59line 58 didn't jump to line 59 because the condition on line 58 was never true
59 random_value = ObjectId()
60 elif issubclass(field_type, UUID): 60 ↛ 61line 60 didn't jump to line 61 because the condition on line 60 was never true
61 random_value = uuid4()
62 elif field_type == datetime.date: 62 ↛ 63line 62 didn't jump to line 63 because the condition on line 62 was never true
63 random_value = datetime.date.today()
64 elif field_type == datetime.datetime:
65 random_value = datetime.datetime.now()
66 elif issubclass(field_type, Enum):
67 random_value = random.choice(list(field_type))
68 elif field_type == PhoneNumber: 68 ↛ 69line 68 didn't jump to line 69 because the condition on line 68 was never true
69 random_value = f"+7999{random.randint(1_000_000, 9_999_999)}"
70 elif field_type == EmailStr: 70 ↛ 71line 70 didn't jump to line 71
71 random_value = (
72 f"{generate_random_string(16).replace(' ', '')}@ya.ru"
73 )
74 elif issubclass(field_type, BaseModel):
75 random_value = generate_random_model_dict(field_type)
76 elif field_type == NoneType: 76 ↛ 79line 76 didn't jump to line 79 because the condition on line 76 was always true
77 random_value = None
78 else:
79 raise TypeError(
80 f"Random value for type {field_type} is not supported"
81 )
82 else:
83 random_value = None
85 # Set the random value in the object dictionary
86 field_alias = (
87 model.model_fields[field_name].validation_alias
88 or model.model_fields[field_name].alias
89 )
90 field_name = field_alias if field_alias else field_name
91 result[field_name] = random_value
93 return result
96def generate_random_model(model: type[BaseModel]) -> BaseModel:
97 return model(**generate_random_model_dict(model))
100def generate_models_json(
101 model: type[BaseModel], specific: dict | None = None
102) -> dict[str, Any]:
103 if specific is None: 103 ↛ 105line 103 didn't jump to line 105 because the condition on line 103 was always true
104 specific = {}
105 model_dict = generate_random_model_dict(model)
106 to_construct = {**model_dict, **specific}
107 params: dict[str, Any] = dict(mode="json")
108 if issubclass(model, BaseIdModel): 108 ↛ 109line 108 didn't jump to line 109 because the condition on line 108 was never true
109 params.update({"format_ids": False})
110 return model(**to_construct).model_dump(**params)