Source code for testoot.base

import mimetypes
from abc import ABC, abstractmethod
from dataclasses import dataclass
from io import IOBase
from typing import Optional


class FileTypeNoExtension:
    pass


[docs]@dataclass class FileType: """File type hint for tests. :param mime: required MIME type :param override_file_ext: override default MIME type extension """ mime: str override_file_ext: Optional[str] = FileTypeNoExtension
[docs] def get_file_extension(self) -> Optional[str]: if self.override_file_ext is not FileTypeNoExtension: return self.override_file_ext return mimetypes.guess_extension(self.mime, strict=False)
[docs]class Comparator(ABC): """Abstract type comparator"""
[docs] @abstractmethod def compare(self, test_obj: any, canon_obj: any): """Compares objects""" pass # pragma: no cover
[docs]class TestootTestResult(ABC): __test__ = False """Abstract test result"""
[docs] @abstractmethod def format_diff(self) -> str: """Format diff""" pass # pragma: no cover
[docs]class TestootSerializer(ABC): __test__ = False """Abstract serializer for objects canonization"""
[docs] def __init__(self, file_type_hint: FileType, mode: str = 'b'): """Init :param file_type_hint: hint for generating file or resource name :param mode: hint for storage stream """ self._file_type_hint = file_type_hint self._mode = mode
[docs] @abstractmethod def load(self, stream: IOBase) -> any: pass # pragma: no cover
[docs] @abstractmethod def dump(self, obj: any, stream: IOBase): pass # pragma: no cover
@property def file_type_hint(self) -> FileType: return self._file_type_hint @property def mode(self): return self._mode
[docs]class TestootContext(ABC): __test__ = False """Abstract test context"""
[docs] @abstractmethod def get_storage_name(self, file_type_hint: FileType, suffix: Optional[str] = None): """Gets name for test""" pass # pragma: no cover
[docs] @abstractmethod def get_storage_name_from_filename(self, filename: str): pass # pragma: no cover
[docs] @abstractmethod def get_serializer(self) -> Optional[TestootSerializer]: pass # pragma: no cover
[docs] @abstractmethod def get_comparator(self) -> Optional[Comparator]: pass # pragma: no cover
[docs] @abstractmethod def ask_canonize(self) -> bool: pass # pragma: no cover
[docs] @abstractmethod def create_test_result(self, test_obj: any, canon_obj: any, exc: Exception) -> TestootTestResult: pass # pragma: no cover
[docs]class CanonizePolicy(ABC): """Abstract run decisions with conflicted tests"""
[docs] @abstractmethod def ask_canonize(self, test_result: TestootTestResult) -> bool: """Asks user for canonization or decide it by internal tests policies""" pass # pragma: no cover
[docs]class TestootStorage(ABC): __test__ = False """Abstract storage for canonized data"""
[docs] @abstractmethod def open_read(self, key: str, mode: str) -> Optional[IOBase]: pass # pragma: no cover
[docs] @abstractmethod def open_write(self, key: str, mode: str) -> IOBase: pass # pragma: no cover
[docs] @abstractmethod def ensure_exists(self): pass # pragma: no cover
[docs] @abstractmethod def clear_if_exists(self): pass # pragma: no cover
[docs] @abstractmethod def clone(self, *, add_path: Optional[str] = None): pass # pragma: no cover
[docs]class UserInteraction(ABC): """Abstract interaction with user"""
[docs] @abstractmethod def ask_canonize(self, test_result: TestootTestResult) -> bool: """Asks user for canonization""" pass # pragma: no cover