1#! /usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# file src/tex2lyx/test/runtests.py 5# This file is part of LyX, the document processor. 6# Licence details can be found in the file COPYING. 7 8# author Georg Baum 9 10# Full author contact details are available in file CREDITS 11 12# This script is a very basic test suite runner for tex2lyx 13# The defaults for optional command line arguments are tailored to the 14# standard use case of testing without special build settings like a version 15# suffix, since I don't know how to transport command line arguments through 16# the autotools "make check" mechanism. 17 18from __future__ import print_function 19 20import os, string, sys, time, difflib, filecmp, subprocess, re 21 22def usage(prog_name): 23 return "Usage: %s [uselyx2lyx] [<tex2lyx binary> [[<script dir>] [[<output dir>] [testfile]]]]" % prog_name 24 25pat_fl1 = re.compile(r'^#LyX file created by tex2lyx .*$') 26pat_fl2 = re.compile(r'^#LyX \d+\.\d+ created this file.*$') 27 28def compareLyx(lines1, lines2): 29 if lines1[1:] != lines2[1:]: 30 return False 31 if not pat_fl1.match(lines1[0]) and not pat_fl2.match(lines1[0]): 32 return False 33 if not pat_fl1.match(lines2[0]) and not pat_fl2.match(lines2[0]): 34 return False 35 return True 36 37def main(argv): 38 # Parse and manipulate the command line arguments. 39 skipcount = 0 40 uselyx2lyx = False 41 if len(argv) > 1: 42 if argv[1] == "uselyx2lyx": 43 uselyx2lyx = True 44 skipcount = 1 45 if len(argv) >= 3+skipcount: 46 sys.path.append(os.path.join(sys.argv[2+skipcount])) 47 else: 48 sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), '../../../lib/scripts')) 49 50 from lyxpreview_tools import error 51 52 if len(argv) < 2+skipcount: 53 tex2lyx = './tex2lyx' 54 elif len(argv) <= 5+skipcount: 55 tex2lyx = argv[1+skipcount] 56 else: 57 error(usage(argv[0])) 58 59 suffixre = re.search(r'\d+\.\d+$', tex2lyx) 60 if suffixre: 61 suffix = suffixre.group() 62 else: 63 suffix = "" 64 lyx = os.path.join(os.path.dirname(tex2lyx), "lyx" + suffix) 65 inputdir = os.path.realpath(os.path.dirname(argv[0])) 66 if len(argv) >= 4+skipcount: 67 outputdir = os.path.realpath(sys.argv[3+skipcount]) 68 else: 69# outputdir = inputdir 70 outputdir = os.path.realpath(os.path.join(os.path.dirname(tex2lyx), "test")) 71 72 if len(argv) >= 5+skipcount: 73 files = [sys.argv[4+skipcount]] 74 else: 75 files = ['test.ltx', \ 76 'algo2e.tex', \ 77 'beamer.tex', \ 78 'box-color-size-space-align.tex', \ 79 'CJK.tex', \ 80 'CJKutf8.tex', \ 81 'test-insets.tex', \ 82 'test-insets-basic.tex', \ 83 'test-memoir.tex', \ 84 'test-minted.tex', \ 85 'test-modules.tex', \ 86 'test-refstyle-theorems.tex', \ 87 'test-scr.tex', \ 88 'test-structure.tex', \ 89 'verbatim.tex', \ 90 'XeTeX-polyglossia.tex'] 91 92 errors = [] 93 overwrite = (outputdir == inputdir) 94 for f in files: 95 (base, ext) = os.path.splitext(f) 96 texfile = os.path.join(inputdir, f) 97 if overwrite: 98 # we are updating the test references, so use roundtrip to allow 99 # for checking the LyX export as well. 100 cmd = '%s -roundtrip -f %s' % (tex2lyx, texfile) 101 else: 102 lyxfile = os.path.join(outputdir, base + ".lyx") 103 cmd = '%s -roundtrip -copyfiles -f %s %s' % (tex2lyx, texfile, lyxfile) 104 print('Executing: ' + cmd + "\n") 105 proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 106 proc.wait() 107 err = proc.returncode 108 errorstring = proc.stderr.read() 109 if not errorstring is None: 110 print(errorstring) 111 if err != 0: 112 errors.append(f) 113 elif not overwrite: 114 lyxfile1 = getlyxinput(lyx, 115 os.path.join(inputdir, base + ".lyx.lyx"), 116 os.path.join(outputdir, base + ".lyx1.lyx") , uselyx2lyx) 117 if lyxfile1 is None: 118 errors.append(f) 119 else: 120 lyxfile2 = getlyxinput(lyx, 121 os.path.join(outputdir, base + ".lyx"), 122 os.path.join(outputdir, base + ".lyx2.lyx"), uselyx2lyx) 123 if lyxfile2 is None: 124 errors.append(f) 125 else: 126 t1 = time.ctime(os.path.getmtime(lyxfile1)) 127 t2 = time.ctime(os.path.getmtime(lyxfile2)) 128 f1 = open(lyxfile1, 'r') 129 f2 = open(lyxfile2, 'r') 130 lines1 = f1.readlines() 131 i1 = 0 132 for linex in lines1: 133 if linex[:-1] == '\origin ' + inputdir + '/': 134 lines1[i1] = '\origin ' + outputdir + '/' + "\n" 135 break 136 i1 = i1+1 137 lines2 = f2.readlines() 138 f1.close() 139 f2.close() 140 # ignore the first line e.g. the version of lyx 141 if not compareLyx(lines1, lines2): 142 diff = difflib.unified_diff(lines1, lines2, lyxfile1, lyxfile2, t1, t2) 143 sys.stdout.writelines(diff) 144 errors.append(f) 145 146 147 if len(errors) > 0: 148 error('Converting the following files failed: %s' % ', '.join(errors)) 149 150def getlyxinput(lyx, lyxfx, lyxf, uselyx2lyx): 151 if uselyx2lyx: 152 cmd = '%s -E lyx %s %s' % (lyx, lyxf, lyxfx) 153 sys.stdout.writelines(cmd) 154 sys.stdout.writelines("\n") 155 if os.system(cmd) != 0: 156 return None 157 return lyxf 158 else: 159 return lyxfx 160 161if __name__ == "__main__": 162 main(sys.argv) 163 164