hbutils.testing.compare.text
Text alignment and comparison utilities for unit tests.
This module provides TextAligner, a composable helper that normalizes,
transforms, and compares text content. It is designed for test assertions where
text output may require preprocessing such as trimming, dedenting, line mapping,
or custom transformations.
The module contains the following main components:
TextAligner- Configurable text alignment and comparison helper
Example:
>>> from hbutils.testing.compare.text import TextAligner
>>> aligner = TextAligner().multiple_lines()
>>> normalized = aligner('''
... Hello
... World
... ''')
>>> print(normalized)
Hello
World
__all__
- hbutils.testing.compare.text.__all__ = ['TextAligner']
Built-in mutable sequence.
If no argument is given, the constructor creates a new empty list. The argument must be an iterable if specified.
TextAligner
- class hbutils.testing.compare.text.TextAligner(line_rstrip: bool = True, keep_empty_tail: bool = False, text_func: Callable[[str], str] | None = None, line_func: Callable[[str], str] | None = None, ls_func: Callable[[List[str]], List[str]] | None = None)[source]
Text aligner for comparing texts in unittest.
This class provides a flexible way to align, transform, and compare text content. It supports various preprocessing operations and can be chained for complex transformations.
- Parameters:
line_rstrip (bool) – Right strip each line, defaults to
True.keep_empty_tail (bool) – Keep the empty tail of the text, defaults to
False. WhenFalse, trailing empty lines are removed.text_func (Optional[Callable[[str], str]]) – Function for preprocessing the entire text.
line_func (Optional[Callable[[str], str]]) – Function for processing each line.
ls_func (Optional[Callable[[List[str]], List[str]]]) – Function for processing the list of lines.
Example:
>>> from hbutils.testing import TextAligner >>> aligner = TextAligner() >>> print(aligner(''' ... Hello ... World ... ''')) Hello World
- __call__(text: str | List[str]) str[source]
Transform the original text or lines to aligned text.
- Parameters:
text (Union[str, List[str]]) – Original text or lines.
- Returns:
Aligned text.
- Return type:
str
- Examples::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> print(text_align('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) Python 3.6.5 Hello world!! Do not see me like this...
>>> print(text_align.lstrip()('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) Python 3.6.5 Hello world!! Do not see me like this...
- __getattr__(item: str) _StrMethodProxy[source]
Append postprocess from
strof each line.- Parameters:
item (str) – Method name.
- Returns:
A proxy object that wraps the string method.
- Return type:
_StrMethodProxy
- Raises:
AttributeError – If the method is not found in str class.
- Examples::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> print(text_align.lower().multiple_lines()(''' ... Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) python 3.6.5 hello world!! do not see me like this...
- __init__(line_rstrip: bool = True, keep_empty_tail: bool = False, text_func: Callable[[str], str] | None = None, line_func: Callable[[str], str] | None = None, ls_func: Callable[[List[str]], List[str]] | None = None) None[source]
Constructor of
TextAligner.- Parameters:
line_rstrip (bool) – Right strip each line, default is
True.keep_empty_tail (bool) – Keep the empty tail of the text, default is
False, which means the empty tails will be ignored.text_func (Optional[Callable[[str], str]]) – Function for preprocessing whole text.
line_func (Optional[Callable[[str], str]]) – Function for processing each line.
ls_func (Optional[Callable[[List[str]], List[str]]]) – Function for processing lines list.
- assert_equal(expect: str | List[str], actual: str | List[str], max_diff: int = 3, max_extra: int = 5) None[source]
Assert two string is equal.
- Parameters:
expect (Union[str, List[str]]) – Expected text or lines.
actual (Union[str, List[str]]) – Actual text or lines.
max_diff (int) – Max different lines to show in assertion message, default is
3.max_extra (int) – Max extra lines to show in assertion message, default is
5.
- Raises:
AssertionError – If the texts are not equal.
- Examples::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> text_align.multiple_lines().assert_equal('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''', ''' ... Python 3.6.5 ... Hello world!! ... Do not see me like this... ... ''') # this is okay
>>> text_align.multiple_lines().assert_equal('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''', ''' ... Python 3.6.5 ... Hello world!! ... Do not see me like this... ... ''') AssertionError: Difference found in line 3: Expect: Do not see me like this... Actual: Do not see me like this...
- assert_not_equal(expect: str | List[str], actual: str | List[str]) None[source]
Assert two string is not equal, which is similar to
assert_equal().- Parameters:
expect (Union[str, List[str]]) – Expected text or lines.
actual (Union[str, List[str]]) – Actual text or lines.
- Raises:
AssertionError – If the texts are equal.
- Example::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> text_align.assert_not_equal("Hello", "World") # this is okay >>> text_align.assert_not_equal("Hello", "Hello") # this will raise AssertionError
- line_map(line_func: Callable[[str], str]) TextAligner[source]
Mapping for the text of each line.
- Parameters:
line_func (Callable[[str], str]) – New line process function.
- Returns:
A new
TextAlignerobject withline_funcprocess.- Return type:
- Example::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> new_align = text_align.line_map(str.strip)
- ls_trans(ls_func: Callable[[List[str]], List[str]]) TextAligner[source]
Transformation for the separated lines.
- Parameters:
ls_func (Callable[[List[str]], List[str]]) – New lines process function.
- Returns:
A new
TextAlignerobject withls_funcprocess.- Return type:
- Example::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> new_align = text_align.ls_trans(lambda lines: [line for line in lines if line])
- multiple_lines(lstrip: bool = True, dedent: bool = True) TextAligner[source]
Switch to multiple-line mode.
- Parameters:
lstrip (bool) – Left strip the original text.
dedent (bool) – Dedent the text.
- Returns:
A new
TextAlignerobject configured for multiple-line mode.- Return type:
- Examples::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> print(text_align.multiple_lines()(''' ... Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) Python 3.6.5 Hello world!! Do not see me like this...
Note
With
multiple_lines(), the text’s comparison will be compatible with text wrapper.
- splitlines(text: str | List[str]) List[str][source]
Transform the original text or lines to list of aligned lines.
- Parameters:
text (Union[str, List[str]]) – Original text or lines.
- Returns:
List of split lines.
- Return type:
List[str]
- Examples::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> print(text_align.splitlines('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) ['Python 3.6.5', 'Hello world!!', ' Do not see me like this...']
>>> print(text_align.lstrip().splitlines('''Python 3.6.5 ... Hello world!! ... Do not see me like this... ... \n\n\t\n ... ''')) ['Python 3.6.5', 'Hello world!!', 'Do not see me like this...']
- text_trans(text_func: Callable[[str], str]) TextAligner[source]
Transformation for the original text.
- Parameters:
text_func (Callable[[str], str]) – New text process function.
- Returns:
A new
TextAlignerobject withtext_funcprocess.- Return type:
- Example::
>>> from hbutils.testing import TextAligner >>> text_align = TextAligner() >>> new_align = text_align.text_trans(str.upper)