hbutils.testing.isolated

Overview:

Utilities for isolating environment, which can be using in testing.

isolated_directory

hbutils.testing.isolated.isolated_directory(mapping: Optional[Dict[str, str]] = None) → AbstractContextManager[source]
Overview:

Do something in an isolated directory.

Parameters:

mapping – Mappings for the isolated directory.

Examples::
  • Simple usage

>>> import os
>>> import pathlib
>>> from hbutils.testing import isolated_directory
>>>
>>> with isolated_directory():
...     with open('file.txt', 'w') as f:
...         print("Line 1", file=f)
...         print("Line 2rd", file=f)
...     print(os.listdir('.'))
...     print(pathlib.Path('file.txt').read_text())
['file.txt']
Line 1
Line 2rd
>>> print(os.listdir('.'))
['hbutils', 'README.md', 'requirements.txt', ...]
  • Mapping files and directory inside

>>> import os
>>> from hbutils.testing import isolated_directory
>>>
>>> with isolated_directory({
...     'ts': 'hbutils/testing',
...     'README.md': 'README.md',
... }):
...     print(os.listdir('.'))
...     print(os.listdir('ts'))
['README.md', 'ts']
['capture', 'generator', 'isolated', '__init__.py']

isolated_stdin

hbutils.testing.isolated.isolated_stdin(v: Union[str, List[str]], mem: bool = False)[source]
Overview:

Isolation for stdin stream.

Parameters:
  • v – Input content, a whole string or a list of string supported.

  • mem – Use memory or not. Default is False which means a temporary file will be used as fake input stream.

Examples::
>>> from hbutils.testing import isolated_stdin
>>> with isolated_stdin(['123', '456']):
...     a = int(input())
...     b = int(input())
...     print(a, b, a + b)
123 456 579

isolated_entry_points

hbutils.testing.isolated.isolated_entry_points(group: str, fakes: Optional[Union[List, Dict[str, Any]]] = None, auto_import: bool = True, clear: bool = False)[source]
Overview:

Isolation for pkg_resources.iter_entry_points() function. Can be used to fake the plugins, or just disable the installed plugins.

Parameters:
  • group – Group name.

  • fakes – Fake entry points. Dict or list are accepted.

  • auto_import – Auto import the object from string. Default is True which means if a string is given, dynamic import will be performed.

  • clear – Clear the original entry points or not. Default is False which means the original entry points will be kept and be able to be iterated.

Examples::
>>> import pkg_resources
>>> from hbutils.testing import isolated_entry_points
>>> with isolated_entry_points('my_plugin', [
...     (
...             'quick_import_object',  # name import
...             'hbutils.reflection.quick_import_object'
...     ),
...     ('func_filter', filter),  # named entry object
...     map,  # simple function
...     'hbutils.system.is_binary_file',  # simple import
... ]):
...     print({ep.name: ep.load() for ep in
...            pkg_resources.iter_entry_points('my_plugin')})
{'quick_import_object': <function quick_import_object at 0x7fb17f4e5170>, 'func_filter': <class 'filter'>, 'map': <class 'map'>, 'is_binary_file': <function is_binary_file at 0x7fb17f55eef0>}
>>> with isolated_entry_points('my_plugin', {
...     'func_map': map, 'func_binary': 'hbutils.system.is_binary_file'}):
...     print({ep.name: ep.load() for ep in
...            pkg_resources.iter_entry_points('my_plugin')})
{'func_map': <class 'map'>, 'func_binary': <function is_binary_file at 0x7fb17f55eef0>}

isolated_logger

hbutils.testing.isolated.isolated_logger(logger: Optional[Union[str, logging.Logger]] = None, handlers: Optional[List[logging.Handler]] = None, close_handlers: bool = True)[source]
Overview:

Mock loggers in logging module.

Parameters:
  • logger – Logger or logger’s name for isolation.

  • handlers – Initial handlers for isolation.

  • close_handlers – Close handler’s after complete.

Examples::
>>> import logging
>>> from rich.logging import RichHandler  # a 3rd-party logger
>>> from hbutils.testing import isolated_logger
>>>
>>> logging.error('this is error')  # normal log
ERROR:root:this is error
>>> logging.error('this is error')
ERROR:root:this is error
>>> with isolated_logger(handlers=[  # replaced with custom handlers
...     RichHandler(),
...     logging.FileHandler('test_log.txt'),
... ]):
...     logging.error('this is error inside 1')
...     logging.error('this is error inside 2')
[11/08/22 15:39:37] ERROR    this is error inside 1                    <stdin>:5
                    ERROR    this is error inside 2                    <stdin>:6
>>> logging.error('this is error')  # change back to normal log
ERROR:root:this is error
>>> logging.error('this is error')
ERROR:root:this is error