diff --git a/object_mother_pattern/mothers/__init__.py b/object_mother_pattern/mothers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/object_mother_pattern/mothers/base_mother.py b/object_mother_pattern/mothers/base_mother.py new file mode 100644 index 0000000..f4031df --- /dev/null +++ b/object_mother_pattern/mothers/base_mother.py @@ -0,0 +1,102 @@ +""" +BaseMother module. +""" + +from abc import ABC, abstractmethod +from datetime import date, datetime +from random import choice +from typing import Any, Generic, Iterable, TypeVar +from uuid import UUID, uuid4 + +from faker import Faker + +T = TypeVar('T') + + +class BaseMother(ABC, Generic[T]): + """ + BaseMother class. + """ + + _type: type + + @classmethod + def _random(cls) -> Faker: + """ + Get a Faker instance. + + Returns: + Faker: Faker instance. + """ + return Faker(use_weighting=False) + + @classmethod + @abstractmethod + def create(cls, *, value: T | None = None) -> T: + """ + Create a random T. If a value is provided, it will be returned. + + Args: + value (T | None, optional): T value. Defaults to None. + + Returns: + T: Random T. + """ + + @classmethod + def invalid_type(cls, remove_types: Iterable[type[Any]] | None = None) -> Any: # noqa: C901 + """ + Create an invalid type. + + Args: + remove_types (Iterable[type[Any]], optional): Iterable of types to remove. Defaults to None. + + Returns: + Any: Invalid type. + """ + faker = Faker() + + remove_types = set() if remove_types is None else set(remove_types) + remove_types.add(cls._type) + + types: list[Any] = [] + if int not in remove_types: + types.append(faker.pyint()) + + if float not in remove_types: + types.append(faker.pyfloat()) + + if bool not in remove_types: + types.append(faker.pybool()) + + if str not in remove_types: + types.append(faker.pystr()) + + if bytes not in remove_types: + types.append(faker.pystr().encode()) + + if list not in remove_types: + types.append(faker.pylist()) + + if set not in remove_types: + types.append(faker.pyset()) + + if tuple not in remove_types: + types.append(faker.pytuple()) + + if dict not in remove_types: + types.append(faker.pydict()) + + if type(None) not in remove_types: + types.append(None) + + if datetime not in remove_types: + types.append(faker.date_time()) + + if date not in remove_types: + types.append(date.fromisoformat(faker.date())) + + if UUID not in remove_types: + types.append(uuid4()) + + return choice(seq=types) # nosec