diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/checkdiffs.py | 81 | ||||
-rw-r--r-- | tests/expected.py | 41 | ||||
-rw-r--r-- | tests/expected.txt | 140 | ||||
-rw-r--r-- | tests/myprofile.py | 5 | ||||
-rwxr-xr-x | tests/test_examples.py | 195 | ||||
-rw-r--r-- | tests/test_pdfstring.py | 6 | ||||
-rwxr-xr-x | tests/test_roundtrip.py | 132 |
7 files changed, 598 insertions, 2 deletions
diff --git a/tests/checkdiffs.py b/tests/checkdiffs.py new file mode 100755 index 0000000..4d11888 --- /dev/null +++ b/tests/checkdiffs.py @@ -0,0 +1,81 @@ +#! /usr/bin/env python2 + +import sys +import os +import subprocess +import hashlib + +import expected +import static_pdfs + +source_pdfs = static_pdfs.pdffiles[0] +source_pdfs = dict((os.path.basename(x), x) for x in source_pdfs) + +result_dir = expected.result_dir + +for subdir in sorted(os.listdir(result_dir)): + dstd = os.path.join(result_dir, subdir) + if not os.path.isdir(dstd): + continue + for pdffile in sorted(os.listdir(dstd)): + testname = '%s/%s' % (subdir, pdffile) + srcf = source_pdfs.get(pdffile) + dstf = os.path.join(dstd, pdffile) + if pdffile not in source_pdfs: + print('\n Skipping %s -- source not found' % testname) + continue + + with open(dstf, 'rb') as f: + data = f.read() + hash = hashlib.md5(data).hexdigest() + skipset = set((hash, 'skip', 'xfail', 'fail', '!' + hash)) + if expected.results[testname] & skipset: + print('\n Skipping %s -- marked done' % testname) + continue + if os.path.exists('foobar.pdf'): + os.remove('foobar.pdf') + builtdiff = False + while 1: + sys.stdout.write(''' + Test case %s + + c = compare using imagemagick and okular + f = display foobar.pdf (result from comparison) + o = display results with okular + a = display results with acrobat + + s = mark 'skip' and go to next PDF + g = mark as good and go to next PDF + b = mark as bad and go to next PDF + n = next pdf without marking + q = quit +--> ''' % testname) + sel = raw_input() + if sel == 'q': + raise SystemExit(0) + if sel == 'n': + break + if sel == 'c': + subprocess.call(('compare', '-verbose', srcf, dstf, + 'foobar.pdf')) + builtdiff = True + continue + if sel == 'f': + subprocess.call(('okular', 'foobar.pdf')) + continue + if sel == 'o': + subprocess.call(('okular', srcf, dstf)) + continue + if sel == 'a': + if builtdiff: + subprocess.call(('acroread', srcf, dstf, 'foobar.pdf')) + else: + subprocess.call(('acroread', srcf, dstf)) + continue + + if sel in 'sgb': + results = (hash if sel == 'g' else + ' skip' if sel == 's' else '!'+hash) + with open(expected.expectedf, 'a') as f: + f.write('%s %s\n' % (testname, results)) + break diff --git a/tests/expected.py b/tests/expected.py new file mode 100644 index 0000000..a65c989 --- /dev/null +++ b/tests/expected.py @@ -0,0 +1,41 @@ +# A part of pdfrw (https://github.com/pmaupin/pdfrw) +# Copyright (C) 2006-2015 Patrick Maupin, Austin, Texas +# MIT license -- See LICENSE.txt for details + +''' + Read expected.txt, which should be in the format: + + testname/srcname.pdf validhash + + More than one validhash is allowed (on separate lines), + and hash-delimited comments are allowed. +''' + +import os +import collections +from pdfrw.py23_diffs import convert_load + +root_dir = os.path.dirname(__file__) +result_dir = 'tmp_results' +if os.path.exists('ramdisk'): + result_dir = os.path.join('ramdisk', result_dir) +result_dir = os.path.join(root_dir, result_dir) + +for sourcef in ('mytests.txt', 'expected.txt'): + expectedf = os.path.join(root_dir, sourcef) + if os.path.exists(expectedf): + break + + +def results(): + results = collections.defaultdict(set) + with open(expectedf, 'rb') as f: + for line in f: + line = convert_load(line) + line = line.split('#', 1)[0].split() + if not line: + continue + key, value = line + results[key].add(value) + return results +results = results() diff --git a/tests/expected.txt b/tests/expected.txt new file mode 100644 index 0000000..64eecdd --- /dev/null +++ b/tests/expected.txt @@ -0,0 +1,140 @@ +# Example programs + +examples/4up_b1c400de699af29ea3f1983bb26870ab 1b73c612c40b5082d955ed72f63644bd +examples/alter_b1c400de699af29ea3f1983bb26870ab 3c3ee465f45a685ba7098691be05a5ab +examples/booklet_b1c400de699af29ea3f1983bb26870ab d711b74110eefb4e9e6bf1a5bea16bfe +examples/extract_1975ef8db7355b1d691bc79d0749574b b4f5ee36a288da970ed040a9a733c8b0 +examples/extract_c5c895deecf7a7565393587e0d61be2b 539aad09ef80907bb396c3260eb87d7b +examples/extract_d711b74110eefb4e9e6bf1a5bea16bfe 26ddfd09c6e6002228f06782c8544ac4 +examples/print_two_b1c400de699af29ea3f1983bb26870ab 73c8a16aba44548c2c06dae6e2551961 +examples/subset_b1c400de699af29ea3f1983bb26870ab_1-3_5 880a9578197130273ccb51265af08029 +examples/unspread_d711b74110eefb4e9e6bf1a5bea16bfe 780a9abe26a9de0b5b95ee22c4835e4b + +examples/cat_b1c400de699af29ea3f1983bb26870ab_06c86654f9a77e82f9adaa0086fc391c 62bb9b746ff5932d3f1b88942d36a81d +examples/rotate_707e3e2d17cbe9ec2273414b3b63f333_270_1-4_7-8_10-50_52-56 841c980dfadf2cc47ad86e4649ca69b6 +examples/watermark_b1c400de699af29ea3f1983bb26870ab_06c86654f9a77e82f9adaa0086fc391c 41989bb2cb6225c6e14262ff5d4f151f +examples/watermark_b1c400de699af29ea3f1983bb26870ab_06c86654f9a77e82f9adaa0086fc391c_-u e43e3ac0afe1cc242549424755dbf612 + +# All these are in the poster test +examples/subset_1975ef8db7355b1d691bc79d0749574b_21 5057f345f1a1109a0e54276a68e8f8df +examples/rotate_5057f345f1a1109a0e54276a68e8f8df_90_1 881f4dc8dcf069e707bf61af95492d86 +examples/poster_881f4dc8dcf069e707bf61af95492d86 a34be06d22105b6c02394a9f278fec0d + +examples/rl1/4up_b1c400de699af29ea3f1983bb26870ab 959d6246ad8bda72bd023e8681216d17 +examples/rl1/booklet_b1c400de699af29ea3f1983bb26870ab 45b4ae29a038271896b7264bbed63bdf +examples/rl1/subset_b1c400de699af29ea3f1983bb26870ab_3_5 822bce1cb9e053f1f3f6b922bf27fab8 +examples/rl1/platypus_pdf_template_b1c400de699af29ea3f1983bb26870ab 97ad6a8ca3fe7cc4e1f0ffb8475355e9 + +# List things that need work here (typically cause exceptions) + +# Bad info dict -- works otherwise + +simple/b1c400de699af29ea3f1983bb26870ab.pdf ecf2e28de18a724b53670c0d5637ec28 +repaginate/b1c400de699af29ea3f1983bb26870ab.pdf 4d7d6c5f6e14c6eac1dfc055cebfa499 + +# 07b0ba4 is missing an object. Best we can do is report it +# (and we do) + +repaginate/07b0ba4cff1c6ff73fd468b04b013457.pdf 993c763e085bce7ecc941ba104f4c892 +simple/07b0ba4cff1c6ff73fd468b04b013457.pdf 499b9c1b1e1c76b7c5c0d5e3b62889e3 + +#b107 has a single page, but with an empty contents dict. + +repaginate/b107669d1dd69eabb89765fabb2cb321.pdf 0652d2da25b50cad75863d0e2bbaa878 +simple/b107669d1dd69eabb89765fabb2cb321.pdf 56025c06ab8633575ddc6c6990d2fbf1 + +# Encrypted files + +repaginate/0ae80b493bc21e6de99f2ff6bbb8bc2c.pdf skip +repaginate/6e122f618c27f3aa9a689423e3be6b8d.pdf skip +repaginate/7dc787639aa6765214e9ff5494d231ed.pdf skip +repaginate/b4b27aaa1f9c7c524298e98be279bebb.pdf skip +repaginate/b5b6c6405d7b48418bccf97277957664.pdf skip +repaginate/bd0ef57aec16ded45bd89d61b54af0be.pdf skip +repaginate/dbb807a878ac1da6b91ac15c9de4e209.pdf skip +simple/0ae80b493bc21e6de99f2ff6bbb8bc2c.pdf skip +simple/6e122f618c27f3aa9a689423e3be6b8d.pdf skip +simple/7dc787639aa6765214e9ff5494d231ed.pdf skip +simple/b4b27aaa1f9c7c524298e98be279bebb.pdf skip +simple/b5b6c6405d7b48418bccf97277957664.pdf skip +simple/bd0ef57aec16ded45bd89d61b54af0be.pdf skip +simple/dbb807a878ac1da6b91ac15c9de4e209.pdf skip + + + +# List good hashes for round-trips here. + +repaginate/06c86654f9a77e82f9adaa0086fc391c.pdf 848966fe40a1e3de842f82700dc6d67b +repaginate/08f69084d72dabc5dfdcf5c1ff2a719f.pdf b8c60878b0e0ce81cb6e8777038166b1 +repaginate/09715ec1a7b0f3a7ae02b3046f627b9f.pdf daf7cff9c0a15bbb347489f9fbda25f8 +repaginate/0a61de50b5ee0ea4d5d69c95dab817a3.pdf c6cd38b1131c4b856f60ebfcf51da6f5 +repaginate/1975ef8db7355b1d691bc79d0749574b.pdf 53e5510be27db134edf3cf23873914af +repaginate/1c2af1d2b0db6cac3c8e558a26efd38b.pdf 20dc3be2affe9082564c01b1146d7598 +repaginate/1f5dd128c3757420a881a155f2f8ace3.pdf 019aead1450842406a04c508243e5161 +repaginate/22628a7ed578b622520325673ab2a4f2.pdf 255776a6956918c7b324dede711680ae +repaginate/2ac7c68e26a8ef797aead15e4875cc6d.pdf e7344551183415d6257e2cab2aef4a61 +repaginate/295d26e61a85635433f8e4b768953f60.pdf 13ece51f4d2ad25707982765abbcd789 +repaginate/2fac0d9a189ca5fcef8626153d050be8.pdf 95fe3d9258ace5bdccb95a55c2c8cb22 +repaginate/319c998910453bc44d40c7748cd2cb79.pdf c1a19d1acc3f172711bdbea000cf392e +repaginate/35df0b8cff4afec0c08f08c6a5bc9857.pdf 3568e1c885a461b350c790ec5b729af3 +repaginate/365b9c95574ee8944370fe286905d0e8.pdf 84e5fc0d4f30ff8db05780fd244d9cf0 +repaginate/4805fdcd7e142e8df3c04c6ba06025af.pdf 3b5b8254dc99c2f0f62fe2afa42fad4e +repaginate/49e31fd074eca6af981d78d42d0078ec.pdf 77fd3fa86c7c0166a373b66cfef357d2 +repaginate/536dfc6fbadd87c03eb59375d091eb53.pdf d0b7467d7bd6c7f73b7764b06c0be1aa +repaginate/569f8094597bbe5b58efc3a7c6e14e87.pdf 6b0ab50c247ca43b70b2b2f27ee2c1a2 +repaginate/5f0cff36d0ad74536a6513a98a755016.pdf b65c2557988db8625c0761bab1d131f1 +repaginate/5f265db2736850782aeaba2571a3c749.pdf 9bb5644ede0ee7cf99642729eda76686 +repaginate/6a42c8c79b807bf164d31071749e07b0.pdf 33a231263e1a4203338b7b1052fc0091 +repaginate/6f3a4de5c68ba3b5093e9b54b7c4e9f4.pdf 93419e831e436d9093a153f35d3441c3 +repaginate/7037a992b80b60f0294016037baa9292.pdf dd41b0104f185206b51e7ffe5b07d261 +repaginate/707e3e2d17cbe9ec2273414b3b63f333.pdf 6c65526ab372d72cb185933e3d2584ef +repaginate/71a751ce2d93a6a5d6ff21735b701fb7.pdf a825f06c934319b93474902fcf300cd2 +repaginate/72eb207b8f882618899aa7a65d3cecda.pdf 0b64f19a8a39fadfa2a3eec3f1a01233 +repaginate/97ba0a239cefa0dc727c2f1be050ec6c.pdf a94fe7183ce8979174b2ac16dcd9b1ea +repaginate/9d8626d18b1d8807d271e6ffc409446a.pdf cdfcf8add1af9e612ba1a2ee06a6a273 +repaginate/9f98322c243fe67726d56ccfa8e0885b.pdf 69503ac140a1e4f1322f9350646e3dae +repaginate/c55eb9a13859a7fbddd8af9c16eba3a7.pdf b0d1f3925423f9c3ecf4a47baa949f75 +repaginate/c5c895deecf7a7565393587e0d61be2b.pdf 59e350c6f7d7b89fab36a4019bb526fd +repaginate/d2f0b2086160d4f3d325c79a5dc1fb4d.pdf 3623b7f200818c63cb6838f9678a4840 +repaginate/d6fd9567078b48c86710e9c49173781f.pdf 874b532f61139261f71afb5987dd2a68 +repaginate/e9ab02aa769f4c040a6fa52f00d6e3f0.pdf 7d3c3ae13cc7d53e7fa6ef046e15dbaa +repaginate/ec00d5825f47b9d0faa953b1709163c3.pdf 8e6a481476c2b3bdd64ce8e36f8fe273 +repaginate/ed81787b83cc317c9f049643b853bea3.pdf 4636b68f294302417b81aaaadde1c73d + +simple/06c86654f9a77e82f9adaa0086fc391c.pdf 6e2a2e063de895d28dfea9aacb9fe469 +simple/08f69084d72dabc5dfdcf5c1ff2a719f.pdf 5a41601f6033356539e623091a3f79ef +simple/0a61de50b5ee0ea4d5d69c95dab817a3.pdf 182712dd5be8aebd29decb57cf530334 +simple/09715ec1a7b0f3a7ae02b3046f627b9f.pdf c4e4b3b725bd5fc3b008f1ac6251ad1c +simple/1975ef8db7355b1d691bc79d0749574b.pdf 475c28c9588f3a7f6110d30f391758c4 +simple/1c2af1d2b0db6cac3c8e558a26efd38b.pdf 3f17f19fd92adf01998bb13a0ee52b92 +simple/1f5dd128c3757420a881a155f2f8ace3.pdf b0d01f9d6ac156326aeb14b940aa73e7 +simple/22628a7ed578b622520325673ab2a4f2.pdf 1163cec415728899e997a29be465d02d +simple/295d26e61a85635433f8e4b768953f60.pdf fe3b8960c7f877db05c7cd12c9c6e097 +simple/2ac7c68e26a8ef797aead15e4875cc6d.pdf 2623eae06eada9587574f8ddd7fc80fa +simple/2fac0d9a189ca5fcef8626153d050be8.pdf 458501ecda909b00262b9654f0b09ebf +simple/319c998910453bc44d40c7748cd2cb79.pdf 8c84e36ec1db8c1dbfaa312646e000b4 +simple/35df0b8cff4afec0c08f08c6a5bc9857.pdf 0a2926c23ad916c449d5dadcfa9d38ef +simple/365b9c95574ee8944370fe286905d0e8.pdf cf3bfac41f410bf5bd657e3f906dfbc6 +simple/4805fdcd7e142e8df3c04c6ba06025af.pdf 3b5b8254dc99c2f0f62fe2afa42fad4e +simple/49e31fd074eca6af981d78d42d0078ec.pdf 2c316537a5b0917634cbbdc5b91511df +simple/536dfc6fbadd87c03eb59375d091eb53.pdf 319851765c70ba103c4191f7ec2148db +simple/569f8094597bbe5b58efc3a7c6e14e87.pdf 025f1bf95cc537c36b8c3a044758b86c +simple/5f0cff36d0ad74536a6513a98a755016.pdf 8476fd75e75394fcbbe02816d0640e7d +simple/5f265db2736850782aeaba2571a3c749.pdf d4d2e93ab22e866c86e32da84421f6f9 +simple/6a42c8c79b807bf164d31071749e07b0.pdf 221fec351c925a43f5f409fe03d90013 +simple/6f3a4de5c68ba3b5093e9b54b7c4e9f4.pdf fe8dd16dd7fef40338140e0610d0cbbf +simple/7037a992b80b60f0294016037baa9292.pdf 6a2ef24e5f74dd74969ff8cefdfc6a05 +simple/707e3e2d17cbe9ec2273414b3b63f333.pdf 4bdf1e57a96ce42717110b4e55098c1a +simple/71a751ce2d93a6a5d6ff21735b701fb7.pdf a825f06c934319b93474902fcf300cd2 +simple/72eb207b8f882618899aa7a65d3cecda.pdf 4ce7ff29531cc417c26389af28dc1c5e +simple/97ba0a239cefa0dc727c2f1be050ec6c.pdf c24873bab85b8ecc7c5433d8d802bceb +simple/9d8626d18b1d8807d271e6ffc409446a.pdf 2358d654bf20d2b9d179ab009a615c4e +simple/9f98322c243fe67726d56ccfa8e0885b.pdf 9290b4c32f005e1e4c7f431955246c4c +simple/c55eb9a13859a7fbddd8af9c16eba3a7.pdf 6b406128e0ed1ac23dc5a0ee34d1f717 +simple/c5c895deecf7a7565393587e0d61be2b.pdf 2cc3c75e56d5dd562ca5b1f994bd9d5c +simple/d2f0b2086160d4f3d325c79a5dc1fb4d.pdf 2083f0e55cf06d88df02956a21bfef23 +simple/d6fd9567078b48c86710e9c49173781f.pdf 77464ec5cfdacb61a73b506bc4945631 +simple/e9ab02aa769f4c040a6fa52f00d6e3f0.pdf 5bc96989bc4f4b6438da953443336124 +simple/ec00d5825f47b9d0faa953b1709163c3.pdf 708f66049169c28ac39b0553908dc318 +simple/ed81787b83cc317c9f049643b853bea3.pdf c227d627217dc6808c50e80063734d27 + diff --git a/tests/myprofile.py b/tests/myprofile.py new file mode 100644 index 0000000..af18a64 --- /dev/null +++ b/tests/myprofile.py @@ -0,0 +1,5 @@ +import cProfile +import unittest +import test_roundtrip + +cProfile.run('unittest.main(test_roundtrip)') diff --git a/tests/test_examples.py b/tests/test_examples.py new file mode 100755 index 0000000..baa98a6 --- /dev/null +++ b/tests/test_examples.py @@ -0,0 +1,195 @@ +#! /usr/bin/env python + +# A part of pdfrw (https://github.com/pmaupin/pdfrw) +# Copyright (C) 2015 Patrick Maupin, Austin, Texas +# MIT license -- See LICENSE.txt for details + +''' +Run from the directory above like so: + + python -m tests.test_examples + +A PDF that has been determined to be good or bad +should be added to expected.txt with either a good +checksum, or just the word "fail". + +These tests are incomplete, but they allow us to try +out various PDFs. There is a collection of difficult +PDFs available on github. + +In order to use them: + + 1) Insure that github.com/pmaupin/static_pdfs is on your path. + + 2) Use the imagemagick compare program to look at differences + between the static_pdfs/global directory and the tmp_results + directory after you run this. + + +''' +import sys +import os +import hashlib +import subprocess +import static_pdfs +import expected + +from pdfrw.py23_diffs import convert_store +from pdfrw import PdfReader, PdfWriter + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +prog_dir = os.path.join(expected.root_dir, '..', 'examples', '%s.py') +prog_dir = os.path.abspath(prog_dir) +dstdir = os.path.join(expected.result_dir, 'examples') +hashfile = os.path.join(expected.result_dir, 'hashes.txt') + +lookup = static_pdfs.pdffiles[0] +lookup = dict((os.path.basename(x)[:-4], x) for x in lookup) + + +class TestOnePdf(unittest.TestCase): + + def do_test(self, params, prev_results=[''], scrub=False): + params = params.split() + hashkey = 'examples/%s' % '_'.join(params) + params = [lookup.get(x, x) for x in params] + progname = params[0] + params[0] = prog_dir % progname + srcf = params[1] + params.insert(0, sys.executable) + subdir, progname = os.path.split(progname) + subdir = os.path.join(dstdir, subdir) + if not os.path.exists(subdir): + os.makedirs(subdir) + os.chdir(subdir) + dstf = '%s.%s' % (progname, os.path.basename(srcf)) + scrub = scrub and dstf + dstf = dstf if not scrub else 'final.%s' % dstf + hash = '------no-file-generated---------' + expects = expected.results[hashkey] + + # If the test has been deliberately skipped, + # we are done. Otherwise, execute it even + # if we don't know about it yet, so we have + # results to compare. + + result = 'fail' + size = 0 + try: + if 'skip' in expects: + result = 'skip requested' + return self.skipTest(result) + elif 'xfail' in expects: + result = 'xfail requested' + return self.fail(result) + + exists = os.path.exists(dstf) + if expects or not exists: + if exists: + os.remove(dstf) + if scrub and os.path.exists(scrub): + os.remove(scrub) + subprocess.call(params) + if scrub: + PdfWriter().addpages(PdfReader(scrub).pages).write(dstf) + with open(dstf, 'rb') as f: + data = f.read() + size = len(data) + if data: + hash = hashlib.md5(data).hexdigest() + lookup[hash] = dstf + prev_results[0] = hash + else: + os.remove(dstf) + if expects: + if len(expects) == 1: + expects, = expects + self.assertEqual(hash, expects) + else: + self.assertIn(hash, expects) + result = 'pass' + else: + result = 'skip' + self.skipTest('No hash available') + finally: + result = '%8d %-20s %s %s\n' % (size, result, hashkey, hash) + with open(hashfile, 'ab') as f: + f.write(convert_store(result)) + + def test_4up(self): + self.do_test('4up b1c400de699af29ea3f1983bb26870ab') + + def test_booklet_unspread(self): + prev = [None] + self.do_test('booklet b1c400de699af29ea3f1983bb26870ab', prev) + if prev[0] is not None: + self.do_test('unspread ' + prev[0]) + self.do_test('extract ' + prev[0]) + + def test_print_two(self): + self.do_test('print_two b1c400de699af29ea3f1983bb26870ab') + + def test_watermarks(self): + self.do_test('watermark b1c400de699af29ea3f1983bb26870ab ' + '06c86654f9a77e82f9adaa0086fc391c') + self.do_test('watermark b1c400de699af29ea3f1983bb26870ab ' + '06c86654f9a77e82f9adaa0086fc391c -u') + + def test_subset(self): + self.do_test('subset b1c400de699af29ea3f1983bb26870ab 1-3 5') + + def test_alter(self): + self.do_test('alter b1c400de699af29ea3f1983bb26870ab') + + def test_cat(self): + self.do_test('cat b1c400de699af29ea3f1983bb26870ab ' + '06c86654f9a77e82f9adaa0086fc391c') + + def test_rotate(self): + self.do_test('rotate 707e3e2d17cbe9ec2273414b3b63f333 ' + '270 1-4 7-8 10-50 52-56') + + def test_poster(self): + prev = [None] + self.do_test('subset 1975ef8db7355b1d691bc79d0749574b 21', prev) + self.do_test('rotate %s 90 1' % prev[0], prev) + self.do_test('poster %s' % prev[0], prev) + + def test_extract(self): + self.do_test('extract 1975ef8db7355b1d691bc79d0749574b') + self.do_test('extract c5c895deecf7a7565393587e0d61be2b') + + def test_rl1_4up(self): + if sys.version_info < (2, 7): + return + self.do_test('rl1/4up b1c400de699af29ea3f1983bb26870ab', + scrub=True) + + def test_rl1_booklet(self): + if sys.version_info < (2, 7): + return + self.do_test('rl1/booklet b1c400de699af29ea3f1983bb26870ab', + scrub=True) + + def test_rl1_subset(self): + if sys.version_info < (2, 7): + return + self.do_test('rl1/subset b1c400de699af29ea3f1983bb26870ab 3 5', + scrub=True) + + def test_rl1_platypus(self): + if sys.version_info < (2, 7): + return + self.do_test('rl1/platypus_pdf_template b1c400de699af29ea3f1983bb26870ab', + scrub=True) + +def main(): + unittest.main() + +if __name__ == '__main__': + main() diff --git a/tests/test_pdfstring.py b/tests/test_pdfstring.py index 4dcd2df..fce47ef 100644 --- a/tests/test_pdfstring.py +++ b/tests/test_pdfstring.py @@ -1,3 +1,5 @@ +#! /usr/bin/env python + ''' Run from the directory above like so: python -m tests.test_pdfstring @@ -12,11 +14,11 @@ class TestEncoding(unittest.TestCase): @staticmethod def decode(value): - return pdfrw.pdfobjects.PdfString(value).decode() + return pdfrw.objects.PdfString(value).decode() @staticmethod def encode(value): - return str(pdfrw.pdfobjects.PdfString.encode(value)) + return str(pdfrw.objects.PdfString.encode(value)) @classmethod def encode_decode(cls, value): diff --git a/tests/test_roundtrip.py b/tests/test_roundtrip.py new file mode 100755 index 0000000..cb3645e --- /dev/null +++ b/tests/test_roundtrip.py @@ -0,0 +1,132 @@ +#! /usr/bin/env python + +# A part of pdfrw (https://github.com/pmaupin/pdfrw) +# Copyright (C) 2015 Patrick Maupin, Austin, Texas +# MIT license -- See LICENSE.txt for details + +''' +Run from the directory above like so: + + python -m tests.test_roundtrip + +A PDF that has been determined to be good or bad +should be added to expected.txt with either a good +checksum, or just the word "fail". + +These tests are incomplete, but they allow us to try +out various PDFs. There is a collection of difficult +PDFs available on github. + +In order to use them: + + 1) Insure that github.com/pmaupin/static_pdfs is on your path. + + 2) Use the imagemagick compare program to look at differences + between the static_pdfs/global directory and the tmp_results + directory after you run this. + + +''' +import os +import hashlib +import pdfrw +import static_pdfs +import expected + +from pdfrw.py23_diffs import convert_store + +try: + import unittest2 as unittest +except ImportError: + import unittest + + +class TestOnePdf(unittest.TestCase): + + def roundtrip(self, testname, basename, srcf, decompress=False, + compress=False, repaginate=False): + dstd = os.path.join(expected.result_dir, testname) + if not os.path.exists(dstd): + os.makedirs(dstd) + dstf = os.path.join(dstd, basename) + hashfile = os.path.join(expected.result_dir, 'hashes.txt') + hashkey = '%s/%s' % (testname, basename) + hash = '------no-file-generated---------' + expects = expected.results[hashkey] + + # If the test has been deliberately skipped, + # we are done. Otherwise, execute it even + # if we don't know about it yet, so we have + # results to compare. + + result = 'fail' + size = 0 + try: + if 'skip' in expects: + result = 'skip requested' + return self.skipTest(result) + elif 'xfail' in expects: + result = 'xfail requested' + return self.fail(result) + + exists = os.path.exists(dstf) + if expects or not exists: + if exists: + os.remove(dstf) + trailer = pdfrw.PdfReader(srcf, decompress=decompress, + verbose=False) + if trailer.Encrypt: + result = 'skip -- encrypt' + hash = '------skip-encrypt-no-file------' + return self.skipTest('File encrypted') + writer = pdfrw.PdfWriter(compress=compress) + if repaginate: + writer.addpages(trailer.pages) + trailer = None + writer.write(dstf, trailer) + with open(dstf, 'rb') as f: + data = f.read() + size = len(data) + if data: + hash = hashlib.md5(data).hexdigest() + else: + os.remove(dstf) + if expects: + if len(expects) == 1: + expects, = expects + self.assertEqual(hash, expects) + else: + self.assertIn(hash, expects) + result = 'pass' + else: + result = 'skip' + self.skipTest('No hash available') + finally: + result = '%8d %-20s %s %s\n' % (size, result, hashkey, hash) + with open(hashfile, 'ab') as f: + f.write(convert_store(result)) + + +def build_tests(): + def test_closure(*args, **kw): + def test(self): + self.roundtrip(*args, **kw) + return test + for mytest, repaginate in ( + ('simple', False), + ('repaginate', True) + ): + for srcf in static_pdfs.pdffiles[0]: + basename = os.path.basename(srcf) + test_name = 'test_%s_%s' % (mytest, basename) + test = test_closure(mytest, basename, srcf, + repaginate=repaginate) + setattr(TestOnePdf, test_name, test) +build_tests() + + +def main(): + unittest.main() + +if __name__ == '__main__': + main() |