diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 83924218..601b1136 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -40,11 +40,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v2 - - name: Checkout test-data - uses: actions/checkout@v2 - with: - repository: pyqtgraph/test-data - path: .pyqtgraph/test-data - name: Setup Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: @@ -106,7 +101,7 @@ jobs: - name: Run Tests run: | mkdir $SCREENSHOT_DIR - pytest pyqtgraph examples -v \ + pytest tests examples -v \ --junitxml pytest.xml \ shell: bash - name: Upload Screenshots diff --git a/pyqtgraph/functions.py b/pyqtgraph/functions.py index 6abfecce..2926063d 100644 --- a/pyqtgraph/functions.py +++ b/pyqtgraph/functions.py @@ -1511,17 +1511,10 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True): return ndarray_to_qimage(imgData, imgFormat) -def imageToArray(img, copy=False, transpose=True): - """ - Convert a QImage into numpy array. The image must have format RGB32, ARGB32, or ARGB32_Premultiplied. - By default, the image is not copied; changes made to the array will appear in the QImage as well (beware: if - the QImage is collected before the array, there may be trouble). - The array will have shape (width, height, (b,g,r,a)). - """ - fmt = img.format() - img_ptr = img.bits() +def qimage_to_ndarray(qimg): + img_ptr = qimg.bits() - if QT_LIB.startswith('PyQt'): + if hasattr(img_ptr, 'setsize'): # PyQt sip.voidptr # sizeInBytes() was introduced in Qt 5.10 # however PyQt5 5.12 will fail with: # "TypeError: QImage.sizeInBytes() is a private method" @@ -1529,14 +1522,37 @@ def imageToArray(img, copy=False, transpose=True): # PyQt5 5.15, PySide2 5.12, PySide2 5.15 try: # 64-bits size - nbytes = img.sizeInBytes() + nbytes = qimg.sizeInBytes() except (TypeError, AttributeError): # 32-bits size - nbytes = img.byteCount() + nbytes = qimg.byteCount() img_ptr.setsize(nbytes) - arr = np.frombuffer(img_ptr, dtype=np.ubyte) - arr = arr.reshape(img.height(), img.width(), 4) + depth = qimg.depth() + if depth in (8, 24, 32): + dtype = np.uint8 + nchan = depth // 8 + elif depth in (16, 64): + dtype = np.uint16 + nchan = depth // 16 + else: + raise ValueError("Unsupported Image Type") + shape = qimg.height(), qimg.width() + if nchan != 1: + shape = shape + (nchan,) + return np.frombuffer(img_ptr, dtype=dtype).reshape(shape) + + +def imageToArray(img, copy=False, transpose=True): + """ + Convert a QImage into numpy array. The image must have format RGB32, ARGB32, or ARGB32_Premultiplied. + By default, the image is not copied; changes made to the array will appear in the QImage as well (beware: if + the QImage is collected before the array, there may be trouble). + The array will have shape (width, height, (b,g,r,a)). + """ + arr = qimage_to_ndarray(img) + + fmt = img.format() if fmt == img.Format_RGB32: arr[...,3] = 255 diff --git a/pyqtgraph/graphicsItems/PlotItem/tests/__init__.py b/pyqtgraph/graphicsItems/PlotItem/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/pytest.ini b/pytest.ini index 550a2faa..f7244778 100644 --- a/pytest.ini +++ b/pytest.ini @@ -4,7 +4,7 @@ xvfb_height = 1080 # use this due to some issues with ndarray reshape errors on CI systems xvfb_colordepth = 24 xvfb_args=-ac +extension GLX +render -faulthandler_timeout = 30 +faulthandler_timeout = 60 filterwarnings = # re-enable standard library warnings diff --git a/pyqtgraph/tests/__init__.py b/tests/__init__.py similarity index 100% rename from pyqtgraph/tests/__init__.py rename to tests/__init__.py diff --git a/pyqtgraph/tests/conftest.py b/tests/conftest.py similarity index 100% rename from pyqtgraph/tests/conftest.py rename to tests/conftest.py diff --git a/pyqtgraph/dockarea/tests/test_dock.py b/tests/dockarea/test_dock.py similarity index 100% rename from pyqtgraph/dockarea/tests/test_dock.py rename to tests/dockarea/test_dock.py diff --git a/pyqtgraph/dockarea/tests/test_dockarea.py b/tests/dockarea/test_dockarea.py similarity index 100% rename from pyqtgraph/dockarea/tests/test_dockarea.py rename to tests/dockarea/test_dockarea.py diff --git a/pyqtgraph/exporters/tests/__init__.py b/tests/exporters/__init__.py similarity index 100% rename from pyqtgraph/exporters/tests/__init__.py rename to tests/exporters/__init__.py diff --git a/pyqtgraph/exporters/tests/test_csv.py b/tests/exporters/test_csv.py similarity index 100% rename from pyqtgraph/exporters/tests/test_csv.py rename to tests/exporters/test_csv.py diff --git a/pyqtgraph/exporters/tests/test_hdf5.py b/tests/exporters/test_hdf5.py similarity index 100% rename from pyqtgraph/exporters/tests/test_hdf5.py rename to tests/exporters/test_hdf5.py diff --git a/pyqtgraph/exporters/tests/test_image.py b/tests/exporters/test_image.py similarity index 100% rename from pyqtgraph/exporters/tests/test_image.py rename to tests/exporters/test_image.py diff --git a/pyqtgraph/exporters/tests/test_matplotlib.py b/tests/exporters/test_matplotlib.py similarity index 100% rename from pyqtgraph/exporters/tests/test_matplotlib.py rename to tests/exporters/test_matplotlib.py diff --git a/pyqtgraph/exporters/tests/test_svg.py b/tests/exporters/test_svg.py similarity index 100% rename from pyqtgraph/exporters/tests/test_svg.py rename to tests/exporters/test_svg.py diff --git a/pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py b/tests/graphicsItems/PlotItem/test_PlotItem.py similarity index 100% rename from pyqtgraph/graphicsItems/PlotItem/tests/test_PlotItem.py rename to tests/graphicsItems/PlotItem/test_PlotItem.py diff --git a/pyqtgraph/graphicsItems/ViewBox/tests/test_ViewBox.py b/tests/graphicsItems/ViewBox/test_ViewBox.py similarity index 100% rename from pyqtgraph/graphicsItems/ViewBox/tests/test_ViewBox.py rename to tests/graphicsItems/ViewBox/test_ViewBox.py diff --git a/pyqtgraph/graphicsItems/ViewBox/tests/test_ViewBoxZoom.py b/tests/graphicsItems/ViewBox/test_ViewBoxZoom.py similarity index 100% rename from pyqtgraph/graphicsItems/ViewBox/tests/test_ViewBoxZoom.py rename to tests/graphicsItems/ViewBox/test_ViewBoxZoom.py diff --git a/pyqtgraph/graphicsItems/tests/test_ArrowItem.py b/tests/graphicsItems/test_ArrowItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_ArrowItem.py rename to tests/graphicsItems/test_ArrowItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_AxisItem.py b/tests/graphicsItems/test_AxisItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_AxisItem.py rename to tests/graphicsItems/test_AxisItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_ErrorBarItem.py b/tests/graphicsItems/test_ErrorBarItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_ErrorBarItem.py rename to tests/graphicsItems/test_ErrorBarItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_GraphicsItem.py b/tests/graphicsItems/test_GraphicsItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_GraphicsItem.py rename to tests/graphicsItems/test_GraphicsItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_ImageItem.py b/tests/graphicsItems/test_ImageItem.py similarity index 99% rename from pyqtgraph/graphicsItems/tests/test_ImageItem.py rename to tests/graphicsItems/test_ImageItem.py index cc9b45f5..01a9f88d 100644 --- a/pyqtgraph/graphicsItems/tests/test_ImageItem.py +++ b/tests/graphicsItems/test_ImageItem.py @@ -5,7 +5,7 @@ import pytest from pyqtgraph.Qt import QtCore, QtGui, QtTest import numpy as np import pyqtgraph as pg -from pyqtgraph.tests import assertImageApproved, TransposedImageItem +from tests.image_testing import assertImageApproved, TransposedImageItem try: import cupy except ImportError: diff --git a/pyqtgraph/graphicsItems/tests/test_ImageItemFormat.py b/tests/graphicsItems/test_ImageItemFormat.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_ImageItemFormat.py rename to tests/graphicsItems/test_ImageItemFormat.py diff --git a/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py b/tests/graphicsItems/test_InfiniteLine.py similarity index 98% rename from pyqtgraph/graphicsItems/tests/test_InfiniteLine.py rename to tests/graphicsItems/test_InfiniteLine.py index be3cb460..2e6ec8bc 100644 --- a/pyqtgraph/graphicsItems/tests/test_InfiniteLine.py +++ b/tests/graphicsItems/test_InfiniteLine.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore, QtTest -from pyqtgraph.tests import mouseDrag, mouseMove +from tests.ui_testing import mouseDrag, mouseMove pg.mkQApp() diff --git a/pyqtgraph/graphicsItems/tests/test_LegendItem.py b/tests/graphicsItems/test_LegendItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_LegendItem.py rename to tests/graphicsItems/test_LegendItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py b/tests/graphicsItems/test_NonUniformImage.py similarity index 94% rename from pyqtgraph/graphicsItems/tests/test_NonUniformImage.py rename to tests/graphicsItems/test_NonUniformImage.py index 52b7c989..5b46a7d5 100644 --- a/pyqtgraph/graphicsItems/tests/test_NonUniformImage.py +++ b/tests/graphicsItems/test_NonUniformImage.py @@ -2,7 +2,7 @@ import numpy as np import pyqtgraph as pg from pyqtgraph.Qt import QtTest from pyqtgraph.graphicsItems.NonUniformImage import NonUniformImage -from pyqtgraph.tests import assertImageApproved +from tests.image_testing import assertImageApproved from pyqtgraph.colormap import ColorMap import pyqtgraph.functions as fn import pytest @@ -93,7 +93,7 @@ def test_NonUniformImage_colormap(): image = NonUniformImage(x, y, Z, border=fn.mkPen('g')) - cmap = ColorMap(pos=[0.0, 1.0], color=[(0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0, 1.0)]) + cmap = ColorMap(pos=[0.0, 1.0], color=[(0, 0, 0), (255, 255, 255)]) image.setColorMap(cmap) viewbox.addItem(image) diff --git a/pyqtgraph/graphicsItems/tests/test_PlotCurveItem.py b/tests/graphicsItems/test_PlotCurveItem.py similarity index 95% rename from pyqtgraph/graphicsItems/tests/test_PlotCurveItem.py rename to tests/graphicsItems/test_PlotCurveItem.py index 80dee478..ab807721 100644 --- a/pyqtgraph/graphicsItems/tests/test_PlotCurveItem.py +++ b/tests/graphicsItems/test_PlotCurveItem.py @@ -1,6 +1,6 @@ import numpy as np import pyqtgraph as pg -from pyqtgraph.tests import assertImageApproved +from tests.image_testing import assertImageApproved def test_PlotCurveItem(): diff --git a/pyqtgraph/graphicsItems/tests/test_PlotDataItem.py b/tests/graphicsItems/test_PlotDataItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_PlotDataItem.py rename to tests/graphicsItems/test_PlotDataItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_ROI.py b/tests/graphicsItems/test_ROI.py similarity index 92% rename from pyqtgraph/graphicsItems/tests/test_ROI.py rename to tests/graphicsItems/test_ROI.py index 044c178b..cb689749 100644 --- a/pyqtgraph/graphicsItems/tests/test_ROI.py +++ b/tests/graphicsItems/test_ROI.py @@ -3,9 +3,10 @@ import sys import numpy as np import pytest import pyqtgraph as pg +import platform from pyqtgraph.Qt import QtCore, QtGui, QtTest -from pyqtgraph.tests import assertImageApproved, mouseMove, mouseDrag, mouseClick, TransposedImageItem, resizeWindow -import pytest +from tests.image_testing import assertImageApproved +from tests.ui_testing import mouseMove, mouseDrag, mouseClick, resizeWindow app = pg.mkQApp() pg.setConfigOption("mouseRateLimit", 0) @@ -39,17 +40,20 @@ def test_getArrayRegion_axisorder(): def check_getArrayRegion(roi, name, testResize=True, transpose=False): + # on windows, edges corner pixels seem to be slightly different from other platforms + # giving a pxCount=2 for a fudge factor + if isinstance(roi, (pg.ROI, pg.RectROI)) and platform.system() == "Windows": + pxCount = 2 + else: + pxCount=-1 + + initState = roi.getState() - #win = pg.GraphicsLayoutWidget() win = pg.GraphicsView() win.show() resizeWindow(win, 200, 400) - # Don't use Qt's layouts for testing--these generate unpredictable results. - #vb1 = win.addViewBox() - #win.nextRow() - #vb2 = win.addViewBox() - + # Don't use Qt's layouts for testing--these generate unpredictable results. # Instead, place the viewboxes manually vb1 = pg.ViewBox() win.scene().addItem(vb1) @@ -97,7 +101,7 @@ def check_getArrayRegion(roi, name, testResize=True, transpose=False): vb2.enableAutoRange(True, True) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion', 'Simple ROI region selection.') + assertImageApproved(win, name+'/roi_getarrayregion', 'Simple ROI region selection.', pxCount=pxCount) with pytest.raises(TypeError): roi.setPos(0, False) @@ -106,38 +110,33 @@ def check_getArrayRegion(roi, name, testResize=True, transpose=False): rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion_halfpx', 'Simple ROI region selection, 0.5 pixel shift.') + assertImageApproved(win, name+'/roi_getarrayregion_halfpx', 'Simple ROI region selection, 0.5 pixel shift.', pxCount=pxCount) roi.setAngle(45) roi.setPos([3, 0]) rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion_rotate', 'Simple ROI region selection, rotation.') + assertImageApproved(win, name+'/roi_getarrayregion_rotate', 'Simple ROI region selection, rotation.', pxCount=pxCount) if testResize: roi.setSize([60, 60]) rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion_resize', 'Simple ROI region selection, resized.') + assertImageApproved(win, name+'/roi_getarrayregion_resize', 'Simple ROI region selection, resized.', pxCount=pxCount) img1.setPos(0, img1.height()) img1.setTransform(QtGui.QTransform().scale(1, -1).rotate(20), True) rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion_img_trans', 'Simple ROI region selection, image transformed.') + assertImageApproved(win, name+'/roi_getarrayregion_img_trans', 'Simple ROI region selection, image transformed.', pxCount=pxCount) vb1.invertY() rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - # on windows, one edge of one ROI handle is shifted slightly; letting this slide with pxCount=10 - if pg.Qt.QT_LIB in {'PyQt4', 'PySide'}: - pxCount = 10 - else: - pxCount=-1 assertImageApproved(win, name+'/roi_getarrayregion_inverty', 'Simple ROI region selection, view inverted.', pxCount=pxCount) roi.setState(initState) @@ -146,7 +145,7 @@ def check_getArrayRegion(roi, name, testResize=True, transpose=False): rgn = roi.getArrayRegion(data, img1, axes=(1, 2)) img2.setImage(rgn[0, ..., 0]) app.processEvents() - assertImageApproved(win, name+'/roi_getarrayregion_anisotropic', 'Simple ROI region selection, image scaled anisotropically.') + assertImageApproved(win, name+'/roi_getarrayregion_anisotropic', 'Simple ROI region selection, image scaled anisotropically.', pxCount=pxCount) # allow the roi to be re-used roi.scene().removeItem(roi) diff --git a/pyqtgraph/graphicsItems/tests/test_ScatterPlotItem.py b/tests/graphicsItems/test_ScatterPlotItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_ScatterPlotItem.py rename to tests/graphicsItems/test_ScatterPlotItem.py diff --git a/pyqtgraph/graphicsItems/tests/test_TextItem.py b/tests/graphicsItems/test_TextItem.py similarity index 100% rename from pyqtgraph/graphicsItems/tests/test_TextItem.py rename to tests/graphicsItems/test_TextItem.py diff --git a/pyqtgraph/tests/image_testing.py b/tests/image_testing.py similarity index 54% rename from pyqtgraph/tests/image_testing.py rename to tests/image_testing.py index e64df55e..54dd4901 100644 --- a/pyqtgraph/tests/image_testing.py +++ b/tests/image_testing.py @@ -3,68 +3,32 @@ """ Procedure for unit-testing with images: -1. Run unit tests at least once; this initializes a git clone of - pyqtgraph/test-data in ~/.pyqtgraph. - -2. Run individual test scripts with the PYQTGRAPH_AUDIT environment variable set: + Run individual test scripts with the PYQTGRAPH_AUDIT environment variable set: $ PYQTGRAPH_AUDIT=1 python pyqtgraph/graphicsItems/tests/test_PlotCurveItem.py - Any failing tests will display the test results, standard image, and the - differences between the two. If the test result is bad, then press (f)ail. - If the test result is good, then press (p)ass and the new image will be - saved to the test-data directory. - - To check all test results regardless of whether the test failed, set the - environment variable PYQTGRAPH_AUDIT_ALL=1. - -3. After adding or changing test images, create a new commit: - - $ cd ~/.pyqtgraph/test-data - $ git add ... - $ git commit -a - -4. Look up the most recent tag name from the `testDataTag` global variable - below. Increment the tag name by 1 and create a new tag in the test-data - repository: - - $ git tag test-data-NNN - $ git push --tags origin master - - This tag is used to ensure that each pyqtgraph commit is linked to a specific - commit in the test-data repository. This makes it possible to push new - commits to the test-data repository without interfering with existing - tests, and also allows unit tests to continue working on older pyqtgraph - versions. + Any failing tests will display the test results, standard image, and the + differences between the two. If the test result is bad, then press (f)ail. + If the test result is good, then press (p)ass and the new image will be + saved to the test-data directory. + To check all test results regardless of whether the test failed, set the + environment variable PYQTGRAPH_AUDIT_ALL=1. """ - -# This is the name of a tag in the test-data repository that this version of -# pyqtgraph should be tested against. When adding or changing test images, -# create and push a new tag and update this variable. To test locally, begin -# by creating the tag in your ~/.pyqtgraph/test-data repository. -testDataTag = 'test-data-8' - - import time import os import sys import inspect -import base64 -import subprocess as sp +import warnings import numpy as np -if sys.version[0] >= '3': - import http.client as httplib - import urllib.parse as urllib -else: - import httplib - import urllib -from ..Qt import QtGui, QtCore, QtTest, QT_LIB -from .. import functions as fn -from .. import GraphicsLayoutWidget -from .. import ImageItem, TextItem +from pathlib import Path + +from pyqtgraph.Qt import QtGui, QtCore +from pyqtgraph import functions as fn +from pyqtgraph import GraphicsLayoutWidget +from pyqtgraph import ImageItem, TextItem tester = None @@ -101,6 +65,21 @@ def getTester(): return tester +def getImageFromWidget(widget): + + # just to be sure the widget size is correct (new window may be resized): + QtGui.QApplication.processEvents() + + qimg = QtGui.QImage(widget.size(), QtGui.QImage.Format.Format_ARGB32) + qimg.fill(QtCore.Qt.GlobalColor.transparent) + painter = QtGui.QPainter(qimg) + widget.render(painter) + painter.end() + + qimg = qimg.convertToFormat(QtGui.QImage.Format.Format_RGBA8888) + return fn.qimage_to_ndarray(qimg).copy() + + def assertImageApproved(image, standardFile, message=None, **kwargs): """Check that an image test result matches a pre-approved standard. @@ -108,10 +87,6 @@ def assertImageApproved(image, standardFile, message=None, **kwargs): to compare the images and decide whether to fail the test or save the new image as the standard. - This function will automatically clone the test-data repository into - ~/.pyqtgraph/test-data. However, it is up to the user to ensure this repository - is kept up to date and to commit/push new images after they are saved. - Run the test with the environment variable PYQTGRAPH_AUDIT=1 to bring up the auditing GUI. @@ -131,43 +106,28 @@ def assertImageApproved(image, standardFile, message=None, **kwargs): comparison (see ``assertImageMatch()``). """ if isinstance(image, QtGui.QWidget): - w = image - - # just to be sure the widget size is correct (new window may be resized): + # just to be sure the widget size is correct (new window may be resized): QtGui.QApplication.processEvents() - graphstate = scenegraphState(w, standardFile) - qimg = QtGui.QImage(w.size(), QtGui.QImage.Format.Format_ARGB32) - qimg.fill(QtCore.Qt.GlobalColor.transparent) - painter = QtGui.QPainter(qimg) - w.render(painter) - painter.end() - - image = fn.imageToArray(qimg, copy=False, transpose=False) - - # the standard images seem to have their Red and Blue swapped - if sys.byteorder == 'little': - # transpose B,G,R,A to R,G,B,A - image = image[..., [2, 1, 0, 3]] - else: - # transpose A,R,G,B to A,B,G,R - image = image[..., [0, 3, 2, 1]] + graphstate = scenegraphState(image, standardFile) + image = getImageFromWidget(image) if message is None: code = inspect.currentframe().f_back.f_code message = "%s::%s" % (code.co_filename, code.co_name) - # Make sure we have a test data repo available, possibly invoking git - dataPath = getTestDataRepo() + # Make sure we have a test data repo available + dataPath = getTestDataDirectory() # Read the standard image if it exists stdFileName = os.path.join(dataPath, standardFile + '.png') if not os.path.isfile(stdFileName): stdImage = None else: - pxm = QtGui.QPixmap() - pxm.load(stdFileName) - stdImage = fn.imageToArray(pxm.toImage(), copy=True, transpose=False) + qimg = QtGui.QImage(stdFileName) + qimg = qimg.convertToFormat(QtGui.QImage.Format.Format_RGBA8888) + stdImage = fn.qimage_to_ndarray(qimg).copy() + del qimg # If the test image does not match, then we go to audit if requested. try: @@ -191,18 +151,13 @@ def assertImageApproved(image, standardFile, message=None, **kwargs): image = fn.downsample(image, sr[0], axis=(0, 1)).astype(image.dtype) assertImageMatch(image, stdImage, **kwargs) - + if bool(os.getenv('PYQTGRAPH_PRINT_TEST_STATE', False)): print(graphstate) - + if os.getenv('PYQTGRAPH_AUDIT_ALL') == '1': raise Exception("Image test passed, but auditing due to PYQTGRAPH_AUDIT_ALL evnironment variable.") except Exception: - - if stdFileName in gitStatus(dataPath): - print("\n\nWARNING: unit test failed against modified standard " - "image %s.\nTo revert this file, run `cd %s; git checkout " - "%s`\n" % (stdFileName, dataPath, standardFile)) if os.getenv('PYQTGRAPH_AUDIT') == '1' or os.getenv('PYQTGRAPH_AUDIT_ALL') == '1': sys.excepthook(*sys.exc_info()) getTester().test(image, stdImage, message) @@ -210,20 +165,18 @@ def assertImageApproved(image, standardFile, message=None, **kwargs): print('Saving new standard image to "%s"' % stdFileName) if not os.path.isdir(stdPath): os.makedirs(stdPath) - img = fn.makeQImage(image, alpha=True, transpose=False) - img.save(stdFileName) + qimg = fn.ndarray_to_qimage(image, QtGui.QImage.Format.Format_RGBA8888) + qimg.save(stdFileName) + del qimg else: if stdImage is None: raise Exception("Test standard %s does not exist. Set " "PYQTGRAPH_AUDIT=1 to add this image." % stdFileName) - else: - if os.getenv('TRAVIS') is not None: - saveFailedTest(image, stdImage, standardFile, upload=True) - elif os.getenv('CI') is not None: - standardFile = os.path.join(os.getenv("SCREENSHOT_DIR", "screenshots"), standardFile) - saveFailedTest(image, stdImage, standardFile) - print(graphstate) - raise + if os.getenv('CI') is not None: + standardFile = os.path.join(os.getenv("SCREENSHOT_DIR", "screenshots"), standardFile) + saveFailedTest(image, stdImage, standardFile) + print(graphstate) + raise def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50., @@ -249,8 +202,8 @@ def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50., pxThreshold : float Minimum value difference at which two pixels are considered different pxCount : int or None - Maximum number of pixels that may differ. Default is 0 for Qt4 and - 1% of image size for Qt5. + Maximum number of pixels that may differ. Default is 0, on Windows some + tests have a value of 2. maxPxDiff : float or None Maximum allowed difference between pixels avgPxDiff : float or None @@ -264,12 +217,7 @@ def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50., assert im1.dtype == im2.dtype if pxCount == -1: - if QT_LIB in {'PyQt5', 'PySide2', 'PySide6', 'PyQt6'}: - # Qt5 generates slightly different results; relax the tolerance - # until test images are updated. - pxCount = int(im1.shape[0] * im1.shape[1] * 0.01) - else: - pxCount = 0 + pxCount = 0 diff = im1.astype(float) - im2.astype(float) if imgDiff is not None: @@ -292,9 +240,7 @@ def assertImageMatch(im1, im2, minCorr=None, pxThreshold=50., assert corr >= minCorr -def saveFailedTest(data, expect, filename, upload=False): - """Upload failed test images to web server to allow CI test debugging. - """ +def saveFailedTest(data, expect, filename): # concatenate data, expect, and diff into a single image ds = data.shape es = expect.shape @@ -310,7 +256,7 @@ def saveFailedTest(data, expect, filename, upload=False): diff = makeDiffImage(data, expect) img[2:2+diff.shape[0], -diff.shape[1]-2:-2] = diff - png = makePng(img) + png = makePng(data) # change `img` to `data` to save just the failed image directory = os.path.dirname(filename) if not os.path.isdir(directory): os.makedirs(directory) @@ -318,38 +264,15 @@ def saveFailedTest(data, expect, filename, upload=False): png_file.write(png) print("\nImage comparison failed. Test result: %s %s Expected result: " "%s %s" % (data.shape, data.dtype, expect.shape, expect.dtype)) - if upload: - uploadFailedTest(filename, png) - - -def uploadFailedTest(filename, png): - commit = runSubprocess(['git', 'rev-parse', 'HEAD']) - name = filename.split(os.path.sep) - name.insert(-1, commit.strip()) - filename = os.path.sep.join(name) - - host = 'data.pyqtgraph.org' - conn = httplib.HTTPConnection(host) - req = urllib.urlencode({'name': filename, - 'data': base64.b64encode(png)}) - conn.request('POST', '/upload.py', req) - response = conn.getresponse().read() - conn.close() - - print("Uploaded to: \nhttp://%s/data/%s" % (host, filename)) - if not response.startswith(b'OK'): - print("WARNING: Error uploading data to %s" % host) - print(response) def makePng(img): """Given an array like (H, W, 4), return a PNG-encoded byte string. """ io = QtCore.QBuffer() - qim = fn.makeQImage(img.transpose(1, 0, 2), alpha=False) + qim = fn.ndarray_to_qimage(img, QtGui.QImage.Format.Format_RGBX8888) qim.save(io, 'PNG') - png = bytes(io.data().data()) - return png + return bytes(io.data().data()) def makeDiffImage(im1, im2): @@ -467,155 +390,18 @@ class ImageTester(QtGui.QWidget): def getTestDataRepo(): - """Return the path to a git repository with the required commit checked - out. - - If the repository does not exist, then it is cloned from - https://github.com/pyqtgraph/test-data. If the repository already exists - then the required commit is checked out. - """ - global testDataTag - - if os.getenv("CI"): - dataPath = os.path.join(os.environ["GITHUB_WORKSPACE"], '.pyqtgraph', 'test-data') - else: - dataPath = os.path.join(os.path.expanduser('~'), '.pyqtgraph', 'test-data') - gitPath = 'https://github.com/pyqtgraph/test-data' - gitbase = gitCmdBase(dataPath) - - if os.path.isdir(dataPath): - # Already have a test-data repository to work with. - - # Get the commit ID of testDataTag. Do a fetch if necessary. - try: - tagCommit = gitCommitId(dataPath, testDataTag) - except NameError: - cmd = gitbase + ['fetch', '--tags', 'origin'] - print(' '.join(cmd)) - sp.check_call(cmd) - try: - tagCommit = gitCommitId(dataPath, testDataTag) - except NameError: - raise Exception("Could not find tag '%s' in test-data repo at" - " %s" % (testDataTag, dataPath)) - except Exception: - if not os.path.exists(os.path.join(dataPath, '.git')): - raise Exception("Directory '%s' does not appear to be a git " - "repository. Please remove this directory." % - dataPath) - else: - raise - - # If HEAD is not the correct commit, then do a checkout - if gitCommitId(dataPath, 'HEAD') != tagCommit: - print("Checking out test-data tag '%s'" % testDataTag) - sp.check_call(gitbase + ['checkout', testDataTag]) - - else: - print("Attempting to create git clone of test data repo in %s.." % - dataPath) - - parentPath = os.path.split(dataPath)[0] - if not os.path.isdir(parentPath): - os.makedirs(parentPath) - - if os.getenv('TRAVIS') is not None or os.getenv('CI') is not None: - # Create a shallow clone of the test-data repository (to avoid - # downloading more data than is necessary) - os.makedirs(dataPath) - cmds = [ - gitbase + ['init'], - gitbase + ['remote', 'add', 'origin', gitPath], - gitbase + ['fetch', '--tags', 'origin', testDataTag, - '--depth=1'], - gitbase + ['checkout', '-b', 'master', 'FETCH_HEAD'], - ] - else: - # Create a full clone - cmds = [['git', 'clone', gitPath, dataPath]] - - for cmd in cmds: - print(' '.join(cmd)) - rval = sp.check_call(cmd) - if rval == 0: - continue - raise RuntimeError("Test data path '%s' does not exist and could " - "not be created with git. Please create a git " - "clone of %s at this path." % - (dataPath, gitPath)) - - return dataPath + warnings.warn( + "Test data data repo has been merged with the main repo" + "use getTestDataDirectory() instead, this method will be removed" + "in a future version of pyqtgraph", + DeprecationWarning, stacklevel=2 + ) + return getTestDataDirectory() -def gitCmdBase(path): - return ['git', '--git-dir=%s/.git' % path, '--work-tree=%s' % path] - - -def gitStatus(path): - """Return a string listing all changes to the working tree in a git - repository. - """ - cmd = gitCmdBase(path) + ['status', '--porcelain'] - return runSubprocess(cmd, stderr=None, universal_newlines=True) - - -def gitCommitId(path, ref): - """Return the commit id of *ref* in the git repository at *path*. - """ - cmd = gitCmdBase(path) + ['show', ref] - try: - output = runSubprocess(cmd, stderr=None, universal_newlines=True) - except sp.CalledProcessError: - print(cmd) - raise NameError("Unknown git reference '%s'" % ref) - commit = output.split('\n')[0] - assert commit[:7] == 'commit ' - return commit[7:] - - -def runSubprocess(command, return_code=False, **kwargs): - """Run command using subprocess.Popen - - Similar to subprocess.check_output(), which is not available in 2.6. - - Run command and wait for command to complete. If the return code was zero - then return, otherwise raise CalledProcessError. - By default, this will also add stdout= and stderr=subproces.PIPE - to the call to Popen to suppress printing to the terminal. - - Parameters - ---------- - command : list of str - Command to run as subprocess (see subprocess.Popen documentation). - **kwargs : dict - Additional kwargs to pass to ``subprocess.Popen``. - - Returns - ------- - stdout : str - Stdout returned by the process. - """ - # code adapted with permission from mne-python - use_kwargs = dict(stderr=None, stdout=sp.PIPE) - use_kwargs.update(kwargs) - - p = sp.Popen(command, **use_kwargs) - output = p.communicate()[0] - - # communicate() may return bytes, str, or None depending on the kwargs - # passed to Popen(). Convert all to unicode str: - output = '' if output is None else output - output = output.decode('utf-8') if isinstance(output, bytes) else output - - if p.returncode != 0: - print(output) - err_fun = sp.CalledProcessError.__init__ - if 'output' in inspect.getfullargspec(err_fun).args: - raise sp.CalledProcessError(p.returncode, command, output) - else: - raise sp.CalledProcessError(p.returncode, command) - - return output +def getTestDataDirectory(): + dataPath = Path(__file__).absolute().parent / "images" + return dataPath.as_posix() def scenegraphState(view, name): @@ -632,7 +418,7 @@ def scenegraphState(view, name): def itemState(root): state = str(root) + '\n' - from .. import ViewBox + from pyqtgraph import ViewBox state += 'bounding rect: ' + str(root.boundingRect()) + '\n' if isinstance(root, ViewBox): state += "view range: " + str(root.viewRange()) + '\n' @@ -647,7 +433,7 @@ def transformStr(t): def indent(s, pfx): - return '\n'.join([pfx+line for line in s.split('\n')]) + return '\n'.join(pfx+line for line in s.split('\n')) class TransposedImageItem(ImageItem): diff --git a/tests/images/imageitem/bool.png b/tests/images/imageitem/bool.png new file mode 100644 index 00000000..fb6e95af Binary files /dev/null and b/tests/images/imageitem/bool.png differ diff --git a/tests/images/imageitem/gradient_mono_byte.png b/tests/images/imageitem/gradient_mono_byte.png new file mode 100644 index 00000000..f86768c0 Binary files /dev/null and b/tests/images/imageitem/gradient_mono_byte.png differ diff --git a/tests/images/imageitem/gradient_mono_byte_levels.png b/tests/images/imageitem/gradient_mono_byte_levels.png new file mode 100644 index 00000000..86fc9a26 Binary files /dev/null and b/tests/images/imageitem/gradient_mono_byte_levels.png differ diff --git a/tests/images/imageitem/gradient_mono_int.png b/tests/images/imageitem/gradient_mono_int.png new file mode 100644 index 00000000..e3d79797 Binary files /dev/null and b/tests/images/imageitem/gradient_mono_int.png differ diff --git a/tests/images/imageitem/gradient_mono_int_levels.png b/tests/images/imageitem/gradient_mono_int_levels.png new file mode 100644 index 00000000..b35c666f Binary files /dev/null and b/tests/images/imageitem/gradient_mono_int_levels.png differ diff --git a/tests/images/imageitem/gradient_rgba_byte.png b/tests/images/imageitem/gradient_rgba_byte.png new file mode 100644 index 00000000..551a2ba5 Binary files /dev/null and b/tests/images/imageitem/gradient_rgba_byte.png differ diff --git a/tests/images/imageitem/gradient_rgba_byte_levels.png b/tests/images/imageitem/gradient_rgba_byte_levels.png new file mode 100644 index 00000000..939aa2fd Binary files /dev/null and b/tests/images/imageitem/gradient_rgba_byte_levels.png differ diff --git a/tests/images/imageitem/gradient_rgba_float.png b/tests/images/imageitem/gradient_rgba_float.png new file mode 100644 index 00000000..7ef8a888 Binary files /dev/null and b/tests/images/imageitem/gradient_rgba_float.png differ diff --git a/tests/images/imageitem/gradient_rgba_float_additive.png b/tests/images/imageitem/gradient_rgba_float_additive.png new file mode 100644 index 00000000..eb39dc50 Binary files /dev/null and b/tests/images/imageitem/gradient_rgba_float_additive.png differ diff --git a/tests/images/imageitem/gradient_rgba_float_alpha.png b/tests/images/imageitem/gradient_rgba_float_alpha.png new file mode 100644 index 00000000..233009f0 Binary files /dev/null and b/tests/images/imageitem/gradient_rgba_float_alpha.png differ diff --git a/tests/images/imageitem/init.png b/tests/images/imageitem/init.png new file mode 100644 index 00000000..f18796bd Binary files /dev/null and b/tests/images/imageitem/init.png differ diff --git a/tests/images/imageitem/levels1.png b/tests/images/imageitem/levels1.png new file mode 100644 index 00000000..b93ef9ca Binary files /dev/null and b/tests/images/imageitem/levels1.png differ diff --git a/tests/images/imageitem/lut.png b/tests/images/imageitem/lut.png new file mode 100644 index 00000000..81a17ee8 Binary files /dev/null and b/tests/images/imageitem/lut.png differ diff --git a/tests/images/imageitem/monochrome.png b/tests/images/imageitem/monochrome.png new file mode 100644 index 00000000..fb6e95af Binary files /dev/null and b/tests/images/imageitem/monochrome.png differ diff --git a/tests/images/imageitem/resolution_with_downsampling_x.png b/tests/images/imageitem/resolution_with_downsampling_x.png new file mode 100644 index 00000000..642de25c Binary files /dev/null and b/tests/images/imageitem/resolution_with_downsampling_x.png differ diff --git a/tests/images/imageitem/resolution_with_downsampling_y.png b/tests/images/imageitem/resolution_with_downsampling_y.png new file mode 100644 index 00000000..c3bf89bb Binary files /dev/null and b/tests/images/imageitem/resolution_with_downsampling_y.png differ diff --git a/tests/images/imageitem/resolution_without_downsampling.png b/tests/images/imageitem/resolution_without_downsampling.png new file mode 100644 index 00000000..aafaed5d Binary files /dev/null and b/tests/images/imageitem/resolution_without_downsampling.png differ diff --git a/tests/images/nonuniform_image/colormap-3x3.png b/tests/images/nonuniform_image/colormap-3x3.png new file mode 100644 index 00000000..b3d25b39 Binary files /dev/null and b/tests/images/nonuniform_image/colormap-3x3.png differ diff --git a/tests/images/nonuniform_image/lut-3x3.png b/tests/images/nonuniform_image/lut-3x3.png new file mode 100644 index 00000000..c8a9092b Binary files /dev/null and b/tests/images/nonuniform_image/lut-3x3.png differ diff --git a/tests/images/plotcurveitem/connectall.png b/tests/images/plotcurveitem/connectall.png new file mode 100644 index 00000000..09f798e3 Binary files /dev/null and b/tests/images/plotcurveitem/connectall.png differ diff --git a/tests/images/plotcurveitem/connectarray.png b/tests/images/plotcurveitem/connectarray.png new file mode 100644 index 00000000..7304df9c Binary files /dev/null and b/tests/images/plotcurveitem/connectarray.png differ diff --git a/tests/images/plotcurveitem/connectfinite.png b/tests/images/plotcurveitem/connectfinite.png new file mode 100644 index 00000000..57ad8dec Binary files /dev/null and b/tests/images/plotcurveitem/connectfinite.png differ diff --git a/tests/images/plotcurveitem/connectpairs.png b/tests/images/plotcurveitem/connectpairs.png new file mode 100644 index 00000000..255140b5 Binary files /dev/null and b/tests/images/plotcurveitem/connectpairs.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion.png b/tests/images/roi/baseroi/roi_getarrayregion.png new file mode 100644 index 00000000..440ebfdc Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_anisotropic.png b/tests/images/roi/baseroi/roi_getarrayregion_anisotropic.png new file mode 100644 index 00000000..ad0eaf2c Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_anisotropic.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_halfpx.png b/tests/images/roi/baseroi/roi_getarrayregion_halfpx.png new file mode 100644 index 00000000..e64976ae Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_halfpx.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_img_trans.png b/tests/images/roi/baseroi/roi_getarrayregion_img_trans.png new file mode 100644 index 00000000..e59ddec7 Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_img_trans.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_inverty.png b/tests/images/roi/baseroi/roi_getarrayregion_inverty.png new file mode 100644 index 00000000..a97fd068 Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_inverty.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_resize.png b/tests/images/roi/baseroi/roi_getarrayregion_resize.png new file mode 100644 index 00000000..5e82196d Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_resize.png differ diff --git a/tests/images/roi/baseroi/roi_getarrayregion_rotate.png b/tests/images/roi/baseroi/roi_getarrayregion_rotate.png new file mode 100644 index 00000000..eff9c64f Binary files /dev/null and b/tests/images/roi/baseroi/roi_getarrayregion_rotate.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion.png b/tests/images/roi/ellipseroi/roi_getarrayregion.png new file mode 100644 index 00000000..8bb1cfc7 Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_anisotropic.png b/tests/images/roi/ellipseroi/roi_getarrayregion_anisotropic.png new file mode 100644 index 00000000..1601298f Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_anisotropic.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_halfpx.png b/tests/images/roi/ellipseroi/roi_getarrayregion_halfpx.png new file mode 100644 index 00000000..88165740 Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_halfpx.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_img_trans.png b/tests/images/roi/ellipseroi/roi_getarrayregion_img_trans.png new file mode 100644 index 00000000..9ba008c7 Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_img_trans.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_inverty.png b/tests/images/roi/ellipseroi/roi_getarrayregion_inverty.png new file mode 100644 index 00000000..2b5b9703 Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_inverty.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_resize.png b/tests/images/roi/ellipseroi/roi_getarrayregion_resize.png new file mode 100644 index 00000000..604d733c Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_resize.png differ diff --git a/tests/images/roi/ellipseroi/roi_getarrayregion_rotate.png b/tests/images/roi/ellipseroi/roi_getarrayregion_rotate.png new file mode 100644 index 00000000..1f806959 Binary files /dev/null and b/tests/images/roi/ellipseroi/roi_getarrayregion_rotate.png differ diff --git a/tests/images/roi/polylineroi/closed_clear.png b/tests/images/roi/polylineroi/closed_clear.png new file mode 100644 index 00000000..052010fb Binary files /dev/null and b/tests/images/roi/polylineroi/closed_clear.png differ diff --git a/tests/images/roi/polylineroi/closed_click_segment.png b/tests/images/roi/polylineroi/closed_click_segment.png new file mode 100644 index 00000000..dba7d2cc Binary files /dev/null and b/tests/images/roi/polylineroi/closed_click_segment.png differ diff --git a/tests/images/roi/polylineroi/closed_drag_handle.png b/tests/images/roi/polylineroi/closed_drag_handle.png new file mode 100644 index 00000000..4a635d46 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_drag_handle.png differ diff --git a/tests/images/roi/polylineroi/closed_drag_new_handle.png b/tests/images/roi/polylineroi/closed_drag_new_handle.png new file mode 100644 index 00000000..ac08eac3 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_drag_new_handle.png differ diff --git a/tests/images/roi/polylineroi/closed_drag_roi.png b/tests/images/roi/polylineroi/closed_drag_roi.png new file mode 100644 index 00000000..9094dca2 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_drag_roi.png differ diff --git a/tests/images/roi/polylineroi/closed_hover_handle.png b/tests/images/roi/polylineroi/closed_hover_handle.png new file mode 100644 index 00000000..c596eb23 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_hover_handle.png differ diff --git a/tests/images/roi/polylineroi/closed_hover_roi.png b/tests/images/roi/polylineroi/closed_hover_roi.png new file mode 100644 index 00000000..e5357733 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_hover_roi.png differ diff --git a/tests/images/roi/polylineroi/closed_hover_segment.png b/tests/images/roi/polylineroi/closed_hover_segment.png new file mode 100644 index 00000000..ff15e582 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_hover_segment.png differ diff --git a/tests/images/roi/polylineroi/closed_init.png b/tests/images/roi/polylineroi/closed_init.png new file mode 100644 index 00000000..e99a6c58 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_init.png differ diff --git a/tests/images/roi/polylineroi/closed_setpoints.png b/tests/images/roi/polylineroi/closed_setpoints.png new file mode 100644 index 00000000..2f311140 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_setpoints.png differ diff --git a/tests/images/roi/polylineroi/closed_setstate.png b/tests/images/roi/polylineroi/closed_setstate.png new file mode 100644 index 00000000..e99a6c58 Binary files /dev/null and b/tests/images/roi/polylineroi/closed_setstate.png differ diff --git a/tests/images/roi/polylineroi/open_clear.png b/tests/images/roi/polylineroi/open_clear.png new file mode 100644 index 00000000..052010fb Binary files /dev/null and b/tests/images/roi/polylineroi/open_clear.png differ diff --git a/tests/images/roi/polylineroi/open_click_segment.png b/tests/images/roi/polylineroi/open_click_segment.png new file mode 100644 index 00000000..f99e663a Binary files /dev/null and b/tests/images/roi/polylineroi/open_click_segment.png differ diff --git a/tests/images/roi/polylineroi/open_drag_handle.png b/tests/images/roi/polylineroi/open_drag_handle.png new file mode 100644 index 00000000..50cfeed5 Binary files /dev/null and b/tests/images/roi/polylineroi/open_drag_handle.png differ diff --git a/tests/images/roi/polylineroi/open_drag_new_handle.png b/tests/images/roi/polylineroi/open_drag_new_handle.png new file mode 100644 index 00000000..f2aad0a7 Binary files /dev/null and b/tests/images/roi/polylineroi/open_drag_new_handle.png differ diff --git a/tests/images/roi/polylineroi/open_drag_roi.png b/tests/images/roi/polylineroi/open_drag_roi.png new file mode 100644 index 00000000..a3fe2d6a Binary files /dev/null and b/tests/images/roi/polylineroi/open_drag_roi.png differ diff --git a/tests/images/roi/polylineroi/open_hover_handle.png b/tests/images/roi/polylineroi/open_hover_handle.png new file mode 100644 index 00000000..93f0f786 Binary files /dev/null and b/tests/images/roi/polylineroi/open_hover_handle.png differ diff --git a/tests/images/roi/polylineroi/open_hover_roi.png b/tests/images/roi/polylineroi/open_hover_roi.png new file mode 100644 index 00000000..23edb196 Binary files /dev/null and b/tests/images/roi/polylineroi/open_hover_roi.png differ diff --git a/tests/images/roi/polylineroi/open_hover_segment.png b/tests/images/roi/polylineroi/open_hover_segment.png new file mode 100644 index 00000000..53c6df6c Binary files /dev/null and b/tests/images/roi/polylineroi/open_hover_segment.png differ diff --git a/tests/images/roi/polylineroi/open_init.png b/tests/images/roi/polylineroi/open_init.png new file mode 100644 index 00000000..38cf15d6 Binary files /dev/null and b/tests/images/roi/polylineroi/open_init.png differ diff --git a/tests/images/roi/polylineroi/open_setpoints.png b/tests/images/roi/polylineroi/open_setpoints.png new file mode 100644 index 00000000..5c2d5931 Binary files /dev/null and b/tests/images/roi/polylineroi/open_setpoints.png differ diff --git a/tests/images/roi/polylineroi/open_setstate.png b/tests/images/roi/polylineroi/open_setstate.png new file mode 100644 index 00000000..38cf15d6 Binary files /dev/null and b/tests/images/roi/polylineroi/open_setstate.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion.png b/tests/images/roi/polylineroi/roi_getarrayregion.png new file mode 100644 index 00000000..bbf424e4 Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion_anisotropic.png b/tests/images/roi/polylineroi/roi_getarrayregion_anisotropic.png new file mode 100644 index 00000000..19009071 Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion_anisotropic.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion_halfpx.png b/tests/images/roi/polylineroi/roi_getarrayregion_halfpx.png new file mode 100644 index 00000000..f5af5fc3 Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion_halfpx.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion_img_trans.png b/tests/images/roi/polylineroi/roi_getarrayregion_img_trans.png new file mode 100644 index 00000000..b3cf8a1c Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion_img_trans.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion_inverty.png b/tests/images/roi/polylineroi/roi_getarrayregion_inverty.png new file mode 100644 index 00000000..00466296 Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion_inverty.png differ diff --git a/tests/images/roi/polylineroi/roi_getarrayregion_rotate.png b/tests/images/roi/polylineroi/roi_getarrayregion_rotate.png new file mode 100644 index 00000000..7961c675 Binary files /dev/null and b/tests/images/roi/polylineroi/roi_getarrayregion_rotate.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion.png b/tests/images/roi/rectroi/roi_getarrayregion.png new file mode 100644 index 00000000..13b308e7 Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_anisotropic.png b/tests/images/roi/rectroi/roi_getarrayregion_anisotropic.png new file mode 100644 index 00000000..8d0a825f Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_anisotropic.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_halfpx.png b/tests/images/roi/rectroi/roi_getarrayregion_halfpx.png new file mode 100644 index 00000000..956796d0 Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_halfpx.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_img_trans.png b/tests/images/roi/rectroi/roi_getarrayregion_img_trans.png new file mode 100644 index 00000000..7a12ba7a Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_img_trans.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_inverty.png b/tests/images/roi/rectroi/roi_getarrayregion_inverty.png new file mode 100644 index 00000000..8a801f78 Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_inverty.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_resize.png b/tests/images/roi/rectroi/roi_getarrayregion_resize.png new file mode 100644 index 00000000..881517fe Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_resize.png differ diff --git a/tests/images/roi/rectroi/roi_getarrayregion_rotate.png b/tests/images/roi/rectroi/roi_getarrayregion_rotate.png new file mode 100644 index 00000000..366e1f9c Binary files /dev/null and b/tests/images/roi/rectroi/roi_getarrayregion_rotate.png differ diff --git a/pyqtgraph/imageview/tests/test_imageview.py b/tests/imageview/test_imageview.py similarity index 100% rename from pyqtgraph/imageview/tests/test_imageview.py rename to tests/imageview/test_imageview.py diff --git a/pyqtgraph/parametertree/tests/test_Parameter.py b/tests/parametertree/test_Parameter.py similarity index 100% rename from pyqtgraph/parametertree/tests/test_Parameter.py rename to tests/parametertree/test_Parameter.py diff --git a/pyqtgraph/parametertree/tests/test_parametertypes.py b/tests/parametertree/test_parametertypes.py similarity index 100% rename from pyqtgraph/parametertree/tests/test_parametertypes.py rename to tests/parametertree/test_parametertypes.py diff --git a/pyqtgraph/tests/test_Point.py b/tests/test_Point.py similarity index 100% rename from pyqtgraph/tests/test_Point.py rename to tests/test_Point.py diff --git a/pyqtgraph/tests/test_Vector.py b/tests/test_Vector.py similarity index 100% rename from pyqtgraph/tests/test_Vector.py rename to tests/test_Vector.py diff --git a/pyqtgraph/tests/test_configparser.py b/tests/test_configparser.py similarity index 100% rename from pyqtgraph/tests/test_configparser.py rename to tests/test_configparser.py diff --git a/pyqtgraph/tests/test_exit_crash.py b/tests/test_exit_crash.py similarity index 100% rename from pyqtgraph/tests/test_exit_crash.py rename to tests/test_exit_crash.py diff --git a/pyqtgraph/tests/test_functions.py b/tests/test_functions.py similarity index 100% rename from pyqtgraph/tests/test_functions.py rename to tests/test_functions.py diff --git a/pyqtgraph/tests/test_makeARGB.py b/tests/test_makeARGB.py similarity index 100% rename from pyqtgraph/tests/test_makeARGB.py rename to tests/test_makeARGB.py diff --git a/pyqtgraph/tests/test_qt.py b/tests/test_qt.py similarity index 100% rename from pyqtgraph/tests/test_qt.py rename to tests/test_qt.py diff --git a/pyqtgraph/tests/test_ref_cycles.py b/tests/test_ref_cycles.py similarity index 100% rename from pyqtgraph/tests/test_ref_cycles.py rename to tests/test_ref_cycles.py diff --git a/pyqtgraph/tests/test_reload.py b/tests/test_reload.py similarity index 100% rename from pyqtgraph/tests/test_reload.py rename to tests/test_reload.py diff --git a/pyqtgraph/tests/test_signalproxy.py b/tests/test_signalproxy.py similarity index 97% rename from pyqtgraph/tests/test_signalproxy.py rename to tests/test_signalproxy.py index 615fc323..7dc366a1 100644 --- a/pyqtgraph/tests/test_signalproxy.py +++ b/tests/test_signalproxy.py @@ -1,11 +1,8 @@ import sys import pytest -from ..Qt import QtCore -from ..Qt import QtGui -from ..Qt import QT_LIB, PYSIDE - -from ..SignalProxy import SignalProxy +from pyqtgraph.Qt import QtCore, QtGui, QT_LIB, PYSIDE +from pyqtgraph import SignalProxy class Sender(QtCore.QObject): diff --git a/pyqtgraph/tests/test_srttransform3d.py b/tests/test_srttransform3d.py similarity index 100% rename from pyqtgraph/tests/test_srttransform3d.py rename to tests/test_srttransform3d.py diff --git a/pyqtgraph/tests/test_stability.py b/tests/test_stability.py similarity index 100% rename from pyqtgraph/tests/test_stability.py rename to tests/test_stability.py diff --git a/pyqtgraph/tests/ui_testing.py b/tests/ui_testing.py similarity index 98% rename from pyqtgraph/tests/ui_testing.py rename to tests/ui_testing.py index 05e74f61..bd09372f 100644 --- a/pyqtgraph/tests/ui_testing.py +++ b/tests/ui_testing.py @@ -1,5 +1,5 @@ import time -from ..Qt import QtCore, QtGui, QtTest +from pyqtgraph.Qt import QtCore, QtGui, QtTest def resizeWindow(win, w, h, timeout=2.0): diff --git a/pyqtgraph/tests/uictest.ui b/tests/uictest.ui similarity index 100% rename from pyqtgraph/tests/uictest.ui rename to tests/uictest.ui diff --git a/pyqtgraph/util/tests/test_lru_cache.py b/tests/util/test_lru_cache.py similarity index 100% rename from pyqtgraph/util/tests/test_lru_cache.py rename to tests/util/test_lru_cache.py diff --git a/pyqtgraph/widgets/tests/test_combobox.py b/tests/widgets/test_combobox.py similarity index 100% rename from pyqtgraph/widgets/tests/test_combobox.py rename to tests/widgets/test_combobox.py diff --git a/pyqtgraph/widgets/tests/test_graphics_view.py b/tests/widgets/test_graphics_view.py similarity index 100% rename from pyqtgraph/widgets/tests/test_graphics_view.py rename to tests/widgets/test_graphics_view.py diff --git a/pyqtgraph/widgets/tests/test_histogramlutwidget.py b/tests/widgets/test_histogramlutwidget.py similarity index 100% rename from pyqtgraph/widgets/tests/test_histogramlutwidget.py rename to tests/widgets/test_histogramlutwidget.py diff --git a/pyqtgraph/widgets/tests/test_spinbox.py b/tests/widgets/test_spinbox.py similarity index 100% rename from pyqtgraph/widgets/tests/test_spinbox.py rename to tests/widgets/test_spinbox.py diff --git a/pyqtgraph/widgets/tests/test_tablewidget.py b/tests/widgets/test_tablewidget.py similarity index 100% rename from pyqtgraph/widgets/tests/test_tablewidget.py rename to tests/widgets/test_tablewidget.py