diff --git a/.gitignore b/.gitignore index 7b811cf..f796ffa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,20 +3,18 @@ CMakeFiles/* cmake_install.cmake CTestTestfile.cmake gmon.out -Makefile install_manifest.txt +Makefile pdf2htmlEX pdf2htmlEX.1 +*.pyc share/base.css +share/base.min.css share/fancy.css -share/js_src/css_class_names.js +share/fancy.min.css share/pdf2htmlEX.js +share/pdf2htmlEX.min.js src/pdf2htmlEX-config.h src/util/css_const.h -test/* +test export-ignore Testing/* -wiki/* -doc/* -/"\\" -/share/base.min.css -/share/fancy.min.css diff --git a/.travis.yml b/.travis.yml index 7a30945..91e1d88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,10 @@ language: cpp compiler: gcc before_install: + - sudo add-apt-repository ppa:fontforge/fontforge --yes - sudo add-apt-repository ppa:coolwanglu/pdf2htmlex --yes - sudo apt-get update -qq - - sudo apt-get install -qq libpoppler-dev libspiro-dev libcairo-dev libfreetype6-dev libltdl-dev -install: - - export LIBRARY_PATH=/usr/local/lib - - export LD_LIBRARY_PATH=/usr/local/lib - - pushd .. - - wget 'https://github.com/coolwanglu/fontforge/archive/pdf2htmlEX.tar.gz' -O - | tar -zxf - - - pushd fontforge-pdf2htmlEX && ./autogen.sh && ./configure && make && sudo make install && popd - - popd + - sudo apt-get install -qq libpoppler-dev libspiro-dev libcairo-dev libfreetype6-dev libltdl-dev libfontforge-dev libpango1.0-dev before_script: - cmake -DENABLE_SVG=ON . script: diff --git a/CMakeLists.txt b/CMakeLists.txt index 63e7f2a..f17578b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,5 +203,4 @@ install (FILES ${PDF2HTMLEX_RESOURCE} DESTINATION share/pdf2htmlEX) install (FILES pdf2htmlEX.1 DESTINATION share/man/man1) enable_testing() -add_test(test_naming - python ${CMAKE_SOURCE_DIR}/test/test_naming.py) +add_test(test python ${CMAKE_SOURCE_DIR}/test/test.py) diff --git a/CTestCustom.cmake b/CTestCustom.cmake new file mode 100644 index 0000000..f8c87fb --- /dev/null +++ b/CTestCustom.cmake @@ -0,0 +1 @@ +SET(CTEST_CUSTOM_POST_TEST "cat Testing/Temporary/LastTest.log") diff --git a/share/manifest b/share/manifest index 74088d1..751bdb2 100644 --- a/share/manifest +++ b/share/manifest @@ -11,6 +11,7 @@ # # Special # If a line contains """ only, all text until next """ will be included +# #TEST_IGNORE_BEGIN & #TEST_IGNORE_END are used for unittest ############# # Declaration - Do not modify @@ -28,8 +29,12 @@ # Styles # base CSS styles - Do not modify @base.min.css + # fancy CSS styles - Optional +#TEST_IGNORE_BEGIN @fancy.min.css +#TEST_IGNORE_END + # PDF specific CSS styles - Do not modify $css @@ -39,7 +44,9 @@ $css # compatibility.min.js, extracted from PDF.js # To support old browsers like IE9 +#TEST_IGNORE_BEGIN @compatibility.min.js +#TEST_IGNORE_END # entry point of pdf2htmlEX.Viewer # You can override default configuration by passing an object to the constructor of Viewer @@ -48,6 +55,7 @@ $css # pdf2htmlEX.defaultViewer = new pdf2htmlEX.Viewer({ # 'key_handler' : false # }); +#TEST_IGNORE_BEGIN @pdf2htmlEX.min.js """ """ +#TEST_IGNORE_END + ############# # Do not modify @@ -71,6 +81,8 @@ try{ # You can add a class 'opened' here if you want it always opened or you don't use pdf2htmlEX.js # e.g. # """ +#TEST_IGNORE_END ############# # The container of PDF pages @@ -100,6 +113,8 @@ $pages # shown when loading a page via ajax # The default appearance should be invisible # The 'active' class will be added when it is used + +#TEST_IGNORE_BEGIN """
""" @@ -107,6 +122,7 @@ $pages """
""" +#TEST_IGNORE_END ############# # Do not modify diff --git a/test/old/convert_to_woff.fontforge b/test/old/convert_to_woff.fontforge new file mode 100644 index 0000000..aa85cb4 --- /dev/null +++ b/test/old/convert_to_woff.fontforge @@ -0,0 +1,3 @@ +Open($1); +Generate($1:r+".woff"); +Quit(0); diff --git a/test/old/test.py b/test/old/test.py new file mode 100755 index 0000000..ccaf9cc --- /dev/null +++ b/test/old/test.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python + +DIR = 'pdf' +#DIR = '../../pdf.js/test/pdfs' + +import os +import sys + +with open('out.html','w') as outf: + outf.write('\n
') + + for f in os.listdir(DIR): + if not f.lower().endswith('.pdf'): + continue + print f + if os.system('pdf2htmlEX -l 10 --no-drm 1 --fit-width 1024 --dest-dir html --external-hint-tool="ttfautohint" "%s/%s"' % (DIR,f)) != 0: + print "error on ", f + sys.exit(-1) + + ff = f[:-3] + outf.write('%s
' % (ff,ff)) + outf.flush(); + + outf.write('
') diff --git a/test/test.py b/test/test.py index ccaf9cc..ae3e41c 100755 --- a/test/test.py +++ b/test/test.py @@ -1,24 +1,88 @@ #!/usr/bin/env python -DIR = 'pdf' -#DIR = '../../pdf.js/test/pdfs' - +import unittest import os import sys +import tempfile +import shutil +import subprocess -with open('out.html','w') as outf: - outf.write('\n
') +class Common(object): + SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + TEST_DIR = os.path.join(SRC_DIR, 'test') + DATA_DIR = os.path.join(SRC_DIR, 'share') + PDF2HTMLEX_PATH = os.path.join(SRC_DIR, 'pdf2htmlEX') + + def setUp(self): + self.cur_temp_dir = tempfile.mkdtemp(prefix='pdf2htmlEX_test') + self.cur_data_dir = os.path.join(self.cur_temp_dir, 'share') + self.cur_output_dir = os.path.join(self.cur_temp_dir, 'out') + os.mkdir(self.cur_data_dir) + os.mkdir(self.cur_output_dir) + + # filter manifest + with open(os.path.join(self.DATA_DIR, 'manifest')) as inf: + with open(os.path.join(self.cur_data_dir, 'manifest'), 'w') as outf: + ignore = False + for line in inf: + if ignore: + if line.startswith('#TEST_IGNORE_END'): + ignore = False + elif line.startswith('#TEST_IGNORE_BEGIN'): + ignore = True + else: + outf.write(line) - for f in os.listdir(DIR): - if not f.lower().endswith('.pdf'): - continue - print f - if os.system('pdf2htmlEX -l 10 --no-drm 1 --fit-width 1024 --dest-dir html --external-hint-tool="ttfautohint" "%s/%s"' % (DIR,f)) != 0: - print "error on ", f - sys.exit(-1) + # copy files + shutil.copy(os.path.join(self.DATA_DIR, 'base.min.css'), + os.path.join(self.cur_data_dir, 'base.min.css')) - ff = f[:-3] - outf.write('%s
' % (ff,ff)) - outf.flush(); + def tearDown(self): + shutil.rmtree(self.cur_temp_dir, True) - outf.write('
') + def run_pdf2htmlEX(self, args): + """ + Execute the pdf2htmlEX with the specified arguments. + + :type args: list of values + :param args: list of arguments to pass to executable. + :return: an object of relevant info + """ + + cmd = [self.PDF2HTMLEX_PATH, + '--data-dir', self.cur_data_dir, + '--dest-dir', self.cur_output_dir + ] + + for val in args: + cmd.append(str(val)) + + return_code = subprocess.call(cmd) + self.assertEquals(return_code, 0) + + files = os.listdir(self.cur_output_dir) + files.sort() + + return { + 'return_code' : return_code, + 'output_files' : files + } + + +if __name__ == '__main__': + if not os.path.isfile(Common.PDF2HTMLEX_PATH) or not os.access(Common.PDF2HTMLEX_PATH, os.X_OK): + print >> sys.stderr, "Cannot locate pdf2htmlEX executable. Make sure source was built before running this test." + exit(1) + suites = [] + loader = unittest.TestLoader() + for module_name in ['test_naming']: + __import__(module_name) + suites.append(loader.loadTestsFromModule(sys.modules[module_name])) + + failure_count = 0 + runner = unittest.TextTestRunner(verbosity=2) + for suite in suites: + result = runner.run(suite) + failure_count += len(result.errors) + len(result.failures) + + exit(failure_count) diff --git a/test/test_naming.py b/test/test_naming.py index d08230b..fd9f051 100644 --- a/test/test_naming.py +++ b/test/test_naming.py @@ -1,264 +1,85 @@ #!/usr/bin/env python +# Test --split-page and --page-filename + import unittest import os -import sys -import tempfile -import shutil -import subprocess -# We assume that this file is put inside SRC_DIR/test -TEST_DIR = os.path.dirname(__file__) -# The location where our test PDFs are stored -TEST_DATA_DIR = os.path.join(TEST_DIR, 'test_data') -# The location where the base css file, etc is stored in the build folder -DATA_DIR = os.path.join(TEST_DIR, '../share') +from test import Common -# The script should be run in the directory containing the binary -# The location where the executable is generated by the build -PDF2HTMLEX_PATH = './pdf2htmlEX' +class OutputNamingTests(Common, unittest.TestCase): + def run_test_case(self, input_file, expected_output_files, args=[]): + args = list(args) + args.insert(0, os.path.join(self.TEST_DIR, 'test_naming', input_file)) + self.assertEquals(self.run_pdf2htmlEX(args)['output_files'], sorted(expected_output_files)) - -def execute_pdf2htmlex_with_args(args): - """ - Execute the pdf2htmlEX with the specified arguments. - - :type args: list of values - :param args: list of arguments to pass to executable. First part of each tuple is the argument, second part is the value. - - :rtype: int - :return: The exit code of the command - """ - executable = os.path.abspath(PDF2HTMLEX_PATH) - - cmd = [executable, '--data-dir', os.path.abspath(DATA_DIR)] - - for val in args: - cmd.append(str(val)) - - return_code = subprocess.call(cmd) - - if return_code != 0: - print >> sys.stderr, "Command return code %d: %s" % (return_code, ' '.join(cmd)) - - return return_code - -def execute_pdf2htmlex_and_get_files(args): - """ - Execute the pdf2htmlEX with the specified arguments, and get the names of the output files. Will automatically create - a temporary directory for the output, pass that as the output dir to pdf2htmlEX, determine the files generated, and - clean up the temporary directory afterwards. - - :type args: list of values - :param args: list of arguments to pass to executable. First part of each tuple is the argument, second part is the value. - - :rtype: list of str - :return: List of the file names that were generated as output in alphabetical order. None if the command does not execute successfully. - """ - temp_dir = tempfile.mkdtemp() - - try: - if execute_pdf2htmlex_with_args(['--dest-dir', temp_dir] + args) != 0: - return None - - files = os.listdir(temp_dir) - files.sort() - return files - finally: - shutil.rmtree(path=temp_dir, ignore_errors=True) - -def path_to_test_file(filename): - """ - Retrieve an absolute path to the specified test file. - - :type filename: - :param filename: the name of the test file to get the path to - - :rtype: str - :returns: the full path to the test file - """ - return os.path.abspath(os.path.join(TEST_DATA_DIR, filename)) - -class OutputNamingTests(unittest.TestCase): def test_generate_single_html_default_name_single_page_pdf(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('1-page.pdf') - ]) - self.assertEquals(files, ['1-page.html']) + self.run_test_case('1-page.pdf', ['1-page.html']) def test_generate_single_html_default_name_multiple_page_pdf(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf') - ]) - self.assertEquals(files, ['2-pages.html']) + self.run_test_case('2-pages.pdf', ['2-pages.html']) def test_generate_single_html_specify_name_single_page_pdf(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('1-page.pdf'), - 'foo.html' - ]) - self.assertEquals(files, ['foo.html']) + self.run_test_case('1-page.pdf', ['foo.html'], ['foo.html']) def test_generate_single_html_specify_name_multiple_page_pdf(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf'), - 'foo.html' - ]) - self.assertEquals(files, ['foo.html']) + self.run_test_case('2-pages.pdf', ['foo.html'], ['foo.html']) def test_generate_split_pages_default_name_single_page(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - path_to_test_file('1-page.pdf') - ]) - self.assertEquals(files, sorted(['1-page.html', '1-page1.page'])) + self.run_test_case('1-page.pdf', ['1-page.html', '1-page1.page'], ['--split-pages', 1]) def test_generate_split_pages_default_name_multiple_pages(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', '3-pages1.page', '3-pages2.page', '3-pages3.page'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', '3-pages1.page', '3-pages2.page', '3-pages3.page'], ['--split-pages', 1]) def test_generate_split_pages_specify_name_single_page(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'foo.xyz', - path_to_test_file('1-page.pdf'), - ]) - self.assertEquals(files, sorted(['1-page.html', 'foo1.xyz'])) + self.run_test_case('1-page.pdf', ['1-page.html', 'foo1.xyz'], ['--split-pages', 1, '--page-filename', 'foo.xyz']) def test_generate_split_pages_specify_name_multiple_pages(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'foo.xyz', - path_to_test_file('3-pages.pdf'), - ]) - self.assertEquals(files, sorted(['3-pages.html', 'foo1.xyz', 'foo2.xyz', 'foo3.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'foo1.xyz', 'foo2.xyz', 'foo3.xyz'], ['--split-pages', 1, '--page-filename', 'foo.xyz']) def test_generate_split_pages_specify_name_formatter_multiple_pages(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'fo%do.xyz', - path_to_test_file('3-pages.pdf'), - ]) - self.assertEquals(files, sorted(['3-pages.html', 'fo1o.xyz', 'fo2o.xyz', 'fo3o.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'fo1o.xyz', 'fo2o.xyz', 'fo3o.xyz'], ['--split-pages', 1, '--page-filename', 'fo%do.xyz']) def test_generate_split_pages_specify_name_formatter_with_padded_zeros_multiple_pages(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'fo%03do.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'fo001o.xyz', 'fo002o.xyz', 'fo003o.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'fo001o.xyz', 'fo002o.xyz', 'fo003o.xyz'], ['--split-pages', 1, '--page-filename', 'fo%03do.xyz']) def test_generate_split_pages_specify_name_only_first_formatter_gets_taken(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%do%do.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f1o%do.xyz', 'f2o%do.xyz', 'f3o%do.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f1o%do.xyz', 'f2o%do.xyz', 'f3o%do.xyz'], ['--split-pages', 1, '--page-filename', 'f%do%do.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_s(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%soo.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%soo1.xyz', 'f%soo2.xyz', 'f%soo3.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%soo1.xyz', 'f%soo2.xyz', 'f%soo3.xyz'], ['--split-pages', 1, '--page-filename', 'f%soo.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_p(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%poo.xyz', - path_to_test_file('3-pages.pdf'), - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%poo1.xyz', 'f%poo2.xyz', 'f%poo3.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%poo1.xyz', 'f%poo2.xyz', 'f%poo3.xyz'], ['--split-pages', 1, '--page-filename', 'f%poo.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_n(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%noo.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%noo1.xyz', 'f%noo2.xyz', 'f%noo3.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%noo1.xyz', 'f%noo2.xyz', 'f%noo3.xyz'], ['--split-pages', 1, '--page-filename', 'f%noo.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_percent(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%%oo.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%%oo1.xyz', 'f%%oo2.xyz', 'f%%oo3.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%%oo1.xyz', 'f%%oo2.xyz', 'f%%oo3.xyz'], ['--split-pages', 1, '--page-filename', 'f%%oo.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_percent_with_actual_placeholder(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%%o%do.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%%o1o.xyz', 'f%%o2o.xyz', 'f%%o3o.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%%o1o.xyz', 'f%%o2o.xyz', 'f%%o3o.xyz'], ['--split-pages', 1, '--page-filename', 'f%%o%do.xyz']) def test_generate_split_pages_specify_name_only_percent_d_is_used_percent_percent_with_actual_placeholder(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'fo%do%%.xyz', - path_to_test_file('3-pages.pdf') - ]) - self.assertEquals(files, sorted(['3-pages.html', 'fo1o%%.xyz', 'fo2o%%.xyz', 'fo3o%%.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'fo1o%%.xyz', 'fo2o%%.xyz', 'fo3o%%.xyz'], ['--split-pages', 1, '--page-filename', 'fo%do%%.xyz']) def test_generate_split_pages_specify_name_only_formatter_starts_part_way_through_invalid_formatter(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'f%02%doo.xyz', - path_to_test_file('3-pages.pdf'), - ]) - self.assertEquals(files, sorted(['3-pages.html', 'f%021oo.xyz', 'f%022oo.xyz', 'f%023oo.xyz'])) + self.run_test_case('3-pages.pdf', ['3-pages.html', 'f%021oo.xyz', 'f%022oo.xyz', 'f%023oo.xyz'], ['--split-pages', 1, '--page-filename', 'f%02%doo.xyz']) def test_generate_split_pages_specify_output_filename_no_formatter_no_extension(self): - files = execute_pdf2htmlex_and_get_files([ - '--split-pages', 1, - '--page-filename', 'foo', - path_to_test_file('1-page.pdf'), - ]) - self.assertEquals(files, sorted(['1-page.html', 'foo1'])) + self.run_test_case('1-page.pdf', ['1-page.html', 'foo1'], ['--split-pages', 1, '--page-filename', 'foo']) def test_generate_single_html_name_specified_format_characters_percent_d(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf'), - 'foo%d.html' - ]) - self.assertEquals(files, ['foo%d.html']) + self.run_test_case('2-pages.pdf', ['foo%d.html'], ['foo%d.html']) def test_generate_single_html_name_specified_format_characters_percent_p(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf'), - 'foo%p.html' - ]) - self.assertEquals(files, ['foo%p.html']) + self.run_test_case('2-pages.pdf', ['foo%p.html'], ['foo%p.html']) def test_generate_single_html_name_specified_format_characters_percent_n(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf'), - 'foo%n.html' - ]) - self.assertEquals(files, ['foo%n.html']) + self.run_test_case('2-pages.pdf', ['foo%n.html'], ['foo%n.html']) def test_generate_single_html_name_specified_format_characters_percent_percent(self): - files = execute_pdf2htmlex_and_get_files([ - path_to_test_file('2-pages.pdf'), - 'foo%%.html' - ]) - self.assertEquals(files, ['foo%%.html']) + self.run_test_case('2-pages.pdf', ['foo%%.html'], ['foo%%.html']) -if __name__=="__main__": - executable = os.path.abspath(PDF2HTMLEX_PATH) - if not os.path.isfile(executable) or not os.access(executable, os.X_OK): - print >> sys.stderr, "Cannot locate pdf2htmlEX executable. Make sure source was built before running this test." - exit(1) - - # we want to run pdf2htmlEX without installing it - shutil.copy(os.path.join(TEST_DIR, '../3rdparty/PDF.js/compatibility.min.js'), DATA_DIR) - unittest.main() diff --git a/test/test_data/1-page.pdf b/test/test_naming/1-page.pdf similarity index 100% rename from test/test_data/1-page.pdf rename to test/test_naming/1-page.pdf diff --git a/test/test_data/2-pages.pdf b/test/test_naming/2-pages.pdf similarity index 100% rename from test/test_data/2-pages.pdf rename to test/test_naming/2-pages.pdf diff --git a/test/test_data/3-pages.pdf b/test/test_naming/3-pages.pdf similarity index 100% rename from test/test_data/3-pages.pdf rename to test/test_naming/3-pages.pdf