hbutils.testing.compare

Text comparison utilities for testing purposes.

This module serves as the main entry point for text comparison functionality, re-exporting all utilities from the text submodule. It provides tools for comparing and validating text content in various formats and contexts, particularly useful in unit testing scenarios.

The module includes the TextAligner class and related utilities for flexible text comparison, preprocessing, and alignment operations.

Example::
>>> from hbutils.testing.compare import TextAligner
>>> aligner = TextAligner()
>>> # Use aligner for text comparison in tests

TextAligner

class hbutils.testing.compare.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.

__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 str of 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)[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)[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])[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 TextAligner object with line_func process.

Return type:

TextAligner

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 TextAligner object with ls_func process.

Return type:

TextAligner

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 TextAligner object configured for multiple-line mode.

Return type:

TextAligner

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 TextAligner object with text_func process.

Return type:

TextAligner

Example::
>>> from hbutils.testing import TextAligner
>>> text_align = TextAligner()
>>> new_align = text_align.text_trans(str.upper)