1from functools import partial 2 3from .common import perform_regression_check, check_text_files 4 5 6class FileRegressionFixture: 7 """ 8 Implementation of `file_regression` fixture. 9 """ 10 11 def __init__(self, datadir, original_datadir, request): 12 """ 13 :type datadir: Path 14 :type original_datadir: Path 15 :type request: FixtureRequest 16 """ 17 self.request = request 18 self.datadir = datadir 19 self.original_datadir = original_datadir 20 self.force_regen = False 21 22 def check( 23 self, 24 contents, 25 encoding=None, 26 extension=".txt", 27 newline=None, 28 basename=None, 29 fullpath=None, 30 binary=False, 31 obtained_filename=None, 32 check_fn=None, 33 ): 34 """ 35 Checks the contents against a previously recorded version, or generate a new file. 36 37 :param str contents: content to be verified. 38 :param str|None encoding: Encoding used to write file, if any. 39 :param str extension: Extension of file. 40 :param str|None newline: See `io.open` docs. 41 :param bool binary: If the file is binary or text. 42 :param obtained_filename: ..see:: FileRegressionCheck 43 :param check_fn: a function with signature ``(obtained_filename, expected_filename)`` that should raise 44 AssertionError if both files differ. 45 If not given, use internal function which compares text using :py:mod:`difflib`. 46 """ 47 __tracebackhide__ = True 48 49 if binary and encoding: 50 raise ValueError( 51 "Only binary ({!r}) or encoding ({!r}) parameters must be passed at the same time.".format( 52 binary, encoding 53 ) 54 ) 55 56 if binary: 57 assert isinstance( 58 contents, bytes 59 ), "Expected bytes contents but received type {}".format( 60 type(contents).__name__ 61 ) 62 else: 63 assert isinstance( 64 contents, str 65 ), "Expected text/unicode contents but received type {}".format( 66 type(contents).__name__ 67 ) 68 69 import io 70 71 if check_fn is None: 72 73 if binary: 74 75 def check_fn(obtained_filename, expected_filename): 76 if obtained_filename.read_bytes() != expected_filename.read_bytes(): 77 raise AssertionError( 78 "Binary files {} and {} differ.".format( 79 obtained_filename, expected_filename 80 ) 81 ) 82 83 else: 84 check_fn = partial(check_text_files, encoding=encoding) 85 86 def dump_fn(filename): 87 mode = "wb" if binary else "w" 88 with open(str(filename), mode, encoding=encoding, newline=newline) as f: 89 f.write(contents) 90 91 perform_regression_check( 92 datadir=self.datadir, 93 original_datadir=self.original_datadir, 94 request=self.request, 95 check_fn=check_fn, 96 dump_fn=dump_fn, 97 extension=extension, 98 basename=basename, 99 fullpath=fullpath, 100 force_regen=self.force_regen, 101 obtained_filename=obtained_filename, 102 ) 103 104 # non-PEP 8 alias used internally at ESSS 105 Check = check 106