├── .coveragerc ├── .travis.yml ├── COPYING ├── MANIFEST.in ├── README.rst ├── bin └── diffoscope ├── debian ├── README.source ├── changelog ├── check-dep-sizes.sh ├── clean ├── compat ├── control ├── copyright ├── diffoscope.1.rst ├── diffoscope.docs ├── diffoscope.install ├── diffoscope.manpages ├── gbp.conf ├── py3dist-overrides ├── rules ├── source │ ├── format │ ├── lintian-overrides │ └── options ├── tests │ ├── basic-command-line │ ├── control │ └── pytest ├── upstream │ └── signing-key.asc └── watch ├── diffoscope ├── __init__.py ├── changes.py ├── comparators │ ├── __init__.py │ ├── apk.py │ ├── ar.py │ ├── binary.py │ ├── bzip2.py │ ├── cbfs.py │ ├── cpio.py │ ├── deb.py │ ├── debian.py │ ├── debian_fallback.py │ ├── device.py │ ├── dex.py │ ├── directory.py │ ├── elf.py │ ├── fonts.py │ ├── fsimage.py │ ├── gettext.py │ ├── git.py │ ├── gzip.py │ ├── haskell.py │ ├── icc.py │ ├── image.py │ ├── ipk.py │ ├── iso9660.py │ ├── java.py │ ├── javascript.py │ ├── json.py │ ├── llvm.py │ ├── macho.py │ ├── missing_file.py │ ├── mono.py │ ├── openssh.py │ ├── pdf.py │ ├── png.py │ ├── ppu.py │ ├── ps.py │ ├── rpm.py │ ├── rpm_fallback.py │ ├── rust.py │ ├── sqlite.py │ ├── squashfs.py │ ├── symlink.py │ ├── tar.py │ ├── text.py │ ├── utils │ │ ├── __init__.py │ │ ├── archive.py │ │ ├── command.py │ │ ├── compare.py │ │ ├── container.py │ │ ├── file.py │ │ ├── filenames.py │ │ ├── fuzzy.py │ │ ├── libarchive.py │ │ └── specialize.py │ ├── xz.py │ └── zip.py ├── config.py ├── diff.py ├── difference.py ├── exc.py ├── excludes.py ├── external_tools.py ├── locale.py ├── logging.py ├── main.py ├── presenters │ ├── __init__.py │ ├── formats.py │ ├── html │ │ ├── __init__.py │ │ ├── html.py │ │ ├── linediff.py │ │ └── templates.py │ ├── icon.py │ ├── json.py │ ├── markdown.py │ ├── restructuredtext.py │ ├── text.py │ └── utils.py ├── profiling.py ├── progress.py ├── tempfiles.py └── tools.py ├── logo.svg ├── setup.py └── tests ├── comparators ├── test_apk.py ├── test_binary.py ├── test_bzip2.py ├── test_cbfs.py ├── test_cpio.py ├── test_deb.py ├── test_debian.py ├── test_device.py ├── test_dex.py ├── test_directory.py ├── test_elf.py ├── test_epub.py ├── test_fonts.py ├── test_fsimage.py ├── test_gettext.py ├── test_git.py ├── test_gzip.py ├── test_haskell.py ├── test_icc.py ├── test_ico_image.py ├── test_ipk.py ├── test_iso9660.py ├── test_java.py ├── test_javascript.py ├── test_jpeg_image.py ├── test_json.py ├── test_macho.py ├── test_mono.py ├── test_openssh_pub_key.py ├── test_pdf.py ├── test_png.py ├── test_ppu.py ├── test_ps.py ├── test_rlib.py ├── test_rpm.py ├── test_sqlite.py ├── test_squashfs.py ├── test_symlink.py ├── test_tar.py ├── test_text.py ├── test_utils.py ├── test_xz.py ├── test_zip.py └── utils │ ├── __init__.py │ ├── data.py │ ├── nonexisting.py │ └── tools.py ├── conftest.py ├── data ├── Samyak-Malayalam1.ttf ├── Samyak-Malayalam2.ttf ├── Test1.class ├── Test2.class ├── apk_manifest_expected_diff ├── apk_zipinfo_expected_diff ├── base-files_157-r45695_ar71xx.ipk ├── base-files_157-r45918_ar71xx.ipk ├── binary1 ├── binary2 ├── binary_expected_diff ├── binary_hexdump_expected_diff ├── cbfs_listing_expected_diff ├── class_expected_diff ├── cpio_listing_expected_diff ├── dbgsym │ ├── add │ │ ├── test-dbgsym-dbgsym_1_amd64.deb │ │ └── test-dbgsym_1_amd64.deb │ ├── mult │ │ ├── test-dbgsym-dbgsym_1_amd64.deb │ │ └── test-dbgsym_1_amd64.deb │ ├── test-dbgsym_1.dsc │ └── test-dbgsym_1.tar.gz ├── deb_metadata_expected_diff ├── device_expected_diff ├── device_expected_diff_reverse ├── dex_expected_diffs ├── dot_buildinfo_fallback_expected_diff ├── dot_changes_description_expected_diff ├── dot_changes_different_contents_and_identical_files_expected_diff ├── dot_changes_fallback_expected_diff ├── dot_changes_identical_contents_and_different_files_expected_diff ├── dot_dsc_fallback_expected_diff ├── elf_lib_metadata_expected_diff ├── elf_lib_objdump_expected_diff ├── elf_obj_expected_diff ├── epub_expected_diffs ├── ext4_expected_diffs ├── fuzzy-tar-in-tar1.tar ├── fuzzy-tar-in-tar2.tar ├── fuzzy1.tar ├── fuzzy2.tar ├── fuzzy3.tar ├── git_expected_diff ├── gnu_debuglink_expected_diff ├── gzip_metadata_expected_diff ├── haskell_expected_diff ├── icc_expected_diff ├── ico_image_expected_diff ├── ico_image_meta_expected_diff ├── index.html ├── ipk_metadata_expected_diff ├── iso9660_content_expected_diff ├── iso9660_rockridge_expected_diff ├── javascript_expected_diff ├── jpeg_image_expected_diff ├── jpeg_image_meta_expected_diff ├── json_expected_diff ├── macho_expected_diff_arch ├── macho_expected_diff_disassembly ├── macho_expected_diff_headers ├── macho_expected_diff_loadcommands ├── mo_charsets_expected_diff ├── mo_expected_diff ├── mozzip_zipinfo_expected_diff ├── no-perms.tar ├── openssh_pub_key_expected_diff ├── order1.diff ├── order1a.json ├── order1b.json ├── output.colored.txt ├── output.html ├── output.json ├── output.md ├── output.rst ├── output.txt ├── pdf_internal_expected_diff ├── pdf_text_expected_diff ├── pe_expected_diff ├── png_expected_diff ├── ppu_expected_diff ├── ps_internal_expected_diff ├── ps_text_expected_diff ├── rlib_armap_expected_diff ├── rlib_elf_expected_diff ├── rlib_llvm_dis_expected_diff ├── rpm_fallback_expected_diff ├── rpm_header_expected_diff ├── rpm_listing_expected_diff ├── sqlite3_expected_diff ├── squashfs_superblock_expected_diff ├── symlink_expected_destination_diff ├── symlink_expected_diff ├── tar_listing_expected_diff ├── test1.a ├── test1.apk ├── test1.buildinfo ├── test1.bz2 ├── test1.changes ├── test1.cpio ├── test1.deb ├── test1.debsrc.tar.gz ├── test1.dex ├── test1.dsc ├── test1.epub ├── test1.exe ├── test1.ext4 ├── test1.git-index ├── test1.gz ├── test1.hi ├── test1.icc ├── test1.ico ├── test1.iso ├── test1.jpg ├── test1.js ├── test1.json ├── test1.macho ├── test1.mo ├── test1.mozzip ├── test1.o ├── test1.pdf ├── test1.png ├── test1.ppu ├── test1.ps ├── test1.rlib ├── test1.rpm ├── test1.sqlite3 ├── test1.squashfs ├── test1.tar ├── test1.xz ├── test1.zip ├── test1_meta.ico ├── test1_meta.jpg ├── test2.a ├── test2.apk ├── test2.buildinfo ├── test2.bz2 ├── test2.changes ├── test2.cpio ├── test2.deb ├── test2.debsrc.tar.gz ├── test2.dex ├── test2.dsc ├── test2.epub ├── test2.exe ├── test2.ext4 ├── test2.git-index ├── test2.gz ├── test2.hi ├── test2.icc ├── test2.ico ├── test2.iso ├── test2.jpg ├── test2.js ├── test2.json ├── test2.macho ├── test2.mo ├── test2.mozzip ├── test2.o ├── test2.pdf ├── test2.png ├── test2.ppu ├── test2.ps ├── test2.rlib ├── test2.rpm ├── test2.sqlite3 ├── test2.squashfs ├── test2.tar ├── test2.xz ├── test2.zip ├── test2_meta.ico ├── test2_meta.jpg ├── test3.changes ├── test4.changes ├── test_directory_device_diff ├── test_directory_file_diff ├── test_directory_symlink_diff ├── test_invalid.json ├── test_iso8859-1.mo ├── test_no_charset.mo ├── test_openssh_pub_key1.pub ├── test_openssh_pub_key2.pub ├── text_ascii1 ├── text_ascii2 ├── text_ascii_expected_diff ├── text_iso8859 ├── text_iso8859_expected_diff ├── text_order1 ├── text_order2 ├── text_order_expected_diff ├── text_unicode1 ├── text_unicode2 ├── text_unicode_binary_fallback ├── text_unicode_expected_diff ├── ttf_expected_diff └── zip_zipinfo_expected_diff ├── test_difference.py ├── test_excludes.py ├── test_main.py ├── test_presenters.py └── test_progress.py /.coveragerc: -------------------------------------------------------------------------------- 1 | [report] 2 | exclude_lines = 3 | noqa 4 | raise NotImplementedError 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | language: generic 3 | 4 | services: 5 | - docker 6 | 7 | script: 8 | - wget -O- http://travis.debian.net/script.sh | sh - 9 | 10 | branches: 11 | except: 12 | - /^debian\/\d/ 13 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include COPYING 2 | include README.rst 3 | graft tests 4 | -------------------------------------------------------------------------------- /bin/diffoscope: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # PYTHON_ARGCOMPLETE_OK 3 | # -*- coding: utf-8 -*- 4 | # 5 | # diffoscope: in-depth comparison of files, archives, and directories 6 | # 7 | # Copyright © 2014-2015 Jérémy Bobbio 8 | # 9 | # diffoscope is free software: you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation, either version 3 of the License, or 12 | # (at your option) any later version. 13 | # 14 | # diffoscope is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with diffoscope. If not, see . 21 | 22 | import os 23 | import sys 24 | 25 | 26 | # Prefer local modules over any system-installed ones to ensure that running a 27 | # Git version from any current working directory does not have unexpected 28 | # behaviour. 29 | parent = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 30 | if os.path.exists(os.path.join(parent, 'diffoscope', '__init__.py')): 31 | sys.path.insert(0, parent) 32 | 33 | from diffoscope.main import main 34 | 35 | if __name__ == '__main__': 36 | main() 37 | -------------------------------------------------------------------------------- /debian/README.source: -------------------------------------------------------------------------------- 1 | diffoscope: hacking tips 2 | ======================== 3 | 4 | Running the test suite 5 | ---------------------- 6 | 7 | Tests are meant to be run with PyTest. The easiest way is simple to run 8 | the tests are then: 9 | 10 | $ py.test 11 | 12 | To get code coverage: 13 | 14 | $ py.test --cov diffoscope --cov-report html 15 | -------------------------------------------------------------------------------- /debian/check-dep-sizes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Check sizes of diffoscope's dependencies (including recommends) 3 | # Give ~i to only list packages installed on your system. 4 | pkg=diffoscope 5 | d=~R 6 | r=~Rrecommends: 7 | LC_ALL=C aptitude search "($d$pkg|$r$pkg|$d$d$pkg|$d$r$pkg|$r$d$pkg|$r$r$pkg) $1" \ 8 | --disable-columns -F '%I %p' \ 9 | | sed -e 's/ kB / KB /g' \ 10 | | LC_ALL=C sort -k2,2 -k1n,1n \ 11 | | sed -e 's/ KB / kB /g' 12 | -------------------------------------------------------------------------------- /debian/clean: -------------------------------------------------------------------------------- 1 | debian/diffoscope.1 2 | debian/diffoscope.bash-completion 3 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /debian/diffoscope.docs: -------------------------------------------------------------------------------- 1 | README.rst 2 | -------------------------------------------------------------------------------- /debian/diffoscope.install: -------------------------------------------------------------------------------- 1 | bin/diffoscope usr/bin 2 | -------------------------------------------------------------------------------- /debian/diffoscope.manpages: -------------------------------------------------------------------------------- 1 | debian/diffoscope.1 2 | -------------------------------------------------------------------------------- /debian/gbp.conf: -------------------------------------------------------------------------------- 1 | [DEFAULT] 2 | # We override the default builder because we don't want '-i -I': we want to 3 | # get the .a and .o files that are part of the test suite included. 4 | builder = debuild 5 | 6 | [buildpackage] 7 | debian-tag = %(version)s 8 | -------------------------------------------------------------------------------- /debian/py3dist-overrides: -------------------------------------------------------------------------------- 1 | tlsh python3-tlsh (>= 3.4.1) 2 | python-magic python3-magic 3 | guestfs python3-guestfs 4 | -------------------------------------------------------------------------------- /debian/source/format: -------------------------------------------------------------------------------- 1 | 3.0 (native) 2 | -------------------------------------------------------------------------------- /debian/source/lintian-overrides: -------------------------------------------------------------------------------- 1 | # This will mainly be used to double check that what we upload to Debian 2 | # is also in our "archive". 3 | debian-watch-file-in-native-package 4 | -------------------------------------------------------------------------------- /debian/source/options: -------------------------------------------------------------------------------- 1 | # Default ignore patterns contains *.o and *.a. So we need to define our own 2 | # patterns to get them included. 3 | --tar-ignore=.*.sw? 4 | --tar-ignore=*/*~ 5 | --tar-ignore=,,* 6 | --tar-ignore=.[#~]* 7 | --tar-ignore=.deps 8 | --tar-ignore=.git 9 | --tar-ignore=.gitattributes 10 | --tar-ignore=.gitignore 11 | --tar-ignore=.gitmodules 12 | -------------------------------------------------------------------------------- /debian/tests/basic-command-line: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # not set -e: we are testing exit codes 4 | 5 | # to have diffoscope able to output stuff in utf-8 6 | export LC_ALL=C.UTF-8 7 | 8 | if ! [ -d "$ADTTMP" ]; then 9 | ADTTMP=`mktemp -d` 10 | TEMP=true 11 | fi 12 | 13 | echo "a" > $ADTTMP/a 14 | echo "a" > $ADTTMP/a_ 15 | echo "b" > $ADTTMP/b 16 | 17 | echo "Testing identical files..." 18 | diffoscope $ADTTMP/a $ADTTMP/a_ 19 | if [ $? -ne 0 ]; then 20 | echo "Exit code was different from 0 when comparing files with identical content." >&2 21 | exit 1 22 | fi 23 | 24 | echo "Testing different files..." 25 | diffoscope $ADTTMP/a $ADTTMP/b 26 | if [ $? -ne 1 ]; then 27 | echo "Exit code was different from 1 when comparing files with different content." >&2 28 | exit 1 29 | fi 30 | 31 | echo "Testing LC_ALL=C works..." 32 | LC_ALL=C diffoscope --debug $ADTTMP/a $ADTTMP/a_ 2>/dev/null 33 | if [ $? -ne 0 ]; then 34 | echo "diffoscope could not handle LC_ALL=C; make sure you're not unconditionally outputting non-ascii chars anywhere." >&2 35 | exit 1 36 | fi 37 | 38 | echo "Testing LC_ALL=C works (--help)..." 39 | LC_ALL=C diffoscope --help >/dev/null 40 | if [ $? -ne 0 ]; then 41 | echo "diffoscope could not handle LC_ALL=C; make sure you're not unconditionally outputting non-ascii chars anywhere." >&2 42 | exit 1 43 | fi 44 | 45 | echo "Testing invalid command line flag..." 46 | diffoscope --thisflagdoesntexistandwontexist 47 | if [ $? -ne 2 ]; then 48 | echo "Exit code was different from 2 when passing a non-existent flag." >&2 49 | exit 1 50 | fi 51 | 52 | if [ -n "${TEMP:-}" ]; then 53 | rm -rf "$ADTTMP" 54 | fi 55 | 56 | echo "All good!" 57 | -------------------------------------------------------------------------------- /debian/tests/control: -------------------------------------------------------------------------------- 1 | Tests: pytest 2 | Depends: diffoscope, python3-pytest 3 | Restrictions: needs-recommends 4 | 5 | Test-Command: debian/tests/pytest 6 | Depends: diffoscope, python3-pytest 7 | # but without Recommends 8 | 9 | Tests: basic-command-line 10 | Depends: diffoscope 11 | Restrictions: allow-stderr 12 | # without Recommends 13 | -------------------------------------------------------------------------------- /debian/tests/pytest: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if ! [ -d "$ADTTMP" ]; then 6 | echo "ADTTMP not set." >&2 7 | exit 1 8 | fi 9 | 10 | export LIBGUESTFS_MEMSIZE=128 11 | 12 | cp -r tests $ADTTMP 13 | (cd $ADTTMP; py.test-3 -vv -l -r a) 14 | -------------------------------------------------------------------------------- /debian/watch: -------------------------------------------------------------------------------- 1 | version=3 2 | opts=pgpsigurlmangle=s/$/.asc/ http://reproducible.alioth.debian.org/releases/diffoscope/diffoscope-(.+).tar.bz2 3 | -------------------------------------------------------------------------------- /diffoscope/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | VERSION = "78" 21 | -------------------------------------------------------------------------------- /diffoscope/comparators/binary.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | import stat 22 | 23 | from .utils.file import File 24 | 25 | 26 | class FilesystemFile(File): 27 | def __init__(self, path, container=None): 28 | super().__init__(container=container) 29 | self._name = path 30 | 31 | @property 32 | def path(self): 33 | return self._name 34 | 35 | def is_directory(self): 36 | return not os.path.islink(self._name) and os.path.isdir(self._name) 37 | 38 | def is_symlink(self): 39 | return os.path.islink(self._name) 40 | 41 | def is_device(self): 42 | mode = os.lstat(self._name).st_mode 43 | return stat.S_ISCHR(mode) or stat.S_ISBLK(mode) 44 | -------------------------------------------------------------------------------- /diffoscope/comparators/bzip2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import os.path 22 | import logging 23 | import subprocess 24 | import collections 25 | 26 | from diffoscope.tools import tool_required 27 | 28 | from .utils.file import File 29 | from .utils.archive import Archive 30 | from .utils.filenames import get_compressed_content_name 31 | 32 | logger = logging.getLogger(__name__) 33 | 34 | 35 | class Bzip2Container(Archive): 36 | def open_archive(self): 37 | return self 38 | 39 | def close_archive(self): 40 | pass 41 | 42 | def get_members(self): 43 | return collections.OrderedDict({'bzip2-content': self.get_member(self.get_member_names()[0])}) 44 | 45 | def get_member_names(self): 46 | return [get_compressed_content_name(self.source.path, '.bz2')] 47 | 48 | @tool_required('bzip2') 49 | def extract(self, member_name, dest_dir): 50 | dest_path = os.path.join(dest_dir, member_name) 51 | logger.debug('bzip2 extracting to %s', dest_path) 52 | with open(dest_path, 'wb') as fp: 53 | subprocess.check_call( 54 | ["bzip2", "--decompress", "--stdout", self.source.path], 55 | shell=False, stdout=fp, stderr=None) 56 | return dest_path 57 | 58 | 59 | class Bzip2File(File): 60 | CONTAINER_CLASS = Bzip2Container 61 | RE_FILE_TYPE = re.compile(r'^bzip2 compressed data\b') 62 | -------------------------------------------------------------------------------- /diffoscope/comparators/cpio.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Reiner Herrmann 6 | # 2015 Jérémy Bobbio 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | import re 22 | 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.libarchive import LibarchiveContainer, list_libarchive 27 | 28 | 29 | class CpioFile(File): 30 | CONTAINER_CLASS = LibarchiveContainer 31 | RE_FILE_TYPE = re.compile(r'\bcpio archive\b') 32 | 33 | def compare_details(self, other, source=None): 34 | return [Difference.from_text_readers( 35 | list_libarchive(self.path), 36 | list_libarchive(other.path), 37 | self.path, 38 | other.path, 39 | source="file list", 40 | )] 41 | -------------------------------------------------------------------------------- /diffoscope/comparators/debian_fallback.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from .text import TextFile 23 | 24 | 25 | class DotChangesFile(TextFile): 26 | RE_FILE_EXTENSION = re.compile(r'\.changes$') 27 | 28 | def compare(self, other, source=None): 29 | difference = super().compare(other) 30 | if not difference: 31 | return None 32 | difference.add_comment('Unable to find Python debian module. Falling back to text comparison.') 33 | return difference 34 | 35 | class DotDscFile(TextFile): 36 | RE_FILE_EXTENSION = re.compile(r'\.dsc$') 37 | 38 | def compare(self, other, source=None): 39 | difference = super().compare(other) 40 | if not difference: 41 | return None 42 | difference.add_comment('Unable to find Python debian module. Falling back to text comparison.') 43 | return difference 44 | 45 | class DotBuildinfoFile(TextFile): 46 | RE_FILE_EXTENSION = re.compile(r'\.buildinfo$') 47 | 48 | def compare(self, other, source=None): 49 | difference = super().compare(other) 50 | if not difference: 51 | return None 52 | difference.add_comment('Unable to find Python debian module. Falling back to text comparison.') 53 | return difference 54 | -------------------------------------------------------------------------------- /diffoscope/comparators/dex.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Reiner Herrmann 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import os.path 22 | import logging 23 | import subprocess 24 | import collections 25 | 26 | from diffoscope.tools import tool_required 27 | 28 | from .utils.file import File 29 | from .utils.archive import Archive 30 | from .utils.filenames import get_compressed_content_name 31 | 32 | logger = logging.getLogger(__name__) 33 | 34 | 35 | class DexContainer(Archive): 36 | @property 37 | def path(self): 38 | return self._path 39 | 40 | def open_archive(self): 41 | return self 42 | 43 | def close_archive(self): 44 | pass 45 | 46 | def get_members(self): 47 | return collections.OrderedDict({'dex-content': self.get_member(self.get_member_names()[0])}) 48 | 49 | def get_member_names(self): 50 | return [get_compressed_content_name(self.source.path, '.dex') + '.jar'] 51 | 52 | @tool_required('enjarify') 53 | def extract(self, member_name, dest_dir): 54 | dest_path = os.path.join(dest_dir, member_name) 55 | logger.debug('dex extracting to %s', dest_path) 56 | subprocess.check_call(['enjarify', '-o', dest_path, self.source.path], 57 | shell=False, stderr=None, stdout=subprocess.PIPE) 58 | return dest_path 59 | 60 | class DexFile(File): 61 | RE_FILE_TYPE = re.compile(r'^Dalvik dex file .*\b') 62 | CONTAINER_CLASS = DexContainer 63 | -------------------------------------------------------------------------------- /diffoscope/comparators/fonts.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.tools import tool_required 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.command import Command 27 | 28 | 29 | class Showttf(Command): 30 | @tool_required('showttf') 31 | def cmdline(self): 32 | return ['showttf', self.path] 33 | 34 | def filter(self, line): 35 | return line.decode('latin-1').encode('utf-8') 36 | 37 | 38 | class TtfFile(File): 39 | RE_FILE_TYPE = re.compile(r'^(TrueType|OpenType) font data$') 40 | 41 | def compare_details(self, other, source=None): 42 | return [Difference.from_command(Showttf, self.path, other.path)] 43 | -------------------------------------------------------------------------------- /diffoscope/comparators/gzip.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import os.path 22 | import logging 23 | import subprocess 24 | import collections 25 | 26 | from diffoscope.tools import tool_required 27 | from diffoscope.difference import Difference 28 | 29 | 30 | from .utils.file import File 31 | from .utils.archive import Archive 32 | from .utils.filenames import get_compressed_content_name 33 | 34 | logger = logging.getLogger(__name__) 35 | 36 | 37 | class GzipContainer(Archive): 38 | def open_archive(self): 39 | return self 40 | 41 | def close_archive(self): 42 | pass 43 | 44 | def get_members(self): 45 | return collections.OrderedDict({'gzip-content': self.get_member(self.get_member_names()[0])}) 46 | 47 | def get_member_names(self): 48 | return [get_compressed_content_name(self.source.path, '.gz')] 49 | 50 | @tool_required('gzip') 51 | def extract(self, member_name, dest_dir): 52 | dest_path = os.path.join(dest_dir, member_name) 53 | logger.debug('gzip extracting to %s', dest_path) 54 | with open(dest_path, 'wb') as fp: 55 | subprocess.check_call( 56 | ["gzip", "--decompress", "--stdout", self.source.path], 57 | shell=False, stdout=fp, stderr=None) 58 | return dest_path 59 | 60 | 61 | class GzipFile(File): 62 | CONTAINER_CLASS = GzipContainer 63 | RE_FILE_TYPE = re.compile(r'^gzip compressed data\b') 64 | 65 | def compare_details(self, other, source=None): 66 | return [Difference.from_text(self.magic_file_type, other.magic_file_type, self, other, source='metadata')] 67 | -------------------------------------------------------------------------------- /diffoscope/comparators/icc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.tools import tool_required 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.command import Command 27 | 28 | 29 | class Iccdump(Command): 30 | @tool_required('cd-iccdump') 31 | def cmdline(self): 32 | return ['cd-iccdump', self.path] 33 | 34 | 35 | class IccFile(File): 36 | RE_FILE_TYPE = re.compile(r'\bColorSync (ICC|color) [Pp]rofile') 37 | 38 | def compare_details(self, other, source=None): 39 | return [Difference.from_command(Iccdump, self.path, other.path)] 40 | -------------------------------------------------------------------------------- /diffoscope/comparators/ipk.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Reiner Herrmann 6 | # 2015 Jérémy Bobbio 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | import re 22 | 23 | from .gzip import GzipFile 24 | 25 | 26 | class IpkFile(GzipFile): 27 | RE_FILE_EXTENSION = re.compile('\.ipk$') 28 | -------------------------------------------------------------------------------- /diffoscope/comparators/java.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Reiner Herrmann 6 | # 2015 Jérémy Bobbio 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | import re 22 | import os.path 23 | 24 | from diffoscope.tools import tool_required 25 | from diffoscope.difference import Difference 26 | 27 | from .utils.file import File 28 | from .utils.command import Command 29 | 30 | 31 | class Javap(Command): 32 | def __init__(self, path, *args, **kwargs): 33 | super().__init__(path, *args, **kwargs) 34 | self.real_path = os.path.realpath(path) 35 | 36 | @tool_required('javap') 37 | def cmdline(self): 38 | return ['javap', '-verbose', '-constants', '-s', '-l', '-private', self.path] 39 | 40 | def filter(self, line): 41 | if re.match(r'^(Classfile %s$| Last modified | MD5 checksum )' % re.escape(self.real_path), line.decode('utf-8')): 42 | return b'' 43 | return line 44 | 45 | 46 | class ClassFile(File): 47 | RE_FILE_TYPE = re.compile(r'^compiled Java class data\b') 48 | 49 | def compare_details(self, other, source=None): 50 | return [Difference.from_command(Javap, self.path, other.path)] 51 | -------------------------------------------------------------------------------- /diffoscope/comparators/javascript.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Emanuel Bronshtein 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.tools import tool_required 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.command import Command 27 | 28 | 29 | class JavaScriptBeautify(Command): 30 | @tool_required('js-beautify') 31 | def cmdline(self): 32 | return ['js-beautify', self.path] 33 | 34 | class JavaScriptFile(File): 35 | RE_FILE_EXTENSION = re.compile(r'\.js$') 36 | 37 | def compare_details(self, other, source=None): 38 | return [Difference.from_command(JavaScriptBeautify, self.path, other.path)] 39 | 40 | -------------------------------------------------------------------------------- /diffoscope/comparators/json.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import json 22 | import collections 23 | 24 | from diffoscope.difference import Difference 25 | 26 | from .utils.file import File 27 | 28 | 29 | class JSONFile(File): 30 | RE_FILE_EXTENSION = re.compile(r'\.json$') 31 | 32 | @staticmethod 33 | def recognizes(file): 34 | if JSONFile.RE_FILE_EXTENSION.search(file.name) is None: 35 | return False 36 | 37 | with open(file.path) as f: 38 | try: 39 | file.parsed = json.load(f, object_pairs_hook=collections.OrderedDict) 40 | except ValueError: 41 | return False 42 | 43 | return True 44 | 45 | def compare_details(self, other, source=None): 46 | difference = Difference.from_text(self.dumps(self), self.dumps(other), 47 | self.path, other.path) 48 | if difference: 49 | return [difference] 50 | 51 | difference = Difference.from_text(self.dumps(self, sort_keys=False), 52 | self.dumps(other, sort_keys=False), 53 | self.path, other.path, 54 | comment="ordering differences only") 55 | return [difference] 56 | 57 | @staticmethod 58 | def dumps(file, sort_keys=True): 59 | if not hasattr(file, 'parsed'): 60 | return "" 61 | return json.dumps(file.parsed, indent=4, sort_keys=sort_keys) 62 | -------------------------------------------------------------------------------- /diffoscope/comparators/llvm.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # Copyright © 2016 Ximin Luo 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | from diffoscope.tools import tool_required 22 | from diffoscope.difference import Difference 23 | 24 | from .utils.file import File 25 | from .utils.command import Command 26 | 27 | 28 | class LlvmBcAnalyzer(Command): 29 | @tool_required('llvm-bcanalyzer') 30 | def cmdline(self): 31 | return ['llvm-bcanalyzer', '-dump', self.path] 32 | 33 | class LlvmBcDisassembler(Command): 34 | @tool_required('llvm-dis') 35 | def cmdline(self): 36 | # execute llvm-dis from the same directory as the file, so it doesn't 37 | # embed the whole path, including our tempdir, into the output. 38 | # this makes it easier to generate reproducible diffs for our tests. 39 | return ['find', self.path, '-execdir', 'llvm-dis', '-o', '-', '{}', ';'] 40 | 41 | class LlvmBitCodeFile(File): 42 | @staticmethod 43 | def recognizes(file): 44 | return file.magic_file_type and file.magic_file_type.startswith('LLVM IR bitcode') 45 | 46 | def compare_details(self, other, source=None): 47 | return [Difference.from_command(LlvmBcAnalyzer, self.path, other.path), 48 | Difference.from_command(LlvmBcDisassembler, self.path, other.path)] 49 | -------------------------------------------------------------------------------- /diffoscope/comparators/mono.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Daniel Kahn Gillmor 6 | # 2015 Jérémy Bobbio 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | import re 22 | 23 | from diffoscope.tools import tool_required 24 | from diffoscope.difference import Difference 25 | 26 | from .utils.file import File 27 | from .utils.command import Command 28 | 29 | 30 | class Pedump(Command): 31 | @tool_required('pedump') 32 | def cmdline(self): 33 | return ['pedump', self.path] 34 | 35 | 36 | class MonoExeFile(File): 37 | RE_FILE_TYPE = re.compile(r'\bPE[0-9]+\b.*\bMono\b') 38 | 39 | def compare_details(self, other, source=None): 40 | return [Difference.from_command(Pedump, self.path, other.path)] 41 | -------------------------------------------------------------------------------- /diffoscope/comparators/openssh.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Emanuel Bronshtein 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.tools import tool_required 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.command import Command 27 | 28 | 29 | class SSHKeyList(Command): 30 | @tool_required('ssh-keygen') 31 | def cmdline(self): 32 | return ['ssh-keygen', '-l', '-f', self.path] 33 | 34 | class PublicKeyFile(File): 35 | RE_FILE_TYPE = re.compile(r'^OpenSSH \S+ public key') 36 | 37 | def compare_details(self, other, source=None): 38 | return [Difference.from_command(SSHKeyList, self.path, other.path)] 39 | 40 | -------------------------------------------------------------------------------- /diffoscope/comparators/pdf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.tools import tool_required 23 | from diffoscope.difference import Difference 24 | 25 | from .utils.file import File 26 | from .utils.command import Command 27 | 28 | 29 | class Pdftotext(Command): 30 | @tool_required('pdftotext') 31 | def cmdline(self): 32 | return ['pdftotext', self.path, '-'] 33 | 34 | 35 | class Pdftk(Command): 36 | @tool_required('pdftk') 37 | def cmdline(self): 38 | return ['pdftk', self.path, 'output', '-', 'uncompress'] 39 | 40 | def filter(self, line): 41 | return line.decode('latin-1').encode('utf-8') 42 | 43 | 44 | class PdfFile(File): 45 | RE_FILE_TYPE = re.compile(r'^PDF document\b') 46 | 47 | def compare_details(self, other, source=None): 48 | return [Difference.from_command(Pdftotext, self.path, other.path), 49 | Difference.from_command(Pdftk, self.path, other.path)] 50 | -------------------------------------------------------------------------------- /diffoscope/comparators/png.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import functools 22 | 23 | from diffoscope.tools import tool_required 24 | from diffoscope.difference import Difference 25 | 26 | from .utils.file import File 27 | from .utils.command import Command 28 | 29 | 30 | class Sng(Command): 31 | @tool_required('sng') 32 | def cmdline(self): 33 | return ['sng'] 34 | 35 | def feed_stdin(self, stdin): 36 | with open(self.path, 'rb') as f: 37 | for buf in iter(functools.partial(f.read, 32768), b''): 38 | stdin.write(buf) 39 | 40 | 41 | class PngFile(File): 42 | RE_FILE_TYPE = re.compile(r'^PNG image data\b') 43 | 44 | def compare_details(self, other, source=None): 45 | return [Difference.from_command(Sng, self.path, other.path, source='sng')] 46 | -------------------------------------------------------------------------------- /diffoscope/comparators/ps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Reiner Herrmann 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import logging 22 | 23 | from diffoscope.exc import RequiredToolNotFound 24 | from diffoscope.tools import tool_required 25 | from diffoscope.difference import Difference 26 | 27 | from .text import TextFile 28 | from .utils.command import Command 29 | 30 | logger = logging.getLogger(__name__) 31 | 32 | 33 | class Pstotext(Command): 34 | @tool_required('ps2ascii') 35 | def cmdline(self): 36 | return ['ps2ascii', self.path] 37 | 38 | 39 | class PsFile(TextFile): 40 | RE_FILE_TYPE = re.compile(r'^PostScript document\b') 41 | 42 | def compare(self, other, source=None): 43 | differences = super().compare(other, source) 44 | details = None 45 | try: 46 | details = Difference.from_command(Pstotext, self.path, other.path) 47 | except RequiredToolNotFound: # noqa 48 | logger.debug('ps2ascii not found') 49 | 50 | if details: 51 | differences.add_details([details]) 52 | return differences 53 | -------------------------------------------------------------------------------- /diffoscope/comparators/rpm_fallback.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from .utils.file import File 23 | 24 | 25 | class AbstractRpmFile(File): 26 | RE_FILE_TYPE = re.compile('^RPM\s') 27 | 28 | class RpmFile(AbstractRpmFile): 29 | def compare(self, other, source=None): 30 | difference = self.compare_bytes(other) 31 | if not difference: 32 | return None 33 | difference.add_comment('Unable to find Python rpm module. Falling back to binary comparison.') 34 | return difference 35 | -------------------------------------------------------------------------------- /diffoscope/comparators/sqlite.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | from diffoscope.tools import tool_required 21 | from diffoscope.difference import Difference 22 | 23 | from .utils.file import File 24 | from .utils.command import Command 25 | 26 | 27 | class Sqlite3Dump(Command): 28 | @tool_required('sqlite3') 29 | def cmdline(self): 30 | return ['sqlite3', self.path, '.dump'] 31 | 32 | 33 | class Sqlite3Database(File): 34 | @staticmethod 35 | def recognizes(file): 36 | return file.magic_file_type and file.magic_file_type.startswith('SQLite 3.x database') 37 | 38 | def compare_details(self, other, source=None): 39 | return [Difference.from_command(Sqlite3Dump, self.path, other.path)] 40 | 41 | -------------------------------------------------------------------------------- /diffoscope/comparators/symlink.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | import logging 22 | 23 | from diffoscope.tempfiles import get_named_temporary_file 24 | from diffoscope.difference import Difference 25 | 26 | from .utils.file import File 27 | 28 | logger = logging.getLogger(__name__) 29 | 30 | 31 | class Symlink(File): 32 | @staticmethod 33 | def recognizes(file): 34 | return file.is_symlink() 35 | 36 | @property 37 | def symlink_destination(self): 38 | return os.readlink(self.name) 39 | 40 | def create_placeholder(self): 41 | with get_named_temporary_file('w+', delete=False) as f: 42 | f.write('destination: %s\n' % self.symlink_destination) 43 | f.flush() 44 | return f.name 45 | 46 | @property 47 | def path(self): 48 | if not hasattr(self, '_placeholder'): 49 | self._placeholder = self.create_placeholder() 50 | return self._placeholder 51 | 52 | def cleanup(self): 53 | if hasattr(self, '_placeholder'): 54 | os.remove(self._placeholder) 55 | del self._placeholder 56 | super().cleanup() 57 | 58 | def compare(self, other, source=None): 59 | with open(self.path) as my_content, \ 60 | open(other.path) as other_content: 61 | return Difference.from_text_readers(my_content, other_content, self.name, other.name, source=source, comment="symlink") 62 | -------------------------------------------------------------------------------- /diffoscope/comparators/tar.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | from diffoscope.difference import Difference 23 | 24 | from .utils.file import File 25 | from .utils.libarchive import LibarchiveContainer, list_libarchive 26 | 27 | class TarContainer(LibarchiveContainer): 28 | pass 29 | 30 | 31 | class TarFile(File): 32 | CONTAINER_CLASS = TarContainer 33 | RE_FILE_TYPE = re.compile(r'\btar archive\b') 34 | 35 | def compare_details(self, other, source=None): 36 | return [Difference.from_text_readers(list_libarchive(self.path), 37 | list_libarchive(other.path), 38 | self.path, other.path, source="file list")] 39 | -------------------------------------------------------------------------------- /diffoscope/comparators/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/diffoscope/comparators/utils/__init__.py -------------------------------------------------------------------------------- /diffoscope/comparators/utils/filenames.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | 22 | 23 | def get_compressed_content_name(path, expected_extension): 24 | basename = os.path.basename(path) 25 | if basename.endswith(expected_extension): 26 | name = basename[:-len(expected_extension)] 27 | else: 28 | name = "%s-content" % basename 29 | return name 30 | -------------------------------------------------------------------------------- /diffoscope/comparators/utils/fuzzy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import logging 21 | import operator 22 | 23 | from diffoscope.config import Config 24 | 25 | try: 26 | import tlsh 27 | except ImportError: # noqa 28 | tlsh = None 29 | 30 | logger = logging.getLogger(__name__) 31 | 32 | 33 | def perform_fuzzy_matching(members1, members2): 34 | if tlsh == None or Config().fuzzy_threshold == 0: 35 | return 36 | already_compared = set() 37 | # Perform local copies because they will be modified by consumer 38 | members1 = dict(members1) 39 | members2 = dict(members2) 40 | for name1, file1 in members1.items(): 41 | if file1.is_directory() or not file1.fuzzy_hash: 42 | continue 43 | comparisons = [] 44 | for name2, file2 in members2.items(): 45 | if name2 in already_compared or file2.is_directory() or not file2.fuzzy_hash: 46 | continue 47 | comparisons.append((tlsh.diff(file1.fuzzy_hash, file2.fuzzy_hash), name2)) 48 | if comparisons: 49 | comparisons.sort(key=operator.itemgetter(0)) 50 | score, name2 = comparisons[0] 51 | logger.debug('fuzzy top match %s %s: %d difference score', name1, name2, score) 52 | if score < Config().fuzzy_threshold: 53 | yield name1, name2, score 54 | already_compared.add(name2) 55 | -------------------------------------------------------------------------------- /diffoscope/comparators/utils/specialize.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import logging 21 | 22 | from diffoscope.profiling import profile 23 | 24 | from .. import ComparatorManager 25 | 26 | logger = logging.getLogger(__name__) 27 | 28 | 29 | def specialize(file): 30 | for cls in ComparatorManager().classes: 31 | if isinstance(file, cls): 32 | return file 33 | 34 | # Does this file class match? 35 | flag = False 36 | if hasattr(cls, 'recognizes'): 37 | with profile('recognizes', file): 38 | flag = cls.recognizes(file) 39 | else: 40 | re_tests = [(x, y) for x, y in ( 41 | (cls.RE_FILE_TYPE, file.magic_file_type), 42 | (cls.RE_FILE_EXTENSION, file.name), 43 | ) if x] 44 | 45 | # If neither are defined, it's *not* a match. 46 | if re_tests: 47 | flag = all(x.search(y) for x, y in re_tests) 48 | 49 | if not flag: 50 | continue 51 | 52 | # Found a match; perform type magic 53 | logger.debug("Using %s for %s", cls.__name__, file.name) 54 | new_cls = type(cls.__name__, (cls, type(file)), {}) 55 | file.__class__ = new_cls 56 | 57 | return file 58 | 59 | logger.debug("Unidentified file. Magic says: %s", file.magic_file_type) 60 | 61 | return file 62 | -------------------------------------------------------------------------------- /diffoscope/comparators/xz.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | import os.path 22 | import logging 23 | import subprocess 24 | import collections 25 | 26 | from diffoscope.tools import tool_required 27 | 28 | from .utils.file import File 29 | from .utils.archive import Archive 30 | from .utils.filenames import get_compressed_content_name 31 | 32 | logger = logging.getLogger(__name__) 33 | 34 | 35 | class XzContainer(Archive): 36 | def open_archive(self): 37 | return self 38 | 39 | def close_archive(self): 40 | pass 41 | 42 | def get_members(self): 43 | return collections.OrderedDict({'xz-content': self.get_member(self.get_member_names()[0])}) 44 | 45 | def get_member_names(self): 46 | return [get_compressed_content_name(self.source.path, '.xz')] 47 | 48 | @tool_required('xz') 49 | def extract(self, member_name, dest_dir): 50 | dest_path = os.path.join(dest_dir, member_name) 51 | logger.debug('xz extracting to %s', dest_path) 52 | with open(dest_path, 'wb') as fp: 53 | subprocess.check_call( 54 | ["xz", "--decompress", "--stdout", self.source.path], 55 | shell=False, stdout=fp, stderr=None) 56 | return dest_path 57 | 58 | 59 | class XzFile(File): 60 | CONTAINER_CLASS = XzContainer 61 | RE_FILE_TYPE = re.compile(r'^XZ compressed data$') 62 | -------------------------------------------------------------------------------- /diffoscope/exc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2014-2015 Jérémy Bobbio 6 | # 2016 Chris Lamb 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | from .tools import get_current_os 22 | from .external_tools import EXTERNAL_TOOLS 23 | 24 | 25 | class OutputParsingError(Exception): 26 | def __init__(self, command, object): 27 | self.command = command 28 | self.object_class = object.__class__ 29 | 30 | class RequiredToolNotFound(Exception): 31 | def __init__(self, command): 32 | self.command = command 33 | 34 | def get_package(self): 35 | try: 36 | providers = EXTERNAL_TOOLS[self.command] 37 | except KeyError: # noqa 38 | return None 39 | 40 | return providers.get(get_current_os(), None) 41 | -------------------------------------------------------------------------------- /diffoscope/excludes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import fnmatch 21 | import logging 22 | 23 | from diffoscope.config import Config 24 | 25 | logger = logging.getLogger(__name__) 26 | 27 | 28 | def filter_excludes(filenames): 29 | result = [] 30 | 31 | for x in filenames: 32 | for y in Config().excludes: 33 | if fnmatch.fnmatchcase(x, y): 34 | logger.debug("Excluding %s as it matches pattern '%s'", x, y) 35 | break 36 | else: 37 | result.append(x) 38 | 39 | return result 40 | 41 | def any_excluded(*filenames): 42 | return len(filter_excludes(filenames)) != len(filenames) 43 | -------------------------------------------------------------------------------- /diffoscope/locale.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | import time 22 | import logging 23 | 24 | logger = logging.getLogger(__name__) 25 | 26 | 27 | def set_locale(): 28 | """ 29 | Normalise locale so external tool gives us stable and properly encoded 30 | output. 31 | """ 32 | 33 | logger.debug("Normalising locale, timezone, etc.") 34 | 35 | for x in ('LANGUAGE', 'LC_ALL'): 36 | os.environ.pop(x, None) 37 | 38 | for x in ( 39 | 'LANG', 40 | 'LC_NUMERIC', 41 | 'LC_TIME', 42 | 'LC_COLLATE', 43 | 'LC_MONETARY', 44 | 'LC_MESSAGES', 45 | 'LC_PAPER', 46 | 'LC_NAME', 47 | 'LC_ADDRESS', 48 | 'LC_TELEPHONE', 49 | 'LC_MEASUREMENT', 50 | 'LC_IDENTIFICATION', 51 | ): 52 | os.environ[x] = 'C' 53 | 54 | os.environ['TZ'] = 'UTC' 55 | os.environ['LC_CTYPE'] = 'C.UTF-8' 56 | 57 | time.tzset() 58 | -------------------------------------------------------------------------------- /diffoscope/logging.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import logging 21 | 22 | 23 | def setup_logging(debug): 24 | logger = logging.getLogger() 25 | logger.setLevel(logging.DEBUG if debug else logging.WARNING) 26 | 27 | ch = logging.StreamHandler() 28 | ch.setLevel(logging.DEBUG) 29 | logger.addHandler(ch) 30 | 31 | formatter = logging.Formatter( 32 | '%(asctime)s %(levelname).1s: %(name)s: %(message)s', 33 | '%Y-%m-%d %H:%M:%S', 34 | ) 35 | ch.setFormatter(formatter) 36 | -------------------------------------------------------------------------------- /diffoscope/presenters/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/diffoscope/presenters/__init__.py -------------------------------------------------------------------------------- /diffoscope/presenters/html/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | from .html import output_html, output_html_directory, JQUERY_SYSTEM_LOCATIONS 21 | -------------------------------------------------------------------------------- /diffoscope/presenters/icon.py: -------------------------------------------------------------------------------- 1 | # Generated from favicon.png 2 | FAVICON_BASE64 = """ 3 | iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz 4 | AAADdgAAA3YBfdWCzAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAM8SURB 5 | VFiF7dZdaJZlGAfw3/O+e9XNjy3XllZzWImBxIpifqTgsmUHBSIeBNFBdRh0UHQ0xGdb66CFBIER 6 | ZEFRQRRUw0HkQkLMYQSBdpCFWdgSP6jpNn2393k68Nn2bj3vXtb6UOh/cl/39b/u67mem/913zf/ 7 | 4z9GUDw5xNI8n5WIzW9m/QF2YluJmI8203mALzEvLWAerRs4Pz6vSIkZSlsYk0/GkaB0zEgyDgWM 8 | lijyWsJuS2fkQwu8pqpMTA0ypeiShG71Bp0rU8Q+A47MWEDgvHZbZl/Av4SpIgxVYB3IqwZDmoUu 9 | YkzosDaNchpAoFqkSmgjGPWzLieF1k3JHVsjvCJQHBYaSy9g1E3m+QImQiK9SbNGqJDzuiDZ0lgg 10 | QJCsyelDq8BB47sbCWTsnvhG3kqcLL833eqF4hk1EOoTOjZjnnaRdq2l6KtMAyl4/g23bKJrun+M 11 | t9uOq7nvqOVbebWYy9Adc1fM/R/3CO780dONbIeFPHsPw+ULeM5ZHTbXHfUtXpxOZzgT5z02UGsZ 12 | ThRzF/ilht9G+fr4zfbfccIxXIa7uVTup69i7LJXaEEqF3on1d9ludBLpVLOVoT1lky9QYtwQ6p3 13 | WAVqSyUslWwSbRrkPJrMtgn0iBVk7BPJ4sGE24EPQKW3jLgdzWKLBTbg0yTuZeGkDsp2gcUGDesH 14 | GQ/gK5G8nLMigWiCe3jCrnTRiJ9EYjm1ImsUEq5l8hScPXbpsVtlKhfan+pv0yD0ZqmU5XegGBmn 15 | DIo/pylj8oYLOP3Eab/v5Zmi6EtZ3vv1FU/2r7LioYSL2dNybbdiMdptFU57++20Vqh+iq/Tap1W 16 | paWY611wmyWyUzxZDbIWTvEV1Ildn5agfBumoUMTtoisFvhebAAHZWxX0ChwTuScvHdVeVykToys 17 | MyJ7ittwbmj31J+6IrRDp5XTfBt1WJ+WYnZdMB0F3xlUgD5uDVj2Sa+a4SrzH+FeyHHmw17V112w 18 | aBOZgP4WczkLZsILar1fpIliMU4XZoK/poE0XHl+N8v6QcGAUbVymnDIZVnzrTXqGzmnhKLxZX/n 19 | iyiDjIJgwg4Se1GR/Y8idGPysh6fr0i1i/AHMWHgrwUJgNAAAAAASUVORK5CYII= 20 | """.replace("\n", "") 21 | -------------------------------------------------------------------------------- /diffoscope/presenters/json.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import json 21 | 22 | from .utils import Presenter 23 | 24 | 25 | class JSONPresenter(Presenter): 26 | def __init__(self, print_func): 27 | self.root = [] 28 | self.current = self.root 29 | self.print_func = print_func 30 | 31 | super().__init__() 32 | 33 | def start(self, difference): 34 | super().start(difference) 35 | 36 | self.print_func(json.dumps(self.root[0], indent=2, sort_keys=True)) 37 | 38 | def visit_difference(self, difference): 39 | self.current.append({ 40 | 'source1': difference.source1, 41 | 'source2': difference.source2, 42 | 'comments': [x for x in difference.comments], 43 | 'differences': [], 44 | 'unified_diff': difference.unified_diff, 45 | }) 46 | 47 | self.current = self.current[-1]['differences'] 48 | -------------------------------------------------------------------------------- /diffoscope/presenters/markdown.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | from .utils import Presenter 21 | 22 | 23 | class MarkdownTextPresenter(Presenter): 24 | def __init__(self, print_func): 25 | self.print_func = print_func 26 | super().__init__() 27 | 28 | def visit_difference(self, difference): 29 | if difference.source1 == difference.source2: 30 | self.title(difference.source1) 31 | else: 32 | self.title("Comparing {} & {}".format( 33 | difference.source1, 34 | difference.source2, 35 | )) 36 | 37 | for x in difference.comments: 38 | self.print_func(x) 39 | self.print_func() 40 | 41 | if difference.unified_diff: 42 | self.print_func(self.indent(difference.unified_diff, ' ')) 43 | self.print_func() 44 | 45 | def title(self, val): 46 | prefix = '#' * min(self.depth + 1, 6) 47 | 48 | self.print_func("{} {}".format(prefix, val)) 49 | self.print_func() 50 | -------------------------------------------------------------------------------- /diffoscope/presenters/restructuredtext.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | from .utils import Presenter 21 | 22 | 23 | class RestructuredTextPresenter(Presenter): 24 | TITLE_CHARS = '=-`:.\'"~^_*+#' 25 | 26 | def __init__(self, print_func): 27 | self.print_func = print_func 28 | super().__init__() 29 | 30 | def visit_difference(self, difference): 31 | if difference.source1 == difference.source2: 32 | self.title(difference.source1) 33 | else: 34 | self.title("Comparing {} & {}".format( 35 | difference.source1, 36 | difference.source2, 37 | )) 38 | 39 | for x in difference.comments: 40 | self.print_func() 41 | self.print_func(x) 42 | 43 | if difference.unified_diff: 44 | self.print_func('::') 45 | self.print_func() 46 | self.print_func(self.indent(difference.unified_diff, ' ')) 47 | self.print_func() 48 | 49 | def title(self, val): 50 | char = self.TITLE_CHARS[self.depth % len(self.TITLE_CHARS)] 51 | 52 | if self.depth < len(self.TITLE_CHARS): 53 | self.print_func(len(val) * char) 54 | 55 | self.print_func(val) 56 | self.print_func(len(val) * char) 57 | self.print_func() 58 | -------------------------------------------------------------------------------- /diffoscope/tempfiles.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | import logging 22 | import tempfile 23 | 24 | _DIRS, _FILES = [], [] 25 | 26 | logger = logging.getLogger(__name__) 27 | 28 | 29 | def get_named_temporary_file(*args, **kwargs): 30 | kwargs['suffix'] = kwargs.pop('suffix', '_diffoscope') 31 | 32 | f = tempfile.NamedTemporaryFile(*args, **kwargs) 33 | _FILES.append(f.name) 34 | 35 | return f 36 | 37 | def get_temporary_directory(*args, **kwargs): 38 | kwargs['suffix'] = kwargs.pop('suffix', '_diffoscope') 39 | 40 | d = tempfile.TemporaryDirectory(*args, **kwargs) 41 | _DIRS.append(d) 42 | 43 | return d 44 | 45 | def clean_all_temp_files(): 46 | logger.debug("Cleaning %d temp files", len(_FILES)) 47 | 48 | for x in _FILES: 49 | try: 50 | os.unlink(x) 51 | except FileNotFoundError: 52 | pass 53 | except: 54 | logger.exception("Unable to delete %s", x) 55 | 56 | logger.debug("Cleaning %d temporary directories", len(_DIRS)) 57 | 58 | for x in _DIRS: 59 | try: 60 | x.cleanup() 61 | except: 62 | logger.exception("Unable to delete %s", x) 63 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys 4 | import diffoscope 5 | 6 | from setuptools import setup, find_packages 7 | from setuptools.command.test import test as TestCommand 8 | 9 | 10 | class PyTest(TestCommand): 11 | user_options = [('pytest-args=', 'a', "Arguments to pass to py.test")] 12 | 13 | def initialize_options(self): 14 | super().initialize_options() 15 | self.pytest_args = [] 16 | 17 | def finalize_options(self): 18 | super().finalize_options() 19 | 20 | def run_tests(self): 21 | #import here, cause outside the eggs aren't loaded 22 | import pytest 23 | errno = pytest.main(self.pytest_args) 24 | sys.exit(errno) 25 | 26 | setup( 27 | name='diffoscope', 28 | version=diffoscope.VERSION, 29 | description='in-depth comparison of files, archives, and directories', 30 | long_description=open('README.rst', encoding='utf-8').read(), 31 | author='Lunar', 32 | author_email='lunar@debian.org', 33 | license='GPL-3+', 34 | url='https://diffoscope.org/', 35 | packages=find_packages(), 36 | tests_require=['pytest'], 37 | cmdclass = {'test': PyTest}, 38 | entry_points={ 39 | 'console_scripts': [ 40 | 'diffoscope=diffoscope.main:main' 41 | ], 42 | }, 43 | install_requires=[ 44 | 'python-magic', 45 | 'libarchive-c', 46 | ], 47 | classifiers=[ 48 | 'Development Status :: 3 - Alpha', 49 | 'Intended Audience :: Developers', 50 | 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 51 | 'Operating System :: POSIX', 52 | 'Programming Language :: Python', 53 | 'Programming Language :: Python :: 3', 54 | 'Programming Language :: Python :: 3.4', 55 | 'Programming Language :: Python :: 3.5', 56 | 'Topic :: Utilities', 57 | ], 58 | ) 59 | -------------------------------------------------------------------------------- /tests/comparators/test_apk.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Maria Glukhova 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.apk import ApkFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | apk1 = load_fixture('test1.apk') 29 | apk2 = load_fixture('test2.apk') 30 | 31 | def test_identification(apk1): 32 | assert isinstance(apk1, ApkFile) 33 | 34 | def test_no_differences(apk1): 35 | difference = apk1.compare(apk1) 36 | assert difference is None 37 | 38 | @pytest.fixture 39 | def differences(apk1, apk2): 40 | return apk1.compare(apk2).details 41 | 42 | @skip_unless_tools_exist('apktool', 'zipinfo') 43 | def test_compare_non_existing(monkeypatch, apk1): 44 | assert_non_existing(monkeypatch, apk1) 45 | 46 | @skip_unless_tools_exist('apktool', 'zipinfo') 47 | def test_zipinfo(differences): 48 | assert differences[0].source1 == 'zipinfo {}' 49 | assert differences[0].source2 == 'zipinfo {}' 50 | expected_diff = get_data('apk_zipinfo_expected_diff') 51 | assert differences[0].unified_diff == expected_diff 52 | 53 | @skip_unless_tools_exist('apktool', 'zipinfo') 54 | def test_android_manifest(differences): 55 | assert differences[2].source1 == 'AndroidManifest.xml' 56 | assert differences[2].source2 == 'AndroidManifest.xml' 57 | expected_diff = get_data('apk_manifest_expected_diff') 58 | assert differences[2].unified_diff == expected_diff 59 | 60 | @skip_unless_tools_exist('apktool', 'zipinfo') 61 | def test_apk_metadata_source(differences): 62 | assert differences[1].source1 == 'APK metadata' 63 | assert differences[1].source2 == 'APK metadata' 64 | -------------------------------------------------------------------------------- /tests/comparators/test_cpio.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.cpio import CpioFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | 29 | cpio1 = load_fixture('test1.cpio') 30 | cpio2 = load_fixture('test2.cpio') 31 | 32 | def test_identification(cpio1): 33 | assert isinstance(cpio1, CpioFile) 34 | 35 | def test_no_differences(cpio1): 36 | difference = cpio1.compare(cpio1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(cpio1, cpio2): 41 | return cpio1.compare(cpio2).details 42 | 43 | @skip_unless_tools_exist('cpio') 44 | def test_listing(differences): 45 | expected_diff = get_data('cpio_listing_expected_diff') 46 | assert differences[0].unified_diff == expected_diff 47 | 48 | @skip_unless_tools_exist('cpio') 49 | def test_symlink(differences): 50 | assert differences[1].source1 == 'dir/link' 51 | assert differences[1].comment == 'symlink' 52 | expected_diff = get_data('symlink_expected_diff') 53 | assert differences[1].unified_diff == expected_diff 54 | 55 | @skip_unless_tools_exist('cpio') 56 | def test_compressed_files(differences): 57 | assert differences[2].source1 == 'dir/text' 58 | assert differences[2].source2 == 'dir/text' 59 | expected_diff = get_data('text_ascii_expected_diff') 60 | assert differences[2].unified_diff == expected_diff 61 | 62 | @skip_unless_tools_exist('cpio') 63 | def test_compare_non_existing(monkeypatch, cpio1): 64 | assert_non_existing(monkeypatch, cpio1) 65 | -------------------------------------------------------------------------------- /tests/comparators/test_device.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.binary import FilesystemFile 23 | from diffoscope.comparators.device import Device 24 | from diffoscope.comparators.utils.specialize import specialize 25 | 26 | from utils.data import load_fixture, get_data, normalize_zeros 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | text_ascii1 = load_fixture('text_ascii1') 31 | 32 | @pytest.fixture 33 | def devnull(): 34 | return specialize(FilesystemFile('/dev/null')) 35 | 36 | @pytest.fixture 37 | def differences(devnull, text_ascii1): 38 | return devnull.compare_bytes(text_ascii1) 39 | 40 | @pytest.fixture 41 | def differences_reverse(text_ascii1, devnull): 42 | return text_ascii1.compare_bytes(devnull) 43 | 44 | def test_identification(devnull): 45 | assert isinstance(devnull, Device) 46 | 47 | @skip_unless_tools_exist('xxd') 48 | def test_diff(differences): 49 | expected_diff = get_data('device_expected_diff') 50 | assert normalize_zeros(differences.unified_diff) == expected_diff 51 | 52 | @skip_unless_tools_exist('xxd') 53 | def test_diff_reverse(differences_reverse): 54 | expected_diff = get_data('device_expected_diff_reverse') 55 | assert normalize_zeros(differences_reverse.unified_diff) == expected_diff 56 | -------------------------------------------------------------------------------- /tests/comparators/test_epub.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.zip import ZipFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | epub1 = load_fixture('test1.epub') 31 | epub2 = load_fixture('test2.epub') 32 | 33 | def test_identification(epub1): 34 | assert isinstance(epub1, ZipFile) 35 | 36 | def test_no_differences(epub1): 37 | difference = epub1.compare(epub1) 38 | assert difference is None 39 | 40 | @pytest.fixture 41 | def differences(epub1, epub2): 42 | return epub1.compare(epub2).details 43 | 44 | @skip_unless_tools_exist('zipinfo') 45 | def test_differences(differences): 46 | assert differences[0].source1 == 'zipinfo {}' 47 | assert differences[0].source2 == 'zipinfo {}' 48 | assert differences[1].source1 == 'content.opf' 49 | assert differences[1].source2 == 'content.opf' 50 | assert differences[2].source1 == 'toc.ncx' 51 | assert differences[2].source2 == 'toc.ncx' 52 | assert differences[3].source1 == 'ch001.xhtml' 53 | assert differences[3].source2 == 'ch001.xhtml' 54 | expected_diff = get_data('epub_expected_diffs') 55 | assert expected_diff == "".join(map(lambda x: x.unified_diff, differences)) 56 | 57 | @skip_unless_tools_exist('zipinfo') 58 | def test_compare_non_existing(monkeypatch, epub1): 59 | monkeypatch.setattr(Config(), 'new_file', True) 60 | difference = epub1.compare(MissingFile('/nonexisting', epub1)) 61 | assert difference.source2 == '/nonexisting' 62 | assert difference.details[-1].source2 == '/dev/null' 63 | -------------------------------------------------------------------------------- /tests/comparators/test_fonts.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.fonts import TtfFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | ttf1 = load_fixture('Samyak-Malayalam1.ttf') 31 | ttf2 = load_fixture('Samyak-Malayalam2.ttf') 32 | 33 | def test_identification(ttf1): 34 | assert isinstance(ttf1, TtfFile) 35 | 36 | def test_no_differences(ttf1): 37 | difference = ttf1.compare(ttf1) 38 | assert difference is None 39 | 40 | @pytest.fixture 41 | def differences(ttf1, ttf2): 42 | return ttf1.compare(ttf2).details 43 | 44 | @skip_unless_tools_exist('showttf') 45 | def test_diff(differences): 46 | expected_diff = get_data('ttf_expected_diff') 47 | assert differences[0].unified_diff == expected_diff 48 | 49 | @skip_unless_tools_exist('showttf') 50 | def test_compare_non_existing(monkeypatch, ttf1): 51 | monkeypatch.setattr(Config(), 'new_file', True) 52 | difference = ttf1.compare(MissingFile('/nonexisting', ttf1)) 53 | assert difference.source2 == '/nonexisting' 54 | assert len(difference.details) > 0 55 | -------------------------------------------------------------------------------- /tests/comparators/test_gettext.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import codecs 21 | import pytest 22 | 23 | from diffoscope.config import Config 24 | from diffoscope.comparators.missing_file import MissingFile 25 | from diffoscope.comparators.gettext import MoFile 26 | 27 | from utils.data import data, load_fixture, get_data 28 | from utils.tools import skip_unless_tools_exist 29 | 30 | 31 | mo1 = load_fixture('test1.mo') 32 | mo2 = load_fixture('test2.mo') 33 | 34 | def test_identification(mo1): 35 | assert isinstance(mo1, MoFile) 36 | 37 | def test_no_differences(mo1): 38 | difference = mo1.compare(mo1) 39 | assert difference is None 40 | 41 | @pytest.fixture 42 | def differences(mo1, mo2): 43 | return mo1.compare(mo2).details 44 | 45 | @skip_unless_tools_exist('msgunfmt') 46 | def test_diff(differences): 47 | expected_diff = get_data('mo_expected_diff') 48 | assert differences[0].unified_diff == expected_diff 49 | 50 | mo_no_charset = load_fixture('test_no_charset.mo') 51 | mo_iso8859_1 = load_fixture('test_iso8859-1.mo') 52 | 53 | @skip_unless_tools_exist('msgunfmt') 54 | def test_charsets(mo_no_charset, mo_iso8859_1): 55 | difference = mo_no_charset.compare(mo_iso8859_1) 56 | expected_diff = codecs.open(data('mo_charsets_expected_diff'), encoding='utf-8').read() 57 | assert difference.details[0].unified_diff == expected_diff 58 | 59 | @skip_unless_tools_exist('msgunfmt') 60 | def test_compare_non_existing(monkeypatch, mo1): 61 | monkeypatch.setattr(Config(), 'new_file', True) 62 | difference = mo1.compare(MissingFile('/nonexisting', mo1)) 63 | assert difference.source2 == '/nonexisting' 64 | assert len(difference.details) > 0 65 | -------------------------------------------------------------------------------- /tests/comparators/test_git.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.git import GitIndexFile 23 | 24 | from utils.data import get_data, load_fixture 25 | 26 | 27 | git1 = load_fixture('test1.git-index') 28 | git2 = load_fixture('test2.git-index') 29 | 30 | def test_identification(git1): 31 | assert isinstance(git1, GitIndexFile) 32 | 33 | def test_no_differences(git1): 34 | assert git1.compare(git1) is None 35 | 36 | @pytest.fixture 37 | def differences(git1, git2): 38 | return git1.compare(git2).details 39 | 40 | def test_diff(differences): 41 | expected_diff = get_data('git_expected_diff') 42 | assert differences[0].unified_diff == expected_diff 43 | -------------------------------------------------------------------------------- /tests/comparators/test_haskell.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.binary import FilesystemFile 23 | from diffoscope.comparators.haskell import HiFile 24 | 25 | from utils.data import get_data, load_fixture 26 | from utils.tools import skip_unless_tools_exist 27 | 28 | 29 | haskell1 = load_fixture('test1.hi') 30 | haskell2 = load_fixture('test2.hi') 31 | 32 | @skip_unless_tools_exist('ghc') 33 | def test_identification(haskell1): 34 | if isinstance(haskell1, FilesystemFile): 35 | pytest.skip("mismatch between system ghc and fixture") 36 | 37 | assert isinstance(haskell1, HiFile) 38 | 39 | def test_no_differences(haskell1): 40 | assert haskell1.compare(haskell1) is None 41 | 42 | @pytest.fixture 43 | def differences(haskell1, haskell2): 44 | return haskell1.compare(haskell2).details 45 | 46 | @skip_unless_tools_exist('ghc') 47 | def test_diff(haskell1, differences): 48 | if isinstance(haskell1, FilesystemFile): 49 | pytest.skip("mismatch between system ghc and fixture") 50 | 51 | expected_diff = get_data('haskell_expected_diff') 52 | assert differences[0].unified_diff == expected_diff 53 | -------------------------------------------------------------------------------- /tests/comparators/test_icc.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.icc import IccFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | icc1 = load_fixture('test1.icc') 31 | icc2 = load_fixture('test2.icc') 32 | 33 | def test_identification(icc1): 34 | assert isinstance(icc1, IccFile) 35 | 36 | def test_no_differences(icc1): 37 | difference = icc1.compare(icc1) 38 | assert difference is None 39 | 40 | @pytest.fixture 41 | def differences(icc1, icc2): 42 | return icc1.compare(icc2).details 43 | 44 | @skip_unless_tools_exist('cd-iccdump') 45 | def test_diff(differences): 46 | expected_diff = get_data('icc_expected_diff') 47 | assert differences[0].unified_diff == expected_diff 48 | 49 | @skip_unless_tools_exist('cd-iccdump') 50 | def test_compare_non_existing(monkeypatch, icc1): 51 | monkeypatch.setattr(Config(), 'new_file', True) 52 | difference = icc1.compare(MissingFile('/nonexisting', icc1)) 53 | assert difference.source2 == '/nonexisting' 54 | assert len(difference.details) > 0 55 | 56 | -------------------------------------------------------------------------------- /tests/comparators/test_ico_image.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.image import ICOImageFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist, skip_unless_tool_is_at_least 26 | from test_jpeg_image import identify_version 27 | 28 | 29 | image1 = load_fixture('test1.ico') 30 | image2 = load_fixture('test2.ico') 31 | image1_meta = load_fixture('test1_meta.ico') 32 | image2_meta = load_fixture('test2_meta.ico') 33 | 34 | def test_identification(image1): 35 | assert isinstance(image1, ICOImageFile) 36 | 37 | def test_no_differences(image1): 38 | difference = image1.compare(image1) 39 | assert difference is None 40 | 41 | @pytest.fixture 42 | def differences(image1, image2): 43 | return image1.compare(image2).details 44 | 45 | @skip_unless_tools_exist('img2txt', 'convert') 46 | def test_diff(differences): 47 | expected_diff = get_data('ico_image_expected_diff') 48 | assert differences[0].unified_diff == expected_diff 49 | 50 | @pytest.fixture 51 | def differences_meta(image1_meta, image2_meta): 52 | return image1_meta.compare(image2_meta).details 53 | 54 | @skip_unless_tools_exist('img2txt', 'identify') 55 | @skip_unless_tool_is_at_least('identify', identify_version, '6.9.6') 56 | def test_diff_meta(differences_meta): 57 | expected_diff = get_data('ico_image_meta_expected_diff') 58 | assert differences_meta[-1].unified_diff == expected_diff 59 | -------------------------------------------------------------------------------- /tests/comparators/test_ipk.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.ipk import IpkFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | 28 | 29 | ipk1 = load_fixture('base-files_157-r45695_ar71xx.ipk') 30 | ipk2 = load_fixture('base-files_157-r45918_ar71xx.ipk') 31 | 32 | def test_identification(ipk1): 33 | assert isinstance(ipk1, IpkFile) 34 | 35 | def test_no_differences(ipk1): 36 | difference = ipk1.compare(ipk1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(ipk1, ipk2): 41 | return ipk1.compare(ipk2).details 42 | 43 | def test_metadata(differences): 44 | assert differences[0].source1 == 'metadata' 45 | expected_diff = get_data('ipk_metadata_expected_diff') 46 | assert differences[0].unified_diff == expected_diff 47 | 48 | def test_compressed_files(differences): 49 | assert differences[1].details[1].source1 == './data.tar.gz' 50 | assert differences[1].details[2].source1 == './control.tar.gz' 51 | 52 | def test_compare_non_existing(monkeypatch, ipk1): 53 | monkeypatch.setattr(Config(), 'new_file', True) 54 | difference = ipk1.compare(MissingFile('/nonexisting', ipk1)) 55 | assert difference.source2 == '/nonexisting' 56 | assert difference.details[-1].source2 == '/dev/null' 57 | -------------------------------------------------------------------------------- /tests/comparators/test_java.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | import subprocess 22 | 23 | from diffoscope.config import Config 24 | from diffoscope.comparators.java import ClassFile 25 | from diffoscope.comparators.missing_file import MissingFile 26 | 27 | from utils.data import load_fixture, get_data 28 | from utils.tools import skip_unless_tools_exist, skip_unless_tool_is_at_least 29 | 30 | 31 | class1 = load_fixture('Test1.class') 32 | class2 = load_fixture('Test2.class') 33 | 34 | def javap_version(): 35 | try: 36 | out = subprocess.check_output(['javap', '-version']) 37 | except subprocess.CalledProcessError as e: 38 | out = e.output 39 | return out.decode('UTF-8').strip() 40 | 41 | def test_identification(class1): 42 | assert isinstance(class1, ClassFile) 43 | 44 | def test_no_differences(class1): 45 | difference = class1.compare(class1) 46 | assert difference is None 47 | 48 | @pytest.fixture 49 | def differences(class1, class2): 50 | return class1.compare(class2).details 51 | 52 | @skip_unless_tool_is_at_least('javap', javap_version, '1.8') 53 | def test_diff(differences): 54 | expected_diff = get_data('class_expected_diff') 55 | assert differences[0].unified_diff == expected_diff 56 | 57 | @skip_unless_tools_exist('javap') 58 | def test_compare_non_existing(monkeypatch, class1): 59 | monkeypatch.setattr(Config(), 'new_file', True) 60 | difference = class1.compare(MissingFile('/nonexisting', class1)) 61 | assert difference.source2 == '/nonexisting' 62 | assert len(difference.details) > 0 63 | -------------------------------------------------------------------------------- /tests/comparators/test_javascript.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Emanuel Bronshtein 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.javascript import JavaScriptFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | javascript1 = load_fixture('test1.js') 31 | javascript2 = load_fixture('test2.js') 32 | 33 | def test_identification(javascript1): 34 | assert isinstance(javascript1, JavaScriptFile) 35 | 36 | def test_no_differences(javascript1): 37 | difference = javascript1.compare(javascript1) 38 | assert difference is None 39 | 40 | @pytest.fixture 41 | def differences(javascript1, javascript2): 42 | return javascript1.compare(javascript2).details 43 | 44 | @skip_unless_tools_exist('js-beautify') 45 | def test_diff(differences): 46 | expected_diff = get_data('javascript_expected_diff') 47 | assert differences[0].unified_diff == expected_diff 48 | 49 | @skip_unless_tools_exist('js-beautify') 50 | def test_compare_non_existing(monkeypatch, javascript1): 51 | monkeypatch.setattr(Config(), 'new_file', True) 52 | difference = javascript1.compare(MissingFile('/nonexisting', javascript1)) 53 | assert difference.source2 == '/nonexisting' 54 | assert len(difference.details) > 0 55 | -------------------------------------------------------------------------------- /tests/comparators/test_json.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.json import JSONFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.nonexisting import assert_non_existing 26 | 27 | 28 | json1 = load_fixture('test1.json') 29 | json2 = load_fixture('test2.json') 30 | json3a = load_fixture('order1a.json') 31 | json3b = load_fixture('order1b.json') 32 | invalid_json = load_fixture('test_invalid.json') 33 | 34 | def test_identification(json1): 35 | assert isinstance(json1, JSONFile) 36 | 37 | def test_invalid(invalid_json): 38 | assert not isinstance(invalid_json, JSONFile) 39 | 40 | def test_no_differences(json1): 41 | assert json1.compare(json1) is None 42 | 43 | @pytest.fixture 44 | def differences(json1, json2): 45 | return json1.compare(json2).details 46 | 47 | def test_diff(differences): 48 | expected_diff = get_data('json_expected_diff') 49 | 50 | assert differences[0].unified_diff == expected_diff 51 | 52 | def test_compare_non_existing(monkeypatch, json1): 53 | assert_non_existing(monkeypatch, json1) 54 | 55 | def test_ordering_differences(json3a, json3b): 56 | diff = json3a.compare(json3b) 57 | assert diff.details[0]._comments == ['ordering differences only'] 58 | assert diff.details[0].unified_diff == get_data('order1.diff') 59 | -------------------------------------------------------------------------------- /tests/comparators/test_mono.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Daniel Kahn Gillmor 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.config import Config 23 | from diffoscope.comparators.mono import MonoExeFile 24 | from diffoscope.comparators.missing_file import MissingFile 25 | 26 | from utils.data import load_fixture, get_data 27 | from utils.tools import skip_unless_tools_exist 28 | 29 | 30 | # these were generated with: 31 | 32 | # echo 'public class Test { static public void Main () {} }' > test.cs 33 | # mcs -out:test1.exe test.cs ; sleep 2; mcs -out:test2.exe test.cs 34 | 35 | exe1 = load_fixture('test1.exe') 36 | exe2 = load_fixture('test2.exe') 37 | 38 | def test_identification(exe1): 39 | assert isinstance(exe1, MonoExeFile) 40 | 41 | def test_no_differences(exe1): 42 | difference = exe1.compare(exe1) 43 | assert difference is None 44 | 45 | @pytest.fixture 46 | def differences(exe1, exe2): 47 | return exe1.compare(exe2).details 48 | 49 | @skip_unless_tools_exist('pedump') 50 | def test_diff(differences): 51 | expected_diff = get_data('pe_expected_diff') 52 | assert differences[0].unified_diff == expected_diff 53 | 54 | @skip_unless_tools_exist('pedump') 55 | def test_compare_non_existing(monkeypatch, exe1): 56 | monkeypatch.setattr(Config(), 'new_file', True) 57 | difference = exe1.compare(MissingFile('/nonexisting', exe1)) 58 | assert difference.source2 == '/nonexisting' 59 | assert len(difference.details) > 0 60 | -------------------------------------------------------------------------------- /tests/comparators/test_pdf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.pdf import PdfFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | 29 | pdf1 = load_fixture('test1.pdf') 30 | pdf2 = load_fixture('test2.pdf') 31 | 32 | def test_identification(pdf1): 33 | assert isinstance(pdf1, PdfFile) 34 | 35 | def test_no_differences(pdf1): 36 | difference = pdf1.compare(pdf1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(pdf1, pdf2): 41 | return pdf1.compare(pdf2).details 42 | 43 | @skip_unless_tools_exist('pdftk', 'pdftotext') 44 | def test_text_diff(differences): 45 | expected_diff = get_data('pdf_text_expected_diff') 46 | assert differences[0].unified_diff == expected_diff 47 | 48 | @skip_unless_tools_exist('pdftk', 'pdftotext') 49 | def test_internal_diff(differences): 50 | expected_diff = get_data('pdf_internal_expected_diff') 51 | assert differences[1].unified_diff == expected_diff 52 | 53 | @skip_unless_tools_exist('pdftk', 'pdftotext') 54 | def test_compare_non_existing(monkeypatch, pdf1): 55 | assert_non_existing(monkeypatch, pdf1, has_null_source=False) 56 | -------------------------------------------------------------------------------- /tests/comparators/test_png.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.png import PngFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | 29 | png1 = load_fixture('test1.png') 30 | png2 = load_fixture('test2.png') 31 | 32 | def test_identification(png1): 33 | assert isinstance(png1, PngFile) 34 | 35 | def test_no_differences(png1): 36 | difference = png1.compare(png1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(png1, png2): 41 | return png1.compare(png2).details 42 | 43 | @skip_unless_tools_exist('sng') 44 | def test_diff(differences): 45 | expected_diff = get_data('png_expected_diff') 46 | assert differences[0].unified_diff == expected_diff 47 | 48 | @skip_unless_tools_exist('sng') 49 | def test_compare_non_existing(monkeypatch, png1): 50 | assert_non_existing(monkeypatch, png1, has_null_source=False) 51 | -------------------------------------------------------------------------------- /tests/comparators/test_ps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Reiner Herrmann 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.ps import PsFile 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | 29 | ps1 = load_fixture('test1.ps') 30 | ps2 = load_fixture('test2.ps') 31 | 32 | def test_identification(ps1): 33 | assert isinstance(ps1, PsFile) 34 | 35 | def test_no_differences(ps1): 36 | difference = ps1.compare(ps1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(ps1, ps2): 41 | return ps1.compare(ps2) 42 | 43 | @skip_unless_tools_exist('ps2ascii') 44 | def test_internal_diff(differences): 45 | expected_diff = get_data('ps_internal_expected_diff') 46 | assert differences.unified_diff == expected_diff 47 | 48 | @skip_unless_tools_exist('ps2ascii') 49 | def test_text_diff(differences): 50 | expected_diff = get_data('ps_text_expected_diff') 51 | assert differences.details[0].unified_diff == expected_diff 52 | 53 | @skip_unless_tools_exist('ps2ascii') 54 | def test_compare_non_existing(monkeypatch, ps1): 55 | assert_non_existing(monkeypatch, ps1, has_null_source=False) 56 | -------------------------------------------------------------------------------- /tests/comparators/test_sqlite.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.comparators.sqlite import Sqlite3Database 23 | 24 | from utils.data import load_fixture, get_data 25 | from utils.tools import skip_unless_tools_exist 26 | from utils.nonexisting import assert_non_existing 27 | 28 | 29 | sqlite3db1 = load_fixture('test1.sqlite3') 30 | sqlite3db2 = load_fixture('test2.sqlite3') 31 | 32 | def test_identification(sqlite3db1): 33 | assert isinstance(sqlite3db1, Sqlite3Database) 34 | 35 | def test_no_differences(sqlite3db1): 36 | difference = sqlite3db1.compare(sqlite3db1) 37 | assert difference is None 38 | 39 | @pytest.fixture 40 | def differences(sqlite3db1, sqlite3db2): 41 | return sqlite3db1.compare(sqlite3db2).details 42 | 43 | @skip_unless_tools_exist('sqlite3') 44 | def test_diff(differences): 45 | expected_diff = get_data('sqlite3_expected_diff') 46 | assert differences[0].unified_diff == expected_diff 47 | 48 | @skip_unless_tools_exist('sqlite3') 49 | def test_compare_non_existing(monkeypatch, sqlite3db1): 50 | assert_non_existing(monkeypatch, sqlite3db1, has_null_source=False) 51 | -------------------------------------------------------------------------------- /tests/comparators/test_symlink.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | 22 | from diffoscope.comparators.binary import FilesystemFile 23 | from diffoscope.comparators.utils.specialize import specialize 24 | 25 | from utils.data import get_data 26 | 27 | 28 | def test_destination(tmpdir): 29 | def create(x): 30 | path = os.path.join(str(tmpdir.mkdir(x)), 'src') 31 | os.symlink('/{}'.format(x), path) 32 | return specialize(FilesystemFile(path)) 33 | 34 | a = create('a') 35 | b = create('b') 36 | 37 | expected_diff = get_data('symlink_expected_destination_diff') 38 | 39 | assert a.compare(b).unified_diff == expected_diff 40 | -------------------------------------------------------------------------------- /tests/comparators/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import re 21 | 22 | re_diff_line_numbers = re.compile(r"(^|\n)@@ -(\d+),(\d+) \+(\d+),(\d+) @@(?=\n|$)") 23 | 24 | def diff_ignore_line_numbers(diff): 25 | return re_diff_line_numbers.sub(r"\1@@ -XX,XX +XX,XX @@", diff) 26 | -------------------------------------------------------------------------------- /tests/comparators/utils/data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 2016-2017 Mattia Rizzolo 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | import os 22 | import re 23 | import pytest 24 | 25 | from diffoscope.comparators.binary import FilesystemFile 26 | from diffoscope.comparators.utils.specialize import specialize 27 | 28 | re_normalize_zeros = re.compile( 29 | r'^(?P[ \-\+])(?P[0-9a-f]+)(?=: )', re.MULTILINE, 30 | ) 31 | 32 | 33 | def init_fixture(filename): 34 | return pytest.fixture( 35 | lambda: specialize(FilesystemFile(filename)) 36 | ) 37 | 38 | 39 | def data(filename): 40 | return os.path.join( 41 | os.path.dirname(os.path.dirname(__file__)), 42 | '..', 43 | 'data', 44 | filename, 45 | ) 46 | 47 | 48 | def get_data(filename): 49 | with open(data(filename), encoding='utf-8') as f: 50 | return f.read() 51 | 52 | 53 | def load_fixture(filename): 54 | return init_fixture(data(filename)) 55 | 56 | 57 | def normalize_zeros(s): 58 | # older xxd had one zero less. Make sure there are always 8. 59 | def repl(x): 60 | return '{}{:08x}'.format(x.group('prefix'), int(x.group('offset'), 16)) 61 | return re_normalize_zeros.sub(repl, s) 62 | -------------------------------------------------------------------------------- /tests/comparators/utils/nonexisting.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 2016-2017 Mattia Rizzolo 7 | # 8 | # diffoscope is free software: you can redistribute it and/or modify 9 | # it under the terms of the GNU General Public License as published by 10 | # the Free Software Foundation, either version 3 of the License, or 11 | # (at your option) any later version. 12 | # 13 | # diffoscope is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | # GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with diffoscope. If not, see . 20 | 21 | from diffoscope.config import Config 22 | from diffoscope.comparators.missing_file import MissingFile 23 | 24 | 25 | def assert_non_existing(monkeypatch, fixture, has_null_source=True, has_details=True): 26 | monkeypatch.setattr(Config(), 'new_file', True) 27 | assert Config().new_file, "didnt get patched" 28 | 29 | difference = fixture.compare(MissingFile('/nonexisting', fixture)) 30 | 31 | assert difference.source2 == '/nonexisting' 32 | assert not has_details or len(difference.details) > 0 33 | assert not has_null_source or difference.details[-1].source2 == '/dev/null' 34 | -------------------------------------------------------------------------------- /tests/conftest.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2016 Brett Smith 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import pytest 21 | 22 | from diffoscope.locale import set_locale 23 | from diffoscope.progress import ProgressManager 24 | from diffoscope.comparators import ComparatorManager 25 | 26 | 27 | # Ensure set_locale fixture runs before all tests. 28 | set_locale = pytest.fixture(autouse=True, scope='session')(set_locale) 29 | 30 | @pytest.fixture(autouse=True) 31 | def reload_comparators(): 32 | # Reload Comparators after every test so we are always in a consistent 33 | # state 34 | ComparatorManager().reload() 35 | 36 | @pytest.fixture(autouse=True) 37 | def reset_progress(): 38 | ProgressManager().reset() 39 | -------------------------------------------------------------------------------- /tests/data/Samyak-Malayalam1.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/Samyak-Malayalam1.ttf -------------------------------------------------------------------------------- /tests/data/Samyak-Malayalam2.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/Samyak-Malayalam2.ttf -------------------------------------------------------------------------------- /tests/data/Test1.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/Test1.class -------------------------------------------------------------------------------- /tests/data/Test2.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/Test2.class -------------------------------------------------------------------------------- /tests/data/apk_manifest_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,9 +1,9 @@ 2 | 3 | - 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/data/apk_zipinfo_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | -Zip file size: 866 bytes, number of entries: 1 3 | +Zip file size: 864 bytes, number of entries: 1 4 | -rw---- 2.0 fat 2096 bl defN 80-Jan-01 02:00 AndroidManifest.xml 5 | -1 file, 2096 bytes uncompressed, 714 bytes compressed: 65.9% 6 | +1 file, 2096 bytes uncompressed, 712 bytes compressed: 66.0% 7 | -------------------------------------------------------------------------------- /tests/data/base-files_157-r45695_ar71xx.ipk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/base-files_157-r45695_ar71xx.ipk -------------------------------------------------------------------------------- /tests/data/base-files_157-r45918_ar71xx.ipk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/base-files_157-r45918_ar71xx.ipk -------------------------------------------------------------------------------- /tests/data/binary1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/binary1 -------------------------------------------------------------------------------- /tests/data/binary2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/binary2 -------------------------------------------------------------------------------- /tests/data/binary_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -00000000: c633 e589 d7d7 ed19 228e d7d3 e325 2309 .3......"....%#. 3 | +00000000: cfa9 41f6 baf2 e1f3 65af 9f01 cf2f f2f5 ..A.....e..../.. 4 | -------------------------------------------------------------------------------- /tests/data/binary_hexdump_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -c633e589d7d7ed19228ed7d3e3252309 3 | +cfa941f6baf2e1f365af9f01cf2ff2f5 4 | -------------------------------------------------------------------------------- /tests/data/cbfs_listing_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,6 +1,3 @@ 2 | -32 kB, bootblocksize 0, romsize 32768, offset 0x0 3 | -alignment: 64 bytes, architecture: x86 4 | - 5 | Name Offset Type Size 6 | -text 0x0 raw 446 7 | -(empty) 0x200 null 32152 8 | +text 0x0 raw 671 9 | +(empty) 0x300 null 31896 10 | -------------------------------------------------------------------------------- /tests/data/class_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -31,13 +31,13 @@ 2 | line 1: 0 3 | 4 | public static int main(java.lang.String[]); 5 | descriptor: ([Ljava/lang/String;)I 6 | flags: ACC_PUBLIC, ACC_STATIC 7 | Code: 8 | stack=1, locals=1, args_size=1 9 | - 0: bipush 42 10 | - 2: ireturn 11 | + 0: iconst_m1 12 | + 1: ireturn 13 | LineNumberTable: 14 | line 3: 0 15 | } 16 | SourceFile: "Test.java" 17 | -------------------------------------------------------------------------------- /tests/data/cpio_listing_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,4 +1,4 @@ 2 | -lrwxrwxrwx 1 1000 1000 6 2015-06-24 15:10:12.000000 dir/link -> broken 3 | +lrwxrwxrwx 1 1000 1000 13 2015-06-24 15:11:35.000000 dir/link -> really-broken 4 | crw-r--r-- 1 0 0 1, 3 2015-06-24 14:47:34.000000 dir/null 5 | --rw-r--r-- 1 1000 1000 446 2015-06-24 15:10:17.000000 dir/text 6 | -drwxr-xr-x 2 1000 1000 0 2015-06-24 15:10:12.000000 dir 7 | +-rw-r--r-- 1 1000 1000 671 2015-06-24 15:11:38.000000 dir/text 8 | +drwxr-xr-x 2 1000 1000 0 2015-06-24 15:11:35.000000 dir 9 | -------------------------------------------------------------------------------- /tests/data/dbgsym/add/test-dbgsym-dbgsym_1_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/dbgsym/add/test-dbgsym-dbgsym_1_amd64.deb -------------------------------------------------------------------------------- /tests/data/dbgsym/add/test-dbgsym_1_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/dbgsym/add/test-dbgsym_1_amd64.deb -------------------------------------------------------------------------------- /tests/data/dbgsym/mult/test-dbgsym-dbgsym_1_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/dbgsym/mult/test-dbgsym-dbgsym_1_amd64.deb -------------------------------------------------------------------------------- /tests/data/dbgsym/mult/test-dbgsym_1_amd64.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/dbgsym/mult/test-dbgsym_1_amd64.deb -------------------------------------------------------------------------------- /tests/data/dbgsym/test-dbgsym_1.dsc: -------------------------------------------------------------------------------- 1 | Format: 1.0 2 | Source: test-dbgsym 3 | Binary: test-dbgsym 4 | Architecture: any 5 | Version: 1 6 | Maintainer: Public Domain 7 | Build-Depends: debhelper (>= 9) 8 | Package-List: 9 | test-dbgsym deb unknown unknown arch=any 10 | Checksums-Sha1: 11 | 47366ea942a8862bc921924dab97318307c7b81e 729 test-dbgsym_1.tar.gz 12 | Checksums-Sha256: 13 | fdbf82cd56628391bb7ee2715be8f486aa86999257daeb91adcb62392c1dbfe7 729 test-dbgsym_1.tar.gz 14 | Files: 15 | ce130dbb7911de551405a3472799deca 729 test-dbgsym_1.tar.gz 16 | -------------------------------------------------------------------------------- /tests/data/dbgsym/test-dbgsym_1.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/dbgsym/test-dbgsym_1.tar.gz -------------------------------------------------------------------------------- /tests/data/deb_metadata_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | --rw-r--r-- 0 0 0 4 2015-06-24 17:40:03.000000 debian-binary 3 | --rw-r--r-- 0 0 0 444 2015-06-24 17:40:03.000000 control.tar.gz 4 | --rw-r--r-- 0 0 0 1626 2015-06-24 17:40:03.000000 data.tar.gz 5 | +-rw-r--r-- 0 0 0 4 2015-06-24 17:40:26.000000 debian-binary 6 | +-rw-r--r-- 0 0 0 442 2015-06-24 17:40:26.000000 control.tar.gz 7 | +-rw-r--r-- 0 0 0 1754 2015-06-24 17:40:26.000000 data.tar.gz 8 | -------------------------------------------------------------------------------- /tests/data/device_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,28 @@ 2 | -00000000: 6465 7669 6365 3a63 6861 7261 6374 6572 device:character 3 | -00000010: 0a6d 616a 6f72 3a20 310a 6d69 6e6f 723a .major: 1.minor: 4 | -00000020: 2033 0a 3. 5 | +00000000: 4c6f 7265 6d20 6970 7375 6d20 646f 6c6f Lorem ipsum dolo 6 | +00000010: 7220 7369 7420 616d 6574 2c20 636f 6e73 r sit amet, cons 7 | +00000020: 6563 7465 7475 7220 6164 6970 6973 6369 ectetur adipisci 8 | +00000030: 6e67 2065 6c69 742c 2073 6564 2064 6f20 ng elit, sed do 9 | +00000040: 6569 7573 6d6f 6420 7465 6d70 6f72 0a69 eiusmod tempor.i 10 | +00000050: 6e63 6964 6964 756e 7420 7574 206c 6162 ncididunt ut lab 11 | +00000060: 6f72 6520 6574 2064 6f6c 6f72 6520 6d61 ore et dolore ma 12 | +00000070: 676e 6120 616c 6971 7561 2e20 5574 2065 gna aliqua. Ut e 13 | +00000080: 6e69 6d20 6164 206d 696e 696d 2076 656e nim ad minim ven 14 | +00000090: 6961 6d2c 2071 7569 730a 6e6f 7374 7275 iam, quis.nostru 15 | +000000a0: 6420 6578 6572 6369 7461 7469 6f6e 2075 d exercitation u 16 | +000000b0: 6c6c 616d 636f 206c 6162 6f72 6973 206e llamco laboris n 17 | +000000c0: 6973 6920 7574 2061 6c69 7175 6970 2065 isi ut aliquip e 18 | +000000d0: 7820 6561 2063 6f6d 6d6f 646f 2063 6f6e x ea commodo con 19 | +000000e0: 7365 7175 6174 2e0a 4475 6973 2061 7574 sequat..Duis aut 20 | +000000f0: 6520 6972 7572 6520 646f 6c6f 7220 696e e irure dolor in 21 | +00000100: 2072 6570 7265 6865 6e64 6572 6974 2069 reprehenderit i 22 | +00000110: 6e20 766f 6c75 7074 6174 6520 7665 6c69 n voluptate veli 23 | +00000120: 7420 6573 7365 2063 696c 6c75 6d20 646f t esse cillum do 24 | +00000130: 6c6f 7265 2065 750a 6675 6769 6174 206e lore eu.fugiat n 25 | +00000140: 756c 6c61 2070 6172 6961 7475 722e 2045 ulla pariatur. E 26 | +00000150: 7863 6570 7465 7572 2073 696e 7420 6f63 xcepteur sint oc 27 | +00000160: 6361 6563 6174 2063 7570 6964 6174 6174 caecat cupidatat 28 | +00000170: 206e 6f6e 2070 726f 6964 656e 742c 2073 non proident, s 29 | +00000180: 756e 7420 696e 0a63 756c 7061 2071 7569 unt in.culpa qui 30 | +00000190: 206f 6666 6963 6961 2064 6573 6572 756e officia deserun 31 | +000001a0: 7420 6d6f 6c6c 6974 2061 6e69 6d20 6964 t mollit anim id 32 | +000001b0: 2065 7374 206c 6162 6f72 756d 2e0a est laborum.. 33 | -------------------------------------------------------------------------------- /tests/data/device_expected_diff_reverse: -------------------------------------------------------------------------------- 1 | @@ -1,28 +1,3 @@ 2 | -00000000: 4c6f 7265 6d20 6970 7375 6d20 646f 6c6f Lorem ipsum dolo 3 | -00000010: 7220 7369 7420 616d 6574 2c20 636f 6e73 r sit amet, cons 4 | -00000020: 6563 7465 7475 7220 6164 6970 6973 6369 ectetur adipisci 5 | -00000030: 6e67 2065 6c69 742c 2073 6564 2064 6f20 ng elit, sed do 6 | -00000040: 6569 7573 6d6f 6420 7465 6d70 6f72 0a69 eiusmod tempor.i 7 | -00000050: 6e63 6964 6964 756e 7420 7574 206c 6162 ncididunt ut lab 8 | -00000060: 6f72 6520 6574 2064 6f6c 6f72 6520 6d61 ore et dolore ma 9 | -00000070: 676e 6120 616c 6971 7561 2e20 5574 2065 gna aliqua. Ut e 10 | -00000080: 6e69 6d20 6164 206d 696e 696d 2076 656e nim ad minim ven 11 | -00000090: 6961 6d2c 2071 7569 730a 6e6f 7374 7275 iam, quis.nostru 12 | -000000a0: 6420 6578 6572 6369 7461 7469 6f6e 2075 d exercitation u 13 | -000000b0: 6c6c 616d 636f 206c 6162 6f72 6973 206e llamco laboris n 14 | -000000c0: 6973 6920 7574 2061 6c69 7175 6970 2065 isi ut aliquip e 15 | -000000d0: 7820 6561 2063 6f6d 6d6f 646f 2063 6f6e x ea commodo con 16 | -000000e0: 7365 7175 6174 2e0a 4475 6973 2061 7574 sequat..Duis aut 17 | -000000f0: 6520 6972 7572 6520 646f 6c6f 7220 696e e irure dolor in 18 | -00000100: 2072 6570 7265 6865 6e64 6572 6974 2069 reprehenderit i 19 | -00000110: 6e20 766f 6c75 7074 6174 6520 7665 6c69 n voluptate veli 20 | -00000120: 7420 6573 7365 2063 696c 6c75 6d20 646f t esse cillum do 21 | -00000130: 6c6f 7265 2065 750a 6675 6769 6174 206e lore eu.fugiat n 22 | -00000140: 756c 6c61 2070 6172 6961 7475 722e 2045 ulla pariatur. E 23 | -00000150: 7863 6570 7465 7572 2073 696e 7420 6f63 xcepteur sint oc 24 | -00000160: 6361 6563 6174 2063 7570 6964 6174 6174 caecat cupidatat 25 | -00000170: 206e 6f6e 2070 726f 6964 656e 742c 2073 non proident, s 26 | -00000180: 756e 7420 696e 0a63 756c 7061 2071 7569 unt in.culpa qui 27 | -00000190: 206f 6666 6963 6961 2064 6573 6572 756e officia deserun 28 | -000001a0: 7420 6d6f 6c6c 6974 2061 6e69 6d20 6964 t mollit anim id 29 | -000001b0: 2065 7374 206c 6162 6f72 756d 2e0a est laborum.. 30 | +00000000: 6465 7669 6365 3a63 6861 7261 6374 6572 device:character 31 | +00000010: 0a6d 616a 6f72 3a20 310a 6d69 6e6f 723a .major: 1.minor: 32 | +00000020: 2033 0a 3. 33 | -------------------------------------------------------------------------------- /tests/data/dex_expected_diffs: -------------------------------------------------------------------------------- 1 | @@ -54,15 +54,15 @@ 2 | version of encoding software: 2.0 3 | minimum file system compatibility required: MS-DOS, OS/2 or NT FAT 4 | minimum software version required to extract: 2.0 5 | compression method: none (stored) 6 | file security status: not encrypted 7 | extended local header: no 8 | file last modified on (DOS date/time): 1980 Jan 1 00:00:00 9 | - 32-bit CRC value (hex): bc28236e 10 | + 32-bit CRC value (hex): 59c3af78 11 | compressed size: 305 bytes 12 | uncompressed size: 305 bytes 13 | length of filename: 30 characters 14 | length of extra field: 0 bytes 15 | length of file comment: 0 characters 16 | disk number on which file begins: disk 1 17 | apparent file type: binary 18 | @@ -17,16 +17,16 @@ 19 | #12 = Methodref #4.#11 // android/app/Activity.onCreate:(Landroid/os/Bundle;)V 20 | #13 = Integer 2130903040 21 | #14 = Float 1.7412887E38f 22 | #15 = Utf8 setContentView 23 | #16 = Utf8 (I)V 24 | #17 = NameAndType #15:#16 // setContentView:(I)V 25 | #18 = Methodref #2.#17 // com/example/MainActivity.setContentView:(I)V 26 | - #19 = Utf8 Sat Nov 21 14:20:33 CET 2015 27 | - #20 = String #19 // Sat Nov 21 14:20:33 CET 2015 28 | + #19 = Utf8 Thu Mar 17 11:54:42 CET 2016 29 | + #20 = String #19 // Thu Mar 17 11:54:42 CET 2016 30 | #21 = Utf8 Code 31 | { 32 | public com.example.MainActivity(); 33 | descriptor: ()V 34 | flags: ACC_PUBLIC 35 | Code: 36 | stack=300, locals=1, args_size=1 37 | -------------------------------------------------------------------------------- /tests/data/dot_buildinfo_fallback_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,19 +1,19 @@ 2 | Format: 1.0 3 | Build-Architecture: amd64 4 | Source: test 5 | Binary: test 6 | Architecture: all 7 | Version: 1 8 | Checksums-Md5: 9 | - 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb 10 | + d323c454462407fe3bfde31a74b23eba 2388 test_1_all.deb 11 | Checksums-Sha1: 12 | - b21eeec5004853c4955d5b856a6546068c2d7dc9 2262 test_1_all.deb 13 | + 70982664db2015334bff6441b429d7e3c58dbecb 2388 test_1_all.deb 14 | Checksums-Sha256: 15 | - d2b2ea8b9cf8ef645a328cdb882586ee465e141fc66a2dbe1ad29b29ac1e7920 2262 test_1_all.deb 16 | + 2f2e45ee3a5fdacd9b30133ec728121588bf9b97af3b947b3882b2b28a0555da 2388 test_1_all.deb 17 | Build-Path: /build/test-1 18 | Build-Environment: 19 | base-files (= 9.4), 20 | base-passwd (= 3.5.38), 21 | bash (= 4.3-14), 22 | binutils (= 2.25.1-5), 23 | bsdmainutils (= 9.0.6), 24 | -------------------------------------------------------------------------------- /tests/data/dot_changes_description_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -test - just a test package 3 | +test - just a simple test package 4 | -------------------------------------------------------------------------------- /tests/data/dot_changes_different_contents_and_identical_files_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | 3 | d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb 4 | - 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_2.buildinfo 5 | + 9972d7c394228311ba92cbcbfe2d6cd9 3765 web optional test_2.buildinfo 6 | -------------------------------------------------------------------------------- /tests/data/dot_changes_fallback_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -5,21 +5,21 @@ 2 | Architecture: source all 3 | Version: 1 4 | Distribution: unstable 5 | Urgency: low 6 | Maintainer: Someone Else 7 | Changed-By: Someone Else 8 | Description: 9 | - test - just a test package 10 | + test - just a simple test package 11 | Changes: 12 | test (1) unstable; urgency=low 13 | . 14 | * Test package. 15 | Checksums-Sha1: 16 | - b21eeec5004853c4955d5b856a6546068c2d7dc9 2262 test_1_all.deb 17 | - e1cafb5f8db51f4ec477807d105b1e3cccf9a767 3780 test_1.buildinfo 18 | + 70982664db2015334bff6441b429d7e3c58dbecb 2388 test_1_all.deb 19 | + 91d2cc6aadddb4a24b0c2f8f24d558ce0e07f9cd 3765 test_2.buildinfo 20 | Checksums-Sha256: 21 | - d2b2ea8b9cf8ef645a328cdb882586ee465e141fc66a2dbe1ad29b29ac1e7920 2262 test_1_all.deb 22 | - 167d989223978a45a69af30dcd488baa00aec2045b66d0f74d7f03b08fd22365 3780 test_1.buildinfo 23 | + 2f2e45ee3a5fdacd9b30133ec728121588bf9b97af3b947b3882b2b28a0555da 2388 test_1_all.deb 24 | + 917d8b5c3ade2bde26fe2b7476481537f32a0c07f10e5e44c0ca7a02c8bfa9d8 3765 test_2.buildinfo 25 | Files: 26 | - 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb 27 | - 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_1.buildinfo 28 | + d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb 29 | + 9972d7c394228311ba92cbcbfe2d6cd9 3765 web optional test_2.buildinfo 30 | -------------------------------------------------------------------------------- /tests/data/dot_changes_identical_contents_and_different_files_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | 3 | - 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb 4 | - 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_1.buildinfo 5 | + d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb 6 | + 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_2.buildinfo 7 | -------------------------------------------------------------------------------- /tests/data/dot_dsc_fallback_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -5,12 +5,12 @@ 2 | Version: 1 3 | Maintainer: Someone Else 4 | Standards-Version: 3.9.6 5 | Build-Depends: debhelper (>= 7) 6 | Package-List: 7 | test deb misc optional 8 | Checksums-Sha1: 9 | - 2f66c0cf9788240c8c3321193d4a628157748445 2086 test_1.tar.gz 10 | + 7453b45105d06be451cbc472c2fa1df13a60eb27 2193 test_1.tar.gz 11 | Checksums-Sha256: 12 | - 1066cb6c1fca0423eb449b7aac27d5a477c55f4262ab8af438100a6d2ee039b4 2086 test_1.tar.gz 13 | + ff86b4d705489ee0f2825a935100f9a0981b6c8c4c0eb5e19436c8599da14324 2193 test_1.tar.gz 14 | Files: 15 | - 42c53394ba8bb4d92aab8d40d33507d7 2086 test_1.tar.gz 16 | + b75f3bae96326e1c518dba429a81f91c 2193 test_1.tar.gz 17 | -------------------------------------------------------------------------------- /tests/data/elf_lib_metadata_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,2 +1,2 @@ 2 | ----------- 0 0 0 10 2015-06-24 12:14:19.000000 / 3 | --rw-r--r-- 0 1000 1000 1216 2015-06-24 12:13:47.000000 test.o 4 | +---------- 0 0 0 10 2015-06-24 12:14:29.000000 / 5 | +-rw-r--r-- 0 1000 1000 1216 2015-06-24 12:14:27.000000 test.o 6 | -------------------------------------------------------------------------------- /tests/data/elf_lib_objdump_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -4,10 +4,10 @@ 2 | 3 | Disassembly of section .text: 4 | 5 | 0000000000000000 : 6 | f(): 7 | 0: 55 push %rbp 8 | 1: 48 89 e5 mov %rsp,%rbp 9 | - 4: b8 2a 00 00 00 mov $0x2a,%eax 10 | + 4: b8 ff ff ff ff mov $0xffffffff,%eax 11 | 9: 5d pop %rbp 12 | a: c3 retq 13 | -------------------------------------------------------------------------------- /tests/data/elf_obj_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -3,10 +3,10 @@ 2 | 3 | Disassembly of section .text: 4 | 5 | 0000000000000000 : 6 | f(): 7 | 0: 55 push %rbp 8 | 1: 48 89 e5 mov %rsp,%rbp 9 | - 4: b8 2a 00 00 00 mov $0x2a,%eax 10 | + 4: b8 ff ff ff ff mov $0xffffffff,%eax 11 | 9: 5d pop %rbp 12 | a: c3 retq 13 | -------------------------------------------------------------------------------- /tests/data/ext4_expected_diffs: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | -drwxr-xr-x 0 0 0 0 2015-12-02 16:01:40.000000 ./ 3 | +drwxr-xr-x 0 0 0 0 2015-12-02 16:03:11.000000 ./ 4 | drwx------ 0 0 0 0 2015-12-02 16:00:55.000000 ./lost+found/ 5 | --rw-rw-rw- 0 1234 1234 28 2015-12-02 16:01:40.000000 ./date.txt 6 | +-r--r--r-- 0 4321 4321 44 2015-12-02 16:03:11.000000 ./date.txt 7 | @@ -1 +1 @@ 8 | -Wed Dec 2 17:01:40 CET 2015 9 | +jeudi 3 décembre 2015, 06:03:11 (UTC+1400) 10 | @@ -1 +1 @@ 11 | -us-ascii 12 | +utf-8 13 | -------------------------------------------------------------------------------- /tests/data/fuzzy1.tar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/fuzzy1.tar -------------------------------------------------------------------------------- /tests/data/git_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -10,7 +10,18 @@ 2 | User ID: 1000 3 | Group ID: 1000 4 | Created: 1471689380.154572964 5 | Modified: 1471689380.154572964 6 | Inode: 52205983 7 | Device ID: (8, 6) 8 | 9 | +Path: b'b' 10 | +SHA: e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 11 | +Size: 0 12 | +Flags: 0b1 13 | +User ID: 1000 14 | +Group ID: 1000 15 | +Created: 1471689417.184218147 16 | +Modified: 1471689417.184218147 17 | +Inode: 52206041 18 | +Device ID: (8, 6) 19 | + 20 | -------------------------------------------------------------------------------- /tests/data/gnu_debuglink_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,7 +1,7 @@ 2 | 3 | Hex dump of section '.gnu_debuglink': 4 | - 0x00000000 66626137 37633062 39376332 30356639 fba77c0b97c205f9 5 | - 0x00000010 31343537 38333630 34356265 64396134 1457836045bed9a4 6 | - 0x00000020 31616431 62642e64 65627567 00000000 1ad1bd.debug.... 7 | - 0x00000030 76f9942d v..- 8 | + 0x00000000 33336535 61393266 63366362 64663338 33e5a92fc6cbdf38 9 | + 0x00000010 61336566 34343333 38333364 33613639 a3ef4433833d3a69 10 | + 0x00000020 64326333 63642e64 65627567 00000000 d2c3cd.debug.... 11 | + 0x00000030 4732b79e G2.. 12 | 13 | -------------------------------------------------------------------------------- /tests/data/gzip_metadata_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -gzip compressed data, last modified: Tue Jun 23 10:12:28 2015, max compression, from Unix 3 | +gzip compressed data, last modified: Tue Jun 23 10:12:28 2015, from Unix 4 | -------------------------------------------------------------------------------- /tests/data/icc_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,20 +1,20 @@ 2 | icc: 3 | Header: 4 | Size = 14684 bytes 5 | Version = 4.3 6 | Profile Kind = display-device 7 | Colorspace = rgb 8 | Conn. Space = xyz 9 | - Date, Time = 2016-02-15, 21:02:09 10 | + Date, Time = 2016-02-15, 21:03:22 11 | Flags = Not embedded profile, Use anywhere 12 | Dev. Attrbts = reflective, glossy 13 | Rndrng Intnt = perceptual 14 | Creator = lcms 15 | - Profile ID = 0x0477fa4b 16 | + Profile ID = 0x06017f17 17 | 18 | tag 00: 19 | sig 'desc' [0x64657363] 20 | size 38 21 | type 'mluc' [0x6d6c7563] 22 | Text: 23 | en_US: sRGB [24 bytes] 24 | -------------------------------------------------------------------------------- /tests/data/ico_image_meta_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,17 +1,17 @@ 2 | Image format: ICO 3 | -File size: 6.93KB 4 | +File size: 3.27KB 5 | Height: 100 6 | Width: 100 7 | Orientation: Undefined 8 | Compression type: Undefined 9 | Compression quality: 0 10 | Colorspace: sRGB 11 | Channels: srgba 12 | -Depth: 4 13 | +Depth: 1 14 | Interlace mode: None 15 | Rendering intent: Perceptual 16 | X resolution: 0 17 | Y resolution: 0 18 | Resolution units: Undefined 19 | Transparency channel enabled: True 20 | Gamma: 0.454545 21 | -------------------------------------------------------------------------------- /tests/data/ipk_metadata_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -gzip compressed data, last modified: Mon May 18 23:26:52 2015, from Unix 3 | +gzip compressed data, last modified: Mon Jun 8 17:31:21 2015, from Unix 4 | -------------------------------------------------------------------------------- /tests/data/iso9660_content_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,7 +1,7 @@ 2 | 3 | Directory listing of / 4 | d--------- 0 0 0 2048 Jun 24 2015 [ 23 02] . 5 | d--------- 0 0 0 2048 Jun 24 2015 [ 23 02] .. 6 | ---------- 0 0 0 0 Jun 24 2015 [ 25 00] LINK.;1 7 | ---------- 0 0 0 0 Jun 24 2015 [ 25 00] NULL.;1 8 | ----------- 0 0 0 446 Jun 24 2015 [ 25 00] TEXT.;1 9 | +---------- 0 0 0 671 Jun 24 2015 [ 25 00] TEXT.;1 10 | -------------------------------------------------------------------------------- /tests/data/iso9660_rockridge_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,7 +1,7 @@ 2 | 3 | Directory listing of / 4 | drwxr-xr-x 2 1750 1750 2048 Jun 24 2015 [ 23 02] . 5 | drwxr-xr-x 2 1750 1750 2048 Jun 24 2015 [ 23 02] .. 6 | -lrwxrwxrwx 1 1750 1750 0 Jun 24 2015 [ 25 00] link -> broken 7 | +lrwxrwxrwx 1 1750 1750 0 Jun 24 2015 [ 25 00] link -> really-broken 8 | crw-r--r-- 1 0 0 0 Jun 24 2015 [ 25 00] null 9 | --rw-r--r-- 1 1750 1750 446 Jun 24 2015 [ 25 00] text 10 | +-rw-r--r-- 1 1750 1750 671 Jun 24 2015 [ 25 00] text 11 | -------------------------------------------------------------------------------- /tests/data/javascript_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,8 +1,8 @@ 2 | function test(str) { 3 | alert(str); 4 | - prompt(str, "TEST1") 5 | + prompt(str, "TEST2") 6 | } 7 | x = 1; 8 | -y = 2; 9 | -z = /.+/; 10 | -d = [2015, 2016]; //comment 11 | +y = 3; 12 | +z = /.*/; 13 | +d = [2015, 2016, 2017]; //comment 14 | -------------------------------------------------------------------------------- /tests/data/jpeg_image_meta_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,20 +1,20 @@ 2 | Image format: JPEG 3 | -File size: 662B 4 | +File size: 627B 5 | Height: 100 6 | Width: 100 7 | Orientation: Undefined 8 | Compression type: JPEG 9 | -Compression quality: 90 10 | +Compression quality: 95 11 | Colorspace: sRGB 12 | Channels: srgb 13 | Depth: 8 14 | Interlace mode: JPEG 15 | Rendering intent: Perceptual 16 | -X resolution: 88 17 | -Y resolution: 88 18 | +X resolution: 65 19 | +Y resolution: 65 20 | Resolution units: PixelsPerInch 21 | Transparency channel enabled: False 22 | Gamma: 0.454545 23 | Number of unique colors: 1 24 | -Comment: Comment #1 25 | +Comment: Comment #2 26 | EXIF data: 27 | -------------------------------------------------------------------------------- /tests/data/json_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | { 3 | - "filename": "test1" 4 | + "filename": "test2" 5 | } 6 | -------------------------------------------------------------------------------- /tests/data/macho_expected_diff_arch: -------------------------------------------------------------------------------- 1 | @@ -1,2 +1 @@ 2 | -i386 3 | x86_64 4 | 5 | -------------------------------------------------------------------------------- /tests/data/macho_expected_diff_disassembly: -------------------------------------------------------------------------------- 1 | @@ -1,18 +1,15 @@ 2 | (__TEXT,__text) section 3 | _main: 4 | -0000000100000f20 pushq %rbp 5 | -0000000100000f21 movq %rsp, %rbp 6 | -0000000100000f24 subq $0x10, %rsp 7 | -0000000100000f28 leaq 0x43(%rip), %rdi ## literal pool for: "%s %s\n" 8 | -0000000100000f2f leaq 0x43(%rip), %rsi ## literal pool for: "17:31:50" 9 | -0000000100000f36 leaq 0x45(%rip), %rdx ## literal pool for: "Wed Dec 2 17:31:49 2015" 10 | -0000000100000f3d movb $0x0, %al 11 | -0000000100000f3f callq 0x100000f52 ## symbol stub for: _printf 12 | -0000000100000f44 xorl %ecx, %ecx 13 | -0000000100000f46 movl %eax, -0x4(%rbp) 14 | -0000000100000f49 movl %ecx, %eax 15 | -0000000100000f4b addq $0x10, %rsp 16 | -0000000100000f4f popq %rbp 17 | -0000000100000f50 retq 18 | -(__DATA,__data) section 19 | -0000000100001018 04 00 00 00 20 | +0000000100000f40 pushq %rbp 21 | +0000000100000f41 movq %rsp, %rbp 22 | +0000000100000f44 subq $0x10, %rsp 23 | +0000000100000f48 leaq 0x3b(%rip), %rdi ## literal pool for: "%s\n" 24 | +0000000100000f4f leaq 0x38(%rip), %rsi ## literal pool for: "15:52:34" 25 | +0000000100000f56 movb $0x0, %al 26 | +0000000100000f58 callq 0x100000f6a ## symbol stub for: _printf 27 | +0000000100000f5d xorl %ecx, %ecx 28 | +0000000100000f5f movl %eax, -0x4(%rbp) 29 | +0000000100000f62 movl %ecx, %eax 30 | +0000000100000f64 addq $0x10, %rsp 31 | +0000000100000f68 popq %rbp 32 | +0000000100000f69 retq 33 | 34 | -------------------------------------------------------------------------------- /tests/data/macho_expected_diff_headers: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | Mach header 3 | magic cputype cpusubtype caps filetype ncmds sizeofcmds flags 4 | - 0xfeedfacf 16777223 3 0x80 2 16 1416 0x00200085 5 | + 0xfeedfacf 16777223 3 0x80 2 15 1280 0x00200085 6 | 7 | -------------------------------------------------------------------------------- /tests/data/macho_expected_diff_loadcommands: -------------------------------------------------------------------------------- 1 | @@ -1,2 +1 @@ 2 | - /usr/lib/libxml2.2.dylib (compatibility version 10.0.0, current version 10.9.0) 3 | /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1225.1.1) 4 | 5 | -------------------------------------------------------------------------------- /tests/data/mo_charsets_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,17 +1,17 @@ 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: debbindiff\n" 5 | "POT-Creation-Date: 2015-06-24 12:42+0200\n" 6 | "PO-Revision-Date: 2015-06-24 14:57+0200\n" 7 | "Last-Translator: Someone \n" 8 | -"Language-Team: English \n" 9 | +"Language-Team: Français \n" 10 | "Language: en\n" 11 | "MIME-Version: 1.0\n" 12 | -"Content-Type: text/plain\n" 13 | +"Content-Type: text/plain; charset=iso8859-1\n" 14 | "Content-Transfer-Encoding: 8bit\n" 15 | 16 | msgid "Another string" 17 | -msgstr "Another string" 18 | +msgstr "Une chaine, là aussi" 19 | 20 | msgid "String" 21 | -msgstr "String" 22 | +msgstr "Chaine, là" 23 | -------------------------------------------------------------------------------- /tests/data/mo_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,14 +1,17 @@ 2 | msgid "" 3 | msgstr "" 4 | "Project-Id-Version: debbindiff\n" 5 | "POT-Creation-Date: 2015-06-24 12:42+0200\n" 6 | -"PO-Revision-Date: 2015-06-24 12:42+0200\n" 7 | +"PO-Revision-Date: 2015-06-24 14:57+0200\n" 8 | "Last-Translator: Someone \n" 9 | "Language-Team: English \n" 10 | "Language: en\n" 11 | "MIME-Version: 1.0\n" 12 | "Content-Type: text/plain; charset=UTF-8\n" 13 | "Content-Transfer-Encoding: 8bit\n" 14 | 15 | +msgid "Another string" 16 | +msgstr "Another string" 17 | + 18 | msgid "String" 19 | msgstr "String" 20 | -------------------------------------------------------------------------------- /tests/data/mozzip_zipinfo_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,8 +1,8 @@ 2 | -Zip file size: 409 bytes, number of entries: 1 3 | -warning [test1.mozzip]: 329 extra bytes at beginning or within zipfile 4 | +Zip file size: 552 bytes, number of entries: 1 5 | +warning [test2.mozzip]: 472 extra bytes at beginning or within zipfile 6 | (attempting to process anyway) 7 | -error [test1.mozzip]: reported length of central directory is 8 | - -329 bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1 9 | +error [test2.mozzip]: reported length of central directory is 10 | + -472 bytes too long (Atari STZip zipfile? J.H.Holm ZIPSPLIT 1.1 11 | zipfile?). Compensating... 12 | --rw-r--r-- 2.0 unx 446 b- defX 10-Jan-01 00:00 dir/text 13 | -1 file, 446 bytes uncompressed, 269 bytes compressed: 39.7% 14 | +-rw-r--r-- 2.0 unx 671 b- defX 10-Jan-01 00:00 dir/text 15 | +1 file, 671 bytes uncompressed, 412 bytes compressed: 38.6% 16 | -------------------------------------------------------------------------------- /tests/data/openssh_pub_key_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -1024 SHA256:v/O+0ETvi2H5TGRXky1RhQ1/WFwLlPpxch5E2Mrj6FM Test1 (DSA) 3 | +4096 SHA256:9dH1CMkA6DSfPWU7vNwdPKS5/ppN4LMdvHTP60l7aSA Test2 (RSA) 4 | -------------------------------------------------------------------------------- /tests/data/order1.diff: -------------------------------------------------------------------------------- 1 | @@ -1,4 +1,4 @@ 2 | { 3 | - "hello": 42, 4 | - "world": 43 5 | + "world": 43, 6 | + "hello": 42 7 | } 8 | -------------------------------------------------------------------------------- /tests/data/order1a.json: -------------------------------------------------------------------------------- 1 | { "hello": 42, "world": 43 } 2 | -------------------------------------------------------------------------------- /tests/data/order1b.json: -------------------------------------------------------------------------------- 1 | { "world": 43, "hello": 42 } 2 | -------------------------------------------------------------------------------- /tests/data/output.colored.txt: -------------------------------------------------------------------------------- 1 | --- test1.tar 2 | +++ test2.tar 3 | ├── file list 4 | │ @@ -1,4 +1,4 @@ 5 | │ -drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/ 6 | │ --rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text 7 | │ -crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null 8 | │ -lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken 9 | │ +drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/ 10 | │ +-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text 11 | │ +crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null 12 | │ +lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken 13 | ├── dir/text 14 | │ @@ -1,6 +1,12 @@ 15 | │ +A common form of lorem ipsum reads: 16 | │ + 17 | │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 18 | │ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 19 | │ nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 20 | │ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 21 | │ fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 22 | │ culpa qui officia deserunt mollit anim id est laborum. 23 | │ + 24 | │ +"Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 25 | │ +bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 26 | │ +The Purposes of Good and Evil). 27 | ├── dir/link 28 | │┄ symlink 29 | │ @@ -1 +1 @@ 30 | │ -destination: broken 31 | │ +destination: really-broken 32 | -------------------------------------------------------------------------------- /tests/data/output.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [], 3 | "differences": [ 4 | { 5 | "comments": [], 6 | "differences": [ 7 | { 8 | "comments": [], 9 | "differences": [ 10 | { 11 | "comments": [ 12 | "symlink" 13 | ], 14 | "differences": [], 15 | "source1": "dir/link", 16 | "source2": "dir/link", 17 | "unified_diff": "@@ -1 +1 @@\n-destination: broken\n+destination: really-broken\n" 18 | } 19 | ], 20 | "source1": "dir/text", 21 | "source2": "dir/text", 22 | "unified_diff": "@@ -1,6 +1,12 @@\n+A common form of lorem ipsum reads:\n+\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor\n incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis\n nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\n Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu\n fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in\n culpa qui officia deserunt mollit anim id est laborum.\n+\n+\"Lorem ipsum\" text is derived from sections 1.10.32--3 of Cicero's De finibus\n+bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About]\n+The Purposes of Good and Evil).\n" 23 | } 24 | ], 25 | "source1": "file list", 26 | "source2": "file list", 27 | "unified_diff": "@@ -1,4 +1,4 @@\n-drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/\n--rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text\n-crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null\n-lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken\n+drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/\n+-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text\n+crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null\n+lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken\n" 28 | } 29 | ], 30 | "source1": "test1.tar", 31 | "source2": "test2.tar", 32 | "unified_diff": null 33 | } 34 | -------------------------------------------------------------------------------- /tests/data/output.md: -------------------------------------------------------------------------------- 1 | # Comparing test1.tar & test2.tar 2 | 3 | ## file list 4 | 5 | @@ -1,4 +1,4 @@ 6 | -drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/ 7 | --rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text 8 | -crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null 9 | -lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken 10 | +drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/ 11 | +-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text 12 | +crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null 13 | +lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken 14 | 15 | ## dir/text 16 | 17 | @@ -1,6 +1,12 @@ 18 | +A common form of lorem ipsum reads: 19 | + 20 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 21 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 22 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 23 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 24 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 25 | culpa qui officia deserunt mollit anim id est laborum. 26 | + 27 | +"Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 28 | +bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 29 | +The Purposes of Good and Evil). 30 | 31 | ## dir/link 32 | 33 | symlink 34 | 35 | @@ -1 +1 @@ 36 | -destination: broken 37 | +destination: really-broken 38 | 39 | -------------------------------------------------------------------------------- /tests/data/output.rst: -------------------------------------------------------------------------------- 1 | =============================== 2 | Comparing test1.tar & test2.tar 3 | =============================== 4 | 5 | --------- 6 | file list 7 | --------- 8 | 9 | :: 10 | 11 | @@ -1,4 +1,4 @@ 12 | -drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/ 13 | --rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text 14 | -crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null 15 | -lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken 16 | +drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/ 17 | +-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text 18 | +crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null 19 | +lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken 20 | 21 | -------- 22 | dir/text 23 | -------- 24 | 25 | :: 26 | 27 | @@ -1,6 +1,12 @@ 28 | +A common form of lorem ipsum reads: 29 | + 30 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 31 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 32 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 33 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 34 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 35 | culpa qui officia deserunt mollit anim id est laborum. 36 | + 37 | +"Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 38 | +bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 39 | +The Purposes of Good and Evil). 40 | 41 | -------- 42 | dir/link 43 | -------- 44 | 45 | 46 | symlink 47 | :: 48 | 49 | @@ -1 +1 @@ 50 | -destination: broken 51 | +destination: really-broken 52 | 53 | -------------------------------------------------------------------------------- /tests/data/output.txt: -------------------------------------------------------------------------------- 1 | --- test1.tar 2 | +++ test2.tar 3 | ├── file list 4 | │ @@ -1,4 +1,4 @@ 5 | │ -drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/ 6 | │ --rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text 7 | │ -crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null 8 | │ -lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken 9 | │ +drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/ 10 | │ +-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text 11 | │ +crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null 12 | │ +lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken 13 | ├── dir/text 14 | │ @@ -1,6 +1,12 @@ 15 | │ +A common form of lorem ipsum reads: 16 | │ + 17 | │ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 18 | │ incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 19 | │ nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 20 | │ Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 21 | │ fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 22 | │ culpa qui officia deserunt mollit anim id est laborum. 23 | │ + 24 | │ +"Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 25 | │ +bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 26 | │ +The Purposes of Good and Evil). 27 | ├── dir/link 28 | │┄ symlink 29 | │ @@ -1 +1 @@ 30 | │ -destination: broken 31 | │ +destination: really-broken 32 | -------------------------------------------------------------------------------- /tests/data/pdf_internal_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -11,23 +11,23 @@ 2 | /Kids [3 0 R] 3 | /Type /Pages 4 | /Count 1 5 | >> 6 | endobj 7 | 4 0 obj 8 | << 9 | -/Length 85 10 | +/Length 109 11 | >> 12 | stream 13 | q 14 | 15 | BT 16 | 36.0 747.384 Td 17 | /F1.0 12 Tf 18 | -[<48656c6c6f2057> 30 <6f72> -15 <6c6421>] TJ 19 | +[<48656c6c6f20536963> 20 <6b205361642057> 30 <6f72> -15 <6c6421>] TJ 20 | ET 21 | 22 | Q 23 | 24 | endstream 25 | endobj 26 | 3 0 obj 27 | @@ -61,21 +61,21 @@ 28 | /Producer 29 | >> 30 | endobj xref 31 | 0 7 32 | 0000000000 65535 f 33 | 0000000015 00000 n 34 | 0000000066 00000 n 35 | -0000000263 00000 n 36 | +0000000288 00000 n 37 | 0000000125 00000 n 38 | -0000000462 00000 n 39 | -0000000561 00000 n 40 | +0000000487 00000 n 41 | +0000000586 00000 n 42 | trailer 43 | 44 | << 45 | /Info 6 0 R 46 | /Root 1 0 R 47 | /Size 7 48 | >> 49 | startxref 50 | -656 51 | +681 52 | %%EOF 53 | -------------------------------------------------------------------------------- /tests/data/pdf_text_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,3 +1,3 @@ 2 | -Hello World! 3 | +Hello Sick Sad World! 4 | 5 | 6 | -------------------------------------------------------------------------------- /tests/data/pe_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,12 +1,12 @@ 2 | 3 | COFF Header: 4 | Machine: 0x014c 5 | Sections: 0x0003 6 | - Time stamp: 0x55a2d5bb 7 | + Time stamp: 0x55a2d5bd 8 | Pointer to Symbol Table: 0x00000000 9 | Symbol Count: 0x00000000 10 | Optional Header Size: 0x00e0 11 | Characteristics: 0x0102 12 | 13 | PE Header: 14 | Magic (0x010b): 0x010b 15 | -------------------------------------------------------------------------------- /tests/data/png_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,8 +1,8 @@ 2 | #SNG: from stdin 3 | IHDR { 4 | width: 1; height: 1; bitdepth: 8; 5 | using color; 6 | } 7 | IMAGE { 8 | - pixels hex ffffff ; 9 | + pixels base64 777; 10 | } 11 | -------------------------------------------------------------------------------- /tests/data/ppu_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -15,15 +15,15 @@ 2 | Definitions stored : 121 3 | Symbols stored : 398 4 | 5 | Interface section 6 | ------------------ 7 | Module Name: CastleGenericLists 8 | 9 | -Source file 1 : castlegenericlists.pas 2016/02/17 15:03:46 10 | +Source file 1 : castlegenericlists.pas 2016/02/17 15:04:53 11 | Uses unit: System (Crc: 09C1FD4E, IntfcCrc: 3A093E2F, IndCrc: FEDD6E0A) 12 | Uses unit: objpas (Crc: 663BC437, IntfcCrc: CA7886A2, IndCrc: 64D020AC) 13 | Uses unit: fgl (Crc: C38E0A5A, IntfcCrc: 470D2834, IndCrc: 0764D076) 14 | Link unit object file: castlegenericlists.o (static ) 15 | DerefMapsize: 2 16 | DerefMap[0] = FGL 17 | DerefMap[1] = SYSTEM 18 | -------------------------------------------------------------------------------- /tests/data/ps_text_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,5 +1,5 @@ 2 | 3 | 4 | -Today's date: February 28, 2016 5 | +Today's date: February 27, 2016 6 | 7 | 1 8 | -------------------------------------------------------------------------------- /tests/data/rlib_armap_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,10 +1,10 @@ 2 | 3 | Archive index: 4 | -__rust_allocate in alloc_system-d16b8f0e.0.o 5 | +__rust_all0cate in alloc_system-d16b8f0e.0.o 6 | __rust_deallocate in alloc_system-d16b8f0e.0.o 7 | __rust_reallocate in alloc_system-d16b8f0e.0.o 8 | __rust_reallocate_inplace in alloc_system-d16b8f0e.0.o 9 | __rust_usable_size in alloc_system-d16b8f0e.0.o 10 | 11 | alloc_system-d16b8f0e.0.o: 12 | 0000000000000000 T __rust_allocate 13 | -------------------------------------------------------------------------------- /tests/data/rlib_elf_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -6,15 +6,15 @@ 2 | 0000000000000000 <__rust_reallocate>: 3 | __rust_reallocate(): 4 | 0: 41 57 push %r15 5 | 2: 41 56 push %r14 6 | 4: 41 54 push %r12 7 | 6: 53 push %rbx 8 | 7: 50 push %rax 9 | - 8: 48 89 d3 mov %rdx,%rbx 10 | + 8: 48 89 d1 mov %rdx,%rcx 11 | b: 49 89 f7 mov %rsi,%r15 12 | e: 49 89 fe mov %rdi,%r14 13 | 11: 48 83 f9 10 cmp $0x10,%rcx 14 | 15: 77 16 ja 2d <__rust_reallocate+0x2d> 15 | 17: 4c 89 f7 mov %r14,%rdi 16 | 1a: 48 89 de mov %rbx,%rsi 17 | 1d: 48 83 c4 08 add $0x8,%rsp 18 | -------------------------------------------------------------------------------- /tests/data/rlib_llvm_dis_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -41,32 +41,32 @@ 2 | entry-block: 3 | %out.i.i = alloca i8*, align 8 4 | %4 = icmp ult i64 %3, 17 5 | br i1 %4, label %then-block-195-.i, label %_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i 6 | 7 | then-block-195-.i: ; preds = %entry-block 8 | %5 = tail call i8* @realloc(i8* %0, i64 %2) #3 9 | - br label %_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit 10 | + br label %_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit 11 | 12 | _ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i: ; preds = %entry-block 13 | %6 = bitcast i8** %out.i.i to i8* 14 | call void @llvm.lifetime.start(i64 8, i8* %6) #3 15 | store i8* null, i8** %out.i.i, align 8 16 | %7 = call i32 @posix_memalign(i8** nonnull %out.i.i, i64 %3, i64 %2) #3 17 | %8 = icmp eq i32 %7, 0 18 | %9 = load i8*, i8** %out.i.i, align 8 19 | %sret_slot.0.i.i = select i1 %8, i8* %9, i8* null 20 | call void @llvm.lifetime.end(i64 8, i8* %6) #3 21 | %10 = icmp ule i64 %2, %1 22 | %11 = select i1 %10, i64 %2, i64 %1 23 | call void @llvm.memmove.p0i8.p0i8.i64(i8* %sret_slot.0.i.i, i8* %0, i64 %11, i32 1, i1 false) #3 24 | call void @free(i8* %0) #3 25 | - br label %_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit 26 | + br label %_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit 27 | 28 | -_ZN12alloc_system3imp10reallocate17h4a0811c9ec086854E.exit: ; preds = %_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i, %then-block-195-.i 29 | +_ZN12alloc_system3imp10reallocate1l44a0811c9ec086854E.exit: ; preds = %_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i, %then-block-195-.i 30 | %sret_slot.0.i = phi i8* [ %5, %then-block-195-.i ], [ %sret_slot.0.i.i, %_ZN12alloc_system3imp8allocate17h8ba7625cc4a820e8E.exit.i ] 31 | ret i8* %sret_slot.0.i 32 | } 33 | 34 | ; Function Attrs: nounwind readnone uwtable 35 | define i64 @__rust_reallocate_inplace(i8* nocapture readnone, i64, i64, i64) unnamed_addr #1 { 36 | entry-block: 37 | -------------------------------------------------------------------------------- /tests/data/rpm_listing_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | --rw-r--r-- 1 0 0 446 2015-06-24 17:55:18.000000 ./dir/text 3 | +-rw-r--r-- 1 0 0 671 2015-06-24 17:55:59.000000 ./dir/text 4 | -------------------------------------------------------------------------------- /tests/data/sqlite3_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,5 +1,5 @@ 2 | PRAGMA foreign_keys=OFF; 3 | BEGIN TRANSACTION; 4 | CREATE TABLE test (value val); 5 | -INSERT INTO "test" VALUES(1); 6 | +INSERT INTO "test" VALUES(2); 7 | COMMIT; 8 | -------------------------------------------------------------------------------- /tests/data/squashfs_superblock_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,10 +1,10 @@ 2 | Found a valid SQUASHFS 4:0 superblock 3 | -Creation or last append time Wed Jun 24 14:49:50 2015 4 | -Filesystem size 0.55 Kbytes (0.00 Mbytes) 5 | +Creation or last append time Wed Jun 24 14:50:09 2015 6 | +Filesystem size 0.70 Kbytes (0.00 Mbytes) 7 | Compression gzip 8 | Block size 131072 9 | Filesystem is exportable via NFS 10 | Inodes are compressed 11 | Data is compressed 12 | Fragments are compressed 13 | Always-use-fragments option is not specified 14 | -------------------------------------------------------------------------------- /tests/data/symlink_expected_destination_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -destination: /a 3 | +destination: /b 4 | -------------------------------------------------------------------------------- /tests/data/symlink_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -destination: broken 3 | +destination: really-broken 4 | -------------------------------------------------------------------------------- /tests/data/tar_listing_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,4 +1,4 @@ 2 | -drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/ 3 | --rw-r--r-- 0 lunar (1000) lunar (1000) 446 2015-06-29 15:49:09.000000 dir/text 4 | -crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:09.000000 dir/null 5 | -lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:09.000000 dir/link -> broken 6 | +drwxr-xr-x 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/ 7 | +-rw-r--r-- 0 lunar (1000) lunar (1000) 671 2015-06-29 15:49:41.000000 dir/text 8 | +crw-r--r-- 0 root (0) root (0) 1, 3 2015-06-29 15:49:41.000000 dir/null 9 | +lrwxrwxrwx 0 lunar (1000) lunar (1000) 0 2015-06-29 15:49:41.000000 dir/link -> really-broken 10 | -------------------------------------------------------------------------------- /tests/data/test1.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.a -------------------------------------------------------------------------------- /tests/data/test1.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.apk -------------------------------------------------------------------------------- /tests/data/test1.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.bz2 -------------------------------------------------------------------------------- /tests/data/test1.changes: -------------------------------------------------------------------------------- 1 | Format: 1.8 2 | Date: Sat, 04 Apr 2015 18:30:48 +0200 3 | Source: test 4 | Binary: test 5 | Architecture: source all 6 | Version: 1 7 | Distribution: unstable 8 | Urgency: low 9 | Maintainer: Someone Else 10 | Changed-By: Someone Else 11 | Description: 12 | test - just a test package 13 | Changes: 14 | test (1) unstable; urgency=low 15 | . 16 | * Test package. 17 | Checksums-Sha1: 18 | b21eeec5004853c4955d5b856a6546068c2d7dc9 2262 test_1_all.deb 19 | e1cafb5f8db51f4ec477807d105b1e3cccf9a767 3780 test_1.buildinfo 20 | Checksums-Sha256: 21 | d2b2ea8b9cf8ef645a328cdb882586ee465e141fc66a2dbe1ad29b29ac1e7920 2262 test_1_all.deb 22 | 167d989223978a45a69af30dcd488baa00aec2045b66d0f74d7f03b08fd22365 3780 test_1.buildinfo 23 | Files: 24 | 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb 25 | 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_1.buildinfo 26 | -------------------------------------------------------------------------------- /tests/data/test1.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.cpio -------------------------------------------------------------------------------- /tests/data/test1.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.deb -------------------------------------------------------------------------------- /tests/data/test1.debsrc.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.debsrc.tar.gz -------------------------------------------------------------------------------- /tests/data/test1.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.dex -------------------------------------------------------------------------------- /tests/data/test1.dsc: -------------------------------------------------------------------------------- 1 | Format: 1.0 2 | Source: test 3 | Binary: test 4 | Architecture: all 5 | Version: 1 6 | Maintainer: Someone Else 7 | Standards-Version: 3.9.6 8 | Build-Depends: debhelper (>= 7) 9 | Package-List: 10 | test deb misc optional 11 | Checksums-Sha1: 12 | 2f66c0cf9788240c8c3321193d4a628157748445 2086 test_1.tar.gz 13 | Checksums-Sha256: 14 | 1066cb6c1fca0423eb449b7aac27d5a477c55f4262ab8af438100a6d2ee039b4 2086 test_1.tar.gz 15 | Files: 16 | 42c53394ba8bb4d92aab8d40d33507d7 2086 test_1.tar.gz 17 | -------------------------------------------------------------------------------- /tests/data/test1.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.epub -------------------------------------------------------------------------------- /tests/data/test1.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.exe -------------------------------------------------------------------------------- /tests/data/test1.ext4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.ext4 -------------------------------------------------------------------------------- /tests/data/test1.git-index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.git-index -------------------------------------------------------------------------------- /tests/data/test1.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.gz -------------------------------------------------------------------------------- /tests/data/test1.hi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.hi -------------------------------------------------------------------------------- /tests/data/test1.icc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.icc -------------------------------------------------------------------------------- /tests/data/test1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.ico -------------------------------------------------------------------------------- /tests/data/test1.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.iso -------------------------------------------------------------------------------- /tests/data/test1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.jpg -------------------------------------------------------------------------------- /tests/data/test1.js: -------------------------------------------------------------------------------- 1 | function test(str) { alert(str);prompt(str,"TEST1")}x=1;y=2;z=/.+/;d=[2015,2016]; //comment 2 | -------------------------------------------------------------------------------- /tests/data/test1.json: -------------------------------------------------------------------------------- 1 | {"filename": "test1"} 2 | -------------------------------------------------------------------------------- /tests/data/test1.macho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.macho -------------------------------------------------------------------------------- /tests/data/test1.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.mo -------------------------------------------------------------------------------- /tests/data/test1.mozzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.mozzip -------------------------------------------------------------------------------- /tests/data/test1.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.o -------------------------------------------------------------------------------- /tests/data/test1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.pdf -------------------------------------------------------------------------------- /tests/data/test1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.png -------------------------------------------------------------------------------- /tests/data/test1.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.ppu -------------------------------------------------------------------------------- /tests/data/test1.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.rlib -------------------------------------------------------------------------------- /tests/data/test1.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.rpm -------------------------------------------------------------------------------- /tests/data/test1.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.sqlite3 -------------------------------------------------------------------------------- /tests/data/test1.squashfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.squashfs -------------------------------------------------------------------------------- /tests/data/test1.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.xz -------------------------------------------------------------------------------- /tests/data/test1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1.zip -------------------------------------------------------------------------------- /tests/data/test1_meta.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1_meta.ico -------------------------------------------------------------------------------- /tests/data/test1_meta.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test1_meta.jpg -------------------------------------------------------------------------------- /tests/data/test2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.a -------------------------------------------------------------------------------- /tests/data/test2.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.apk -------------------------------------------------------------------------------- /tests/data/test2.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.bz2 -------------------------------------------------------------------------------- /tests/data/test2.changes: -------------------------------------------------------------------------------- 1 | Format: 1.8 2 | Date: Sat, 04 Apr 2015 18:30:48 +0200 3 | Source: test 4 | Binary: test 5 | Architecture: source all 6 | Version: 1 7 | Distribution: unstable 8 | Urgency: low 9 | Maintainer: Someone Else 10 | Changed-By: Someone Else 11 | Description: 12 | test - just a simple test package 13 | Changes: 14 | test (1) unstable; urgency=low 15 | . 16 | * Test package. 17 | Checksums-Sha1: 18 | 70982664db2015334bff6441b429d7e3c58dbecb 2388 test_1_all.deb 19 | 91d2cc6aadddb4a24b0c2f8f24d558ce0e07f9cd 3765 test_2.buildinfo 20 | Checksums-Sha256: 21 | 2f2e45ee3a5fdacd9b30133ec728121588bf9b97af3b947b3882b2b28a0555da 2388 test_1_all.deb 22 | 917d8b5c3ade2bde26fe2b7476481537f32a0c07f10e5e44c0ca7a02c8bfa9d8 3765 test_2.buildinfo 23 | Files: 24 | d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb 25 | 9972d7c394228311ba92cbcbfe2d6cd9 3765 web optional test_2.buildinfo 26 | -------------------------------------------------------------------------------- /tests/data/test2.cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.cpio -------------------------------------------------------------------------------- /tests/data/test2.deb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.deb -------------------------------------------------------------------------------- /tests/data/test2.debsrc.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.debsrc.tar.gz -------------------------------------------------------------------------------- /tests/data/test2.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.dex -------------------------------------------------------------------------------- /tests/data/test2.dsc: -------------------------------------------------------------------------------- 1 | Format: 1.0 2 | Source: test 3 | Binary: test 4 | Architecture: all 5 | Version: 1 6 | Maintainer: Someone Else 7 | Standards-Version: 3.9.6 8 | Build-Depends: debhelper (>= 7) 9 | Package-List: 10 | test deb misc optional 11 | Checksums-Sha1: 12 | 7453b45105d06be451cbc472c2fa1df13a60eb27 2193 test_1.tar.gz 13 | Checksums-Sha256: 14 | ff86b4d705489ee0f2825a935100f9a0981b6c8c4c0eb5e19436c8599da14324 2193 test_1.tar.gz 15 | Files: 16 | b75f3bae96326e1c518dba429a81f91c 2193 test_1.tar.gz 17 | -------------------------------------------------------------------------------- /tests/data/test2.epub: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.epub -------------------------------------------------------------------------------- /tests/data/test2.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.exe -------------------------------------------------------------------------------- /tests/data/test2.ext4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.ext4 -------------------------------------------------------------------------------- /tests/data/test2.git-index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.git-index -------------------------------------------------------------------------------- /tests/data/test2.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.gz -------------------------------------------------------------------------------- /tests/data/test2.hi: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.hi -------------------------------------------------------------------------------- /tests/data/test2.icc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.icc -------------------------------------------------------------------------------- /tests/data/test2.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.ico -------------------------------------------------------------------------------- /tests/data/test2.iso: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.iso -------------------------------------------------------------------------------- /tests/data/test2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.jpg -------------------------------------------------------------------------------- /tests/data/test2.js: -------------------------------------------------------------------------------- 1 | function test(str) { alert(str);prompt(str,"TEST2")}x=1;y=3;z=/.*/;d=[2015,2016,2017]; //comment 2 | -------------------------------------------------------------------------------- /tests/data/test2.json: -------------------------------------------------------------------------------- 1 | {"filename": "test2"} 2 | -------------------------------------------------------------------------------- /tests/data/test2.macho: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.macho -------------------------------------------------------------------------------- /tests/data/test2.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.mo -------------------------------------------------------------------------------- /tests/data/test2.mozzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.mozzip -------------------------------------------------------------------------------- /tests/data/test2.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.o -------------------------------------------------------------------------------- /tests/data/test2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.pdf -------------------------------------------------------------------------------- /tests/data/test2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.png -------------------------------------------------------------------------------- /tests/data/test2.ppu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.ppu -------------------------------------------------------------------------------- /tests/data/test2.rlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.rlib -------------------------------------------------------------------------------- /tests/data/test2.rpm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.rpm -------------------------------------------------------------------------------- /tests/data/test2.sqlite3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.sqlite3 -------------------------------------------------------------------------------- /tests/data/test2.squashfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.squashfs -------------------------------------------------------------------------------- /tests/data/test2.xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.xz -------------------------------------------------------------------------------- /tests/data/test2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2.zip -------------------------------------------------------------------------------- /tests/data/test2_meta.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2_meta.ico -------------------------------------------------------------------------------- /tests/data/test2_meta.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test2_meta.jpg -------------------------------------------------------------------------------- /tests/data/test3.changes: -------------------------------------------------------------------------------- 1 | Format: 1.8 2 | Date: Sat, 04 Apr 2015 18:30:48 +0200 3 | Source: test 4 | Binary: test 5 | Architecture: source all 6 | Version: 1 7 | Distribution: unstable 8 | Urgency: low 9 | Maintainer: Someone Else 10 | Changed-By: Someone Else 11 | Description: 12 | test - just a test package 13 | Changes: 14 | test (1) unstable; urgency=low 15 | . 16 | * Test package. 17 | Checksums-Sha1: 18 | b21eeec5004853c4955d5b856a6546068c2d7dc9 2262 test_1_all.deb 19 | 91d2cc6aadddb4a24b0c2f8f24d558ce0e07f9cd 3765 test_2.buildinfo 20 | Checksums-Sha256: 21 | d2b2ea8b9cf8ef645a328cdb882586ee465e141fc66a2dbe1ad29b29ac1e7920 2262 test_1_all.deb 22 | 917d8b5c3ade2bde26fe2b7476481537f32a0c07f10e5e44c0ca7a02c8bfa9d8 3765 test_2.buildinfo 23 | Files: 24 | 660ad4713e5d8271df2e7e86bf246dc0 2262 devel optional test_1_all.deb 25 | 9972d7c394228311ba92cbcbfe2d6cd9 3765 web optional test_2.buildinfo 26 | -------------------------------------------------------------------------------- /tests/data/test4.changes: -------------------------------------------------------------------------------- 1 | Format: 1.8 2 | Date: Sat, 04 Apr 2015 18:30:48 +0200 3 | Source: test 4 | Binary: test 5 | Architecture: source all 6 | Version: 1 7 | Distribution: unstable 8 | Urgency: low 9 | Maintainer: Someone Else 10 | Changed-By: Someone Else 11 | Description: 12 | test - just a test package 13 | Changes: 14 | test (1) unstable; urgency=low 15 | . 16 | * Test package. 17 | Checksums-Sha1: 18 | 70982664db2015334bff6441b429d7e3c58dbecb 2388 test_1_all.deb 19 | e1cafb5f8db51f4ec477807d105b1e3cccf9a767 3780 test_2.buildinfo 20 | Checksums-Sha256: 21 | 2f2e45ee3a5fdacd9b30133ec728121588bf9b97af3b947b3882b2b28a0555da 2388 test_1_all.deb 22 | 167d989223978a45a69af30dcd488baa00aec2045b66d0f74d7f03b08fd22365 3780 test_2.buildinfo 23 | Files: 24 | d323c454462407fe3bfde31a74b23eba 2388 devel optional test_1_all.deb 25 | 40756b7e8aae2c1fcbcac099670b6db8 3780 web optional test_2.buildinfo 26 | -------------------------------------------------------------------------------- /tests/data/test_directory_device_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -type: directory 3 | +type: device 4 | -------------------------------------------------------------------------------- /tests/data/test_directory_file_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -type: directory 3 | +type: file 4 | -------------------------------------------------------------------------------- /tests/data/test_directory_symlink_diff: -------------------------------------------------------------------------------- 1 | @@ -1 +1 @@ 2 | -type: directory 3 | +type: symlink 4 | -------------------------------------------------------------------------------- /tests/data/test_invalid.json: -------------------------------------------------------------------------------- 1 | {"filename": 2 | -------------------------------------------------------------------------------- /tests/data/test_iso8859-1.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test_iso8859-1.mo -------------------------------------------------------------------------------- /tests/data/test_no_charset.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/test_no_charset.mo -------------------------------------------------------------------------------- /tests/data/test_openssh_pub_key1.pub: -------------------------------------------------------------------------------- 1 | ssh-dss AAAAB3NzaC1kc3MAAACBAIa8YajID9g38jwQm8sNBGoGkkwIOv6sQ8k+Bcq8oPXPy1FRXWcra6Kd3iKqApIzLuZUvoYO/f3G2K4lue5yrv72rgwANWmyL4dHVXgcsjwvWwjOl6o4xWTPFspkdNcAAMcZfzG0+w1AOkQxhwMsnK380m3J9a3VOWugUiU4fV1jAAAAFQDzkrIZuJoxlxes564ltb2Vn3hnpQAAAIBHr6uzpiSeSkWLuItB00hHx1RHtBns0zaheNFTTUMGftxtfBU2eBLqObcTlqHJZ3UUY3/YAvD6Ux/uLSgUzEe7JaqvHcgML3K5V4HWIwE0ARRIwzrfU4cAErJObmZZ/OXbXNNRmW2IJgQJI52x4gVuSt0EEuctzASOOvyPA8IekAAAAIA7xe4o0o/ZwUqfWKR9K4QrbPPa6/D4ruFVhMcRJEE/A1LMY1Xo4nVSRU5bxzvMmJPBZvsbR5NEE3CgESqYxp5IPzK8LLyxcf8YxhdHFDYqFL1TbavwaDqtj6/9a/e7+bd8mMYe7zXJUdKWa/Uf+Xm6WRt3HgdLiCEsS2OlpvS2KA== Test1 2 | -------------------------------------------------------------------------------- /tests/data/test_openssh_pub_key2.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDDfey/WO9EfGVjcYaBkuSfFYRSu+qSHCfZ55W8XMX/oc583USAofVD+vdq3ekG8J3Z9sKeIJbXzbxOsi1TrDzj4acCj8Sfp3PyMYr7bHkc0Jkp9p1DxY33+SS2zuJOQUwNU763HAJ3jdA3D2Y9EzXTwhuB2zuVEPNU1HGeAEldbdoa7kycPt/3UklBe6RzoFVYaODY1un9pBUVOZQuQomBrsbGKTeLk5w4b5pt/Sgd7aSpEPEyY/mB62Ac9ZXpPpwK/wIeo36kbfWyjYeM7YkyKoej6JHgG8S1YS+zZQGi9XDSWdIs7l31McIJO1XA1udHagKD114a3v4OMeH+Gn8zTkIyQ4gZovP9vmtoWGrZdq3yWjMZS68/ST+oEk6Wvh/LC7+D5+XR8ENViTE03KaoG+40ZwL2XSQ7WmVUfIS75Q4dOnhgnwLpl3mGlZQ97czlJ/pfQDlilQrUEmM2Nm2/YSCaglF2E6ZVFAH4tJh4YlXcRJhsls8W1e9Y5ZB2guRP8y6Tc9lSWPou+6fex5jqPiscSev3iS44AsNPqU6WTo7PIp8snnl+KtbUX01f5Luyvn0/BVesdtKpWf/37AEDz5LvzNxLHxupEKG6zR0vh7jZXj0KFrTmlu3CQ82qCmv5rnqpxy6EKGkWKDfgOSuRJE6S/Zl7sSmrfYSBo5/mgw== Test2 2 | -------------------------------------------------------------------------------- /tests/data/text_ascii1: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 2 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 3 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 4 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 5 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 6 | culpa qui officia deserunt mollit anim id est laborum. 7 | -------------------------------------------------------------------------------- /tests/data/text_ascii2: -------------------------------------------------------------------------------- 1 | A common form of lorem ipsum reads: 2 | 3 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 4 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 5 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 6 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 7 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 8 | culpa qui officia deserunt mollit anim id est laborum. 9 | 10 | "Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 11 | bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 12 | The Purposes of Good and Evil). 13 | -------------------------------------------------------------------------------- /tests/data/text_ascii_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,6 +1,12 @@ 2 | +A common form of lorem ipsum reads: 3 | + 4 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 5 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 6 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 7 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 8 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 9 | culpa qui officia deserunt mollit anim id est laborum. 10 | + 11 | +"Lorem ipsum" text is derived from sections 1.10.32--3 of Cicero's De finibus 12 | +bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 13 | +The Purposes of Good and Evil). 14 | -------------------------------------------------------------------------------- /tests/data/text_iso8859: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anthraxx/diffoscope/dcfffcbb46685081b883d43ae9e4400ffa43c94c/tests/data/text_iso8859 -------------------------------------------------------------------------------- /tests/data/text_iso8859_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -3,10 +3,10 @@ 2 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 3 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 4 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 5 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 6 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 7 | culpa qui officia deserunt mollit anim id est laborum. 8 | 9 | -«Lorem ipsum» text is derived from sections 1.10.32--3 of Cicero's De finibus 10 | +"Lorem ipsum" text is derived from sections 1.10.32–3 of Cicero's De finibus 11 | bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 12 | The Purposes of Good and Evil). 13 | -------------------------------------------------------------------------------- /tests/data/text_order1: -------------------------------------------------------------------------------- 1 | These 2 | lines 3 | follow 4 | in 5 | some 6 | order 7 | . 8 | -------------------------------------------------------------------------------- /tests/data/text_order2: -------------------------------------------------------------------------------- 1 | These 2 | some 3 | order 4 | follow 5 | in 6 | lines 7 | . 8 | -------------------------------------------------------------------------------- /tests/data/text_order_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,7 +1,7 @@ 2 | These 3 | -lines 4 | -follow 5 | -in 6 | some 7 | order 8 | +follow 9 | +in 10 | +lines 11 | . 12 | -------------------------------------------------------------------------------- /tests/data/text_unicode1: -------------------------------------------------------------------------------- 1 | A common form of lorem ipsum reads: 2 | 3 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 4 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 5 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 6 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 7 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 8 | culpa qui officia deserunt mollit anim id est laborum. 9 | 10 | "Lorem ipsum" text is derived from sections 1.10.32–3 of Cicero's De finibus 11 | bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 12 | The Purposes of Good and Evil). 13 | -------------------------------------------------------------------------------- /tests/data/text_unicode2: -------------------------------------------------------------------------------- 1 | A common form of lorem ipsum reads: 2 | 3 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 4 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 5 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 6 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 7 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 8 | culpa qui officia deserunt mollit anim id est laborum. 9 | 10 | “Lorem ipsum” text is derived from sections 1.10.32–3 of Cicero’s De finibus 11 | bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 12 | The Purposes of Good and Evil). 13 | -------------------------------------------------------------------------------- /tests/data/text_unicode_binary_fallback: -------------------------------------------------------------------------------- 1 | @@ -24,19 +24,20 @@ 2 | 00000170: 7572 2e20 4578 6365 7074 6575 7220 7369 ur. Excepteur si 3 | 00000180: 6e74 206f 6363 6165 6361 7420 6375 7069 nt occaecat cupi 4 | 00000190: 6461 7461 7420 6e6f 6e20 7072 6f69 6465 datat non proide 5 | 000001a0: 6e74 2c20 7375 6e74 2069 6e0a 6375 6c70 nt, sunt in.culp 6 | 000001b0: 6120 7175 6920 6f66 6669 6369 6120 6465 a qui officia de 7 | 000001c0: 7365 7275 6e74 206d 6f6c 6c69 7420 616e serunt mollit an 8 | 000001d0: 696d 2069 6420 6573 7420 6c61 626f 7275 im id est laboru 9 | -000001e0: 6d2e 0a0a 224c 6f72 656d 2069 7073 756d m..."Lorem ipsum 10 | -000001f0: 2220 7465 7874 2069 7320 6465 7269 7665 " text is derive 11 | -00000200: 6420 6672 6f6d 2073 6563 7469 6f6e 7320 d from sections 12 | -00000210: 312e 3130 2e33 32e2 8093 3320 6f66 2043 1.10.32...3 of C 13 | -00000220: 6963 6572 6f27 7320 4465 2066 696e 6962 icero's De finib 14 | -00000230: 7573 0a62 6f6e 6f72 756d 2065 7420 6d61 us.bonorum et ma 15 | -00000240: 6c6f 7275 6d20 284f 6e20 7468 6520 456e lorum (On the En 16 | -00000250: 6473 206f 6620 476f 6f64 7320 616e 6420 ds of Goods and 17 | -00000260: 4576 696c 732c 206f 7220 616c 7465 726e Evils, or altern 18 | -00000270: 6174 6976 656c 7920 5b41 626f 7574 5d0a atively [About]. 19 | -00000280: 5468 6520 5075 7270 6f73 6573 206f 6620 The Purposes of 20 | -00000290: 476f 6f64 2061 6e64 2045 7669 6c29 2e0a Good and Evil).. 21 | +000001e0: 6d2e 0a0a e280 9c4c 6f72 656d 2069 7073 m......Lorem ips 22 | +000001f0: 756d e280 9d20 7465 7874 2069 7320 6465 um... text is de 23 | +00000200: 7269 7665 6420 6672 6f6d 2073 6563 7469 rived from secti 24 | +00000210: 6f6e 7320 312e 3130 2e33 32e2 8093 3320 ons 1.10.32...3 25 | +00000220: 6f66 2043 6963 6572 6fe2 8099 7320 4465 of Cicero...s De 26 | +00000230: 2066 696e 6962 7573 0a62 6f6e 6f72 756d finibus.bonorum 27 | +00000240: 2065 7420 6d61 6c6f 7275 6d20 284f 6e20 et malorum (On 28 | +00000250: 7468 6520 456e 6473 206f 6620 476f 6f64 the Ends of Good 29 | +00000260: 7320 616e 6420 4576 696c 732c 206f 7220 s and Evils, or 30 | +00000270: 616c 7465 726e 6174 6976 656c 7920 5b41 alternatively [A 31 | +00000280: 626f 7574 5d0a 5468 6520 5075 7270 6f73 bout].The Purpos 32 | +00000290: 6573 206f 6620 476f 6f64 2061 6e64 2045 es of Good and E 33 | +000002a0: 7669 6c29 2e0a vil).. 34 | -------------------------------------------------------------------------------- /tests/data/text_unicode_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -3,10 +3,10 @@ 2 | Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor 3 | incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis 4 | nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. 5 | Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu 6 | fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in 7 | culpa qui officia deserunt mollit anim id est laborum. 8 | 9 | -"Lorem ipsum" text is derived from sections 1.10.32–3 of Cicero's De finibus 10 | +“Lorem ipsum” text is derived from sections 1.10.32–3 of Cicero’s De finibus 11 | bonorum et malorum (On the Ends of Goods and Evils, or alternatively [About] 12 | The Purposes of Good and Evil). 13 | -------------------------------------------------------------------------------- /tests/data/zip_zipinfo_expected_diff: -------------------------------------------------------------------------------- 1 | @@ -1,4 +1,4 @@ 2 | -Zip file size: 571 bytes, number of entries: 2 3 | +Zip file size: 714 bytes, number of entries: 2 4 | drwxr-xr-x 3.0 unx 0 bx stor 15-Jun-24 13:44 dir/ 5 | --rw-r--r-- 3.0 unx 446 tx defN 15-Jun-24 13:44 dir/text 6 | -2 files, 446 bytes uncompressed, 269 bytes compressed: 39.7% 7 | +-rw-r--r-- 3.0 unx 671 tx defN 15-Jun-24 13:45 dir/text 8 | +2 files, 671 bytes uncompressed, 412 bytes compressed: 38.6% 9 | -------------------------------------------------------------------------------- /tests/test_difference.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2015 Jérémy Bobbio 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import io 21 | import pytest 22 | 23 | from diffoscope.config import Config 24 | from diffoscope.difference import Difference 25 | 26 | 27 | def test_too_much_input_for_diff(monkeypatch): 28 | monkeypatch.setattr(Config(), 'max_diff_input_lines', 20) 29 | too_long_text_a = io.StringIO("a\n" * 21) 30 | too_long_text_b = io.StringIO("b\n" * 21) 31 | difference = Difference.from_text_readers(too_long_text_a, too_long_text_b, 'a', 'b') 32 | assert '[ Too much input for diff ' in difference.unified_diff 33 | 34 | def test_too_long_diff_block_lines(monkeypatch): 35 | monkeypatch.setattr(Config(), 'enforce_constraints', False) 36 | monkeypatch.setattr(Config(), 'max_diff_block_lines_saved', 10) 37 | too_long_text_a = io.StringIO("a\n" * 21) 38 | too_long_text_b = io.StringIO("b\n" * 21) 39 | difference = Difference.from_text_readers(too_long_text_a, too_long_text_b, 'a', 'b') 40 | assert '[ 11 lines removed ]' in difference.unified_diff 41 | 42 | def test_non_str_arguments_to_source1_source2(): 43 | for x in ( 44 | (None, 'str'), 45 | ('str', None), 46 | ): 47 | a = io.StringIO('a') 48 | b = io.StringIO('b') 49 | 50 | with pytest.raises(TypeError): 51 | Difference.from_text_readers(a, b, *x) 52 | -------------------------------------------------------------------------------- /tests/test_progress.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # diffoscope: in-depth comparison of files, archives, and directories 4 | # 5 | # Copyright © 2017 Chris Lamb 6 | # 7 | # diffoscope is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU General Public License as published by 9 | # the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # diffoscope is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU General Public License 18 | # along with diffoscope. If not, see . 19 | 20 | import os 21 | import sys 22 | import json 23 | import pytest 24 | 25 | from diffoscope.main import main 26 | from diffoscope.progress import ProgressManager, StatusFD 27 | 28 | from comparators.utils.tools import skip_unless_module_exists 29 | 30 | TEST_TAR1_PATH = os.path.join(os.path.dirname(__file__), 'data', 'test1.tar') 31 | TEST_TAR2_PATH = os.path.join(os.path.dirname(__file__), 'data', 'test2.tar') 32 | 33 | 34 | def run(capsys, *args): 35 | with pytest.raises(SystemExit) as exc: 36 | main(args) 37 | 38 | out, err = capsys.readouterr() 39 | 40 | return exc.value.code, out, err 41 | 42 | @skip_unless_module_exists('progressbar') 43 | def test_progress(capsys): 44 | ret, _, err = run(capsys, TEST_TAR1_PATH, TEST_TAR2_PATH, '--progress') 45 | 46 | assert ret == 1 47 | assert "ETA" in err 48 | 49 | def test_status_fd(capsys): 50 | ProgressManager().register(StatusFD(sys.stderr)) 51 | 52 | ret, _, err = run(capsys, TEST_TAR1_PATH, TEST_TAR2_PATH) 53 | 54 | assert ret == 1 55 | 56 | # Parse lines and ensure we emitted at least one line 57 | output = [json.loads(x) for x in err.splitlines()] 58 | assert output 59 | 60 | # Ensure each line is valid 61 | for x in output: 62 | assert 'msg' in x 63 | assert x['current'] <= x['total'] 64 | 65 | # Last line should mark us as "complete" 66 | assert output[-1]['current'] == output[-1]['total'] 67 | --------------------------------------------------------------------------------