def assert_equal_files(self, obtained_fn, expected_fn, fix_callback=lambda x:x, binary=False, encoding=None):
import os<EOL>from zerotk.easyfs import GetFileContents, GetFileLines<EOL>__tracebackhide__ = True<EOL>import io<EOL>def FindFile(filename):<EOL><INDENT>data_filename = self.get_filename(filename)<EOL>if os.path.isfile(data_filename):<EOL><INDENT>return data_filename<EOL><DEDENT>if os.path.isfile(filename):<EOL><INDENT>return filename<EOL><DEDENT>from ._exceptions import MultipleFilesNotFound<EOL>raise MultipleFilesNotFound([filename, data_filename])<EOL><DEDENT>obtained_fn = FindFile(obtained_fn)<EOL>expected_fn = FindFile(expected_fn)<EOL>if binary:<EOL><INDENT>obtained_lines = GetFileContents(obtained_fn, binary=True)<EOL>expected_lines = GetFileContents(expected_fn, binary=True)<EOL>assert obtained_lines == expected_lines<EOL><DEDENT>else:<EOL><INDENT>obtained_lines = fix_callback(GetFileLines(obtained_fn, encoding=encoding))<EOL>expected_lines = GetFileLines(expected_fn, encoding=encoding)<EOL>if obtained_lines != expected_lines:<EOL><INDENT>html_fn = os.path.splitext(obtained_fn)[<NUM_LIT:0>] + '<STR_LIT>'<EOL>html_diff = self._generate_html_diff(<EOL>expected_fn, expected_lines, obtained_fn, obtained_lines)<EOL>with io.open(html_fn, '<STR_LIT:w>') as f:<EOL><INDENT>f.write(html_diff)<EOL><DEDENT>import difflib<EOL>diff = ['<STR_LIT>', obtained_fn, expected_fn]<EOL>diff += ['<STR_LIT>' % html_fn]<EOL>diff += difflib.context_diff(obtained_lines, expected_lines)<EOL>raise AssertionError('<STR_LIT:\n>'.join(diff) + '<STR_LIT:\n>')<EOL><DEDENT><DEDENT>
Compare two files contents. If the files differ, show the diff and write a nice HTML
diff file into the data directory.

Searches for the filenames both inside and outside the data directory (in that order).

:param unicode obtained_fn: basename to obtained file into the data directory, or full path.

:param unicode expected_fn: basename to expected file into the data directory, or full path.

:param bool binary:
    Thread both files as binary files.

:param unicode encoding:
    File's encoding. If not None, contents obtained from file will be decoded using this
    `encoding`.

:param callable fix_callback:
    A callback to "fix" the contents of the obtained (first) file.
    This callback receives a list of strings (lines) and must also return a list of lines,
    changed as needed.
    The resulting lines will be used to compare with the contents of expected_fn.

:param bool binary:
    .. seealso:: zerotk.easyfs.GetFileContents