diff --git a/examples/test_examples.py b/examples/test_examples.py index 81de8235..979bbfb5 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -1,6 +1,7 @@ from __future__ import print_function, division, absolute_import from pyqtgraph import Qt from . import utils +from collections import namedtuple import errno import importlib import itertools @@ -13,77 +14,6 @@ import time path = os.path.abspath(os.path.dirname(__file__)) - -def runExampleFile(name, f, exe, lib, graphicsSystem=None): - global path - fn = os.path.join(path,f) - os.chdir(path) - sys.stdout.write("{} ".format(name)) - sys.stdout.flush() - import1 = "import %s" % lib if lib != '' else '' - import2 = os.path.splitext(os.path.split(fn)[1])[0] - graphicsSystem = '' if graphicsSystem is None else "pg.QtGui.QApplication.setGraphicsSystem('%s')" % graphicsSystem - code = """ -try: - %s - import initExample - import pyqtgraph as pg - %s - import %s - import sys - print("test complete") - sys.stdout.flush() - import time - while True: ## run a little event loop - pg.QtGui.QApplication.processEvents() - time.sleep(0.01) -except: - print("test failed") - raise - -""" % (import1, graphicsSystem, import2) - if sys.platform.startswith('win'): - process = subprocess.Popen([exe], - stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE) - else: - process = subprocess.Popen(['exec %s -i' % (exe)], - shell=True, - stdin=subprocess.PIPE, - stderr=subprocess.PIPE, - stdout=subprocess.PIPE) - process.stdin.write(code.encode('UTF-8')) - process.stdin.close() ##? - output = '' - fail = False - while True: - try: - c = process.stdout.read(1).decode() - except IOError as err: - if err.errno == errno.EINTR: - # Interrupted system call; just try again. - c = '' - else: - raise - output += c - - if output.endswith('test complete'): - break - if output.endswith('test failed'): - fail = True - break - time.sleep(1) - process.kill() - #res = process.communicate() - res = (process.stdout.read(), process.stderr.read()) - if fail or 'exception' in res[1].decode().lower() or 'error' in res[1].decode().lower(): - print(res[0].decode()) - print(res[1].decode()) - return False - return True - - # printing on travis ci frequently leads to "interrupted system call" errors. # as a workaround, we overwrite the built-in print function (bleh) if os.getenv('TRAVIS') is not None: @@ -124,9 +54,9 @@ for frontend in frontends.keys(): installed = sorted([frontend for frontend, isPresent in frontends.items() if isPresent]) -# keep a dictionary of example files and their non-standard dependencies -specialExamples = { - "hdf5.py": ["h5py"] +exceptionCondition = namedtuple("exceptionCondition", ["condition", "reason"]) +conditionalExampleTests = { + "hdf5.py": exceptionCondition(False, reason="Example requires user interaction and is not suitable for testing") } @@ -136,15 +66,84 @@ specialExamples = { pytest.param( frontend, f, - marks=pytest.mark.skipif(any(pkgutil.find_loader(pkg) is None for pkg in specialExamples[f[1]]), - reason="Skipping Example for Missing Dependencies") if f[1] in specialExamples.keys() else (), + marks=pytest.mark.skipif(conditionalExampleTests[f[1]].condition is False, + reason=conditionalExampleTests[f[1]].reason) if f[1] in conditionalExampleTests.keys() else (), ) for frontend, f, in itertools.product(installed, files) ], ids = [" {} - {} ".format(f[1], frontend) for frontend, f in itertools.product(installed, files)] ) -def testExamples(frontend, f): - assert runExampleFile(f[0], f[1], sys.executable, frontend) +def testExamples(frontend, f, graphicsSystem=None): + # runExampleFile(f[0], f[1], sys.executable, frontend) + + name, file = f + global path + fn = os.path.join(path,file) + os.chdir(path) + sys.stdout.write("{} ".format(name)) + sys.stdout.flush() + import1 = "import %s" % frontend if frontend != '' else '' + import2 = os.path.splitext(os.path.split(fn)[1])[0] + graphicsSystem = '' if graphicsSystem is None else "pg.QtGui.QApplication.setGraphicsSystem('%s')" % graphicsSystem + code = """ +try: + %s + import initExample + import pyqtgraph as pg + %s + import %s + import sys + print("test complete") + sys.stdout.flush() + import time + while True: ## run a little event loop + pg.QtGui.QApplication.processEvents() + time.sleep(0.01) +except: + print("test failed") + raise + +""" % (import1, graphicsSystem, import2) + if sys.platform.startswith('win'): + process = subprocess.Popen([sys.executable], + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE) + else: + process = subprocess.Popen(['exec %s -i' % (sys.executable)], + shell=True, + stdin=subprocess.PIPE, + stderr=subprocess.PIPE, + stdout=subprocess.PIPE) + process.stdin.write(code.encode('UTF-8')) + process.stdin.close() ##? + output = '' + fail = False + while True: + try: + c = process.stdout.read(1).decode() + except IOError as err: + if err.errno == errno.EINTR: + # Interrupted system call; just try again. + c = '' + else: + raise + output += c + + if output.endswith('test complete'): + break + if output.endswith('test failed'): + fail = True + break + time.sleep(1) + process.kill() + #res = process.communicate() + res = (process.stdout.read(), process.stderr.read()) + if fail or 'exception' in res[1].decode().lower() or 'error' in res[1].decode().lower(): + print(res[0].decode()) + print(res[1].decode()) + pytest.fail("{}\n{}\nFailed {} Example Test Located in {} ".format(res[0].decode(), res[1].decode(), name, file), pytrace=False) + assert True if __name__ == "__main__": pytest.cmdline.main()