1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
5 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License.
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 # Lesser General Public License for more details.
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 # Author : A. Bruneton
25 import unittest, sys, os, filecmp, shutil, tempfile
26 from pyqtside.QtGui import QApplication, QPixmap, QPainter
27 from PlotController import PlotController
28 from XYView import XYView
31 func.__runOnly__ = True
34 def processDecorator(mod_name):
35 """ Little trick to be able to mark a test with the decorator
37 If one or more tests bear this decorator, only them will be run
41 for name, obj in inspect.getmembers(sys.modules[mod_name]):
42 if name == "PlotTest" and inspect.isclass(obj):
44 if p.startswith("test") and hasattr(obj.__dict__[p], "__runOnly__"):
48 for name, obj in inspect.getmembers(sys.modules[mod_name]):
49 if name == "PlotTest" and inspect.isclass(obj):
52 if p.startswith("test") and not hasattr(obj.__dict__[p], "__runOnly__"):
55 class PlotTestBase(unittest.TestCase):
56 """ Unit test suite for the curve plotter. This class deals with the set up and the screenshot generation/
57 comparison. The tests themselves are stored in the derived class PlotTest below.
59 The class variable below can be turned on to regenerate base line files (reference images).
60 All baselines start with the name of the corresponding test, plus a possible suffix.
61 The baselines directory is set relative to the path of this script.
63 REBUILD_BASELINES = False
65 __BASE_LINE_DIR = "baselines"
68 def __init__(self, methodName):
69 unittest.TestCase.__init__(self, methodName)
71 if self.REBUILD_BASELINES:
72 self.tmpBaselineDir = os.path.join(tempfile.gettempdir(), "curveplot_baselines")
73 if not os.path.isdir(self.tmpBaselineDir):
74 os.mkdir(self.tmpBaselineDir)
75 print("### Rebuilding base lines. Reference files will be saved to '%s'" % self.tmpBaselineDir)
77 PlotController.WITH_CURVE_BROWSER = True
78 XYView._DEFAULT_LEGEND_STATE = True # always show legend by default
79 self._this_dir = os.path.dirname(os.path.realpath(__file__))
81 # import matplotlib as mpl
85 from SalomePyQt_MockUp import SalomePyQt
86 from TableModel import TableModel
87 from CurveModel import CurveModel
88 from XYPlotSetModel import XYPlotSetModel
92 if not self.REBUILD_BASELINES:
93 self.tmpDir = tempfile.mkdtemp(prefix="curveplot_tests")
97 self.sgPyQt = SalomePyQt()
98 # Reinstanciate from scratch the PlotController:
99 self.plotController = PlotController.GetInstance(self.sgPyQt)
100 self.plotController.setFixedSizeWidget()
101 # Reset some class var to make sure IDs appearing in screenshots do not depend on test seq order:
102 CurveModel.START_ID = -1
103 TableModel.START_ID = -1
104 XYPlotSetModel.START_ID = -1
107 if not self.REBUILD_BASELINES:
108 # Clean up temp dir where the file comparison has been made:
110 shutil.rmtree(self.tmpDir, False)
111 PlotController.Destroy()
113 def getTestName(self):
114 return self.id().split(".")[-1]
116 def saveCurrentPix(self, direct, suffix):
117 fileName = os.path.join(direct, self.getTestName() + suffix + "." + self.__FORMAT)
118 self.qpixmap.save(fileName, self.__FORMAT)
121 def areScreenshotEqual(self, widget, suffix=""):
122 """ Test equality between a reference file saved in the baseline directory, and whose name is built as
123 "<test_name><suffix>.png"
124 and the file generated on the fly by taking a snapshot of the widget provided in argument.
125 The comparison is made in a temp dir which is kept if the file differ.
129 self.qpixmap = QPixmap.grabWidget(widget)
131 # Nothing to compare if rebuilding base lines, just saving file:
132 if self.REBUILD_BASELINES:
133 self.saveCurrentPix(self.tmpBaselineDir, suffix)
136 gen_path = self.saveCurrentPix(self.tmpDir, suffix)
137 base_ref = os.path.join(self._this_dir, self.__BASE_LINE_DIR, self.getTestName() + suffix)
139 for ref_path in glob.glob("%s_*.%s" % (base_ref, self.__FORMAT)):
141 ret = filecmp.cmp(ref_path, gen_path, shallow=False)
147 # Keep file if assert is false
149 print("[%s] -- Failed screenshot equality, or unable to open baseline file - directory is kept alive: %s" % (self.getTestName(), self.tmpDir))
152 def showTabWidget(self):
153 tabW = self.plotController._sgPyQt._tabWidget
154 # No simpler way found so far:
158 def getBrowserWidget(self):
159 return self.plotController._curveBrowserView._treeWidget