from __future__ import annotations import shlex import subprocess import pytest import hashImage def hamming_distance(h1, h2) -> int: if isinstance(h1, int): n1 = h1 else: n1 = int(h1, 2) if isinstance(h2, int): n2 = h2 else: n2 = int(h2, 2) # xor the two numbers n = n1 ^ n2 # count up the 1's in the binary string return bin(n)[2:].count('1') def test_hash(request, file, record_property): hasher = request.config.getoption('--hasher') try: python = hashImage.main(['-file', file]) + '\n' except Exception: if request.config.getoption('--skip-invalid-image'): pytest.skip('python imagehash failed') return sh = shlex.shlex(hasher, punctuation_chars=True, posix=True) sh.whitespace_split = True cmd_list = list(sh) for i, p in enumerate(cmd_list): if p == '{}': cmd_list[i] = file external = subprocess.run(cmd_list, shell=None, capture_output=True) external_stdout = str(external.stdout, encoding='utf-8') if external.returncode != 0: if request.config.getoption('--skip-invalid-image'): pytest.skip(str(external.stderr)) return external_stdout_h = python_h = '' for p, e in zip(python.splitlines(), external_stdout.splitlines()): p_, e_ = p.split(' '), e.split(' ') h = hamming_distance(p_[1], e_[1]) record_property(p_[0], h) external_stdout_h += ' '.join(e_) + f' {h}\n' python_h += ' '.join(p_) + f' {h}\n' assert external_stdout_h == python_h