Skip to content

Commit

Permalink
✨ feat: implement TextMother class for generating random text values
Browse files Browse the repository at this point in the history
  • Loading branch information
adriamontoto committed Dec 21, 2024
1 parent cd64201 commit 95c1c3c
Show file tree
Hide file tree
Showing 3 changed files with 219 additions and 1 deletion.
5 changes: 4 additions & 1 deletion object_mother_pattern/mothers/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from .primitives import BoolMother, IntegerMother
from .primitives import BoolMother, IntegerMother, StringMother
from .text_mother import TextMother

__all__ = (
'BoolMother',
'IntegerMother',
'StringMother',
'TextMother',
)
83 changes: 83 additions & 0 deletions object_mother_pattern/mothers/text_mother.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"""
TextMother module.
"""

from random import choice, randint
from sys import version_info

if version_info >= (3, 12):
from typing import override # pragma: no cover
else:
from typing_extensions import override # pragma: no cover

from .primitives import StringMother


class TextMother(StringMother):
"""
TextMother class.
"""

@classmethod
@override
def create(cls, *, value: str | None = None, min_length: int = 1, max_length: int = 1024) -> str: # noqa: C901
"""
Create a random text between the min and max length, both inclusive.
Args:
min_length (int, optional): Minimum text length. Defaults to 1.
max_length (int, optional): Maximum text length. Defaults to 1024.
Raises:
TypeError: If value is not a string.
TypeError: If min_length is not an integer.
TypeError: If max_length is not an integer.
ValueError: If min_length is less than 0.
ValueError: If max_length is less than 0.
ValueError: If min_length is greater than max_length.
Returns:
str: The randomized text.
"""
if value is not None and type(value) is not str:
raise TypeError('TextMother value must be a string.')

if type(min_length) is not int:
raise TypeError('TextMother min_length must be an integer.')

if type(max_length) is not int:
raise TypeError('TextMother max_length must be an integer.')

if min_length < 0:
raise ValueError('TextMother min_length must be greater than or equal to 0.')

if max_length < 0:
raise ValueError('TextMother max_length must be greater than or equal to 0.')

if min_length > max_length:
raise ValueError('TextMother min_length must be less than or equal to max_length.')

if value is not None:
return value

length = randint(a=min_length, b=max_length)
if length == 0:
return ''

if length == 1:
return '.'

text = cls._random().text(max_nb_chars=20) if length < 5 else cls._random().text(max_nb_chars=length)
while len(text) < length:
text += cls._random().text(max_nb_chars=20) if length < 5 else cls._random().text(max_nb_chars=length)

text = text[:length]
text = text.replace('.', ' ')

# Remove spaces at the end of the text due to the string cut
if text[-2] == ' ':
text = text[:-2] + cls._random().lexify(text='?') + text[-1]

text = text[:-1] + '.'

return choice(seq=(text.lower(), text.upper(), text.title()))
132 changes: 132 additions & 0 deletions tests/mothers/test_text_mother.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"""
Test module for the TextMother class.
"""

from pytest import raises as assert_raises

from object_mother_pattern.mothers import IntegerMother, TextMother


def test_text_mother_happy_path() -> None:
"""
Test TextMother happy path.
"""
value = TextMother.create()

assert type(value) is str
assert 1 <= len(value) <= 1024


def test_text_mother_value() -> None:
"""
Test TextMother create method with value.
"""
value = TextMother.create()

assert TextMother.create(value=value) == value


def test_text_mother_length_equal_to_zero() -> None:
"""
Test TextMother create method with length equal to 0.
"""
value = TextMother.of_length(length=0)

assert value == ''


def test_text_mother_length_equal_to_one() -> None:
"""
Test TextMother create method with length equal to 1.
"""
value = TextMother.of_length(length=1)

assert value == '.'


def test_text_mother_of_length_method() -> None:
"""
Test TextMother of_length method.
"""
text_length = IntegerMother.create(min=2, max=1024)
value = TextMother.of_length(length=text_length)

assert type(value) is str
assert len(value) == text_length
assert value[-1] == '.'


def test_text_mother_invalid_type() -> None:
"""
Test TextMother create method with invalid type.
"""
assert type(TextMother.invalid_type()) is not str


def test_text_mother_invalid_value_type() -> None:
"""
Test TextMother create method with invalid value type.
"""
with assert_raises(
expected_exception=TypeError,
match='TextMother value must be a string.',
):
TextMother.create(value=TextMother.invalid_type())


def test_text_mother_invalid_min_length_type() -> None:
"""
Test TextMother create method with invalid min length type.
"""
with assert_raises(
expected_exception=TypeError,
match='TextMother min_length must be an integer.',
):
TextMother.create(min_length=IntegerMother.invalid_type())


def test_text_mother_invalid_max_length_type() -> None:
"""
Test TextMother create method with invalid max length type.
"""
with assert_raises(
expected_exception=TypeError,
match='TextMother max_length must be an integer.',
):
TextMother.create(max_length=IntegerMother.invalid_type())


def test_text_mother_min_length_less_than_zero() -> None:
"""
Test TextMother create method with min greater than max.
"""
with assert_raises(
expected_exception=ValueError,
match='TextMother min_length must be greater than or equal to 0.',
):
TextMother.create(min_length=IntegerMother.negative())


def test_text_mother_max_length_less_than_zero() -> None:
"""
Test TextMother create method with max less than 0.
"""
with assert_raises(
expected_exception=ValueError,
match='TextMother max_length must be greater than or equal to 0.',
):
TextMother.create(max_length=IntegerMother.negative())


def test_text_mother_min_length_greater_than_max_length() -> None:
"""
Test TextMother create method with min greater than max.
"""
min_value = IntegerMother.create(min=1, max=1024)
max_value = IntegerMother.create(min=1025, max=2048)

with assert_raises(
expected_exception=ValueError,
match='TextMother min_length must be less than or equal to max_length.',
):
TextMother.create(min_length=max_value, max_length=min_value)

0 comments on commit 95c1c3c

Please sign in to comment.