1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2024 CEA, EDF
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 # Author : A. Bruneton
22 from curveplot import *
23 from curveplot.PlotTestBase import PlotTestBase, processDecorator
24 from curveplot.PlotSettings import PlotSettings
26 from pyqtside.QtWidgets import QApplication
28 qapp = QApplication(sys.argv)
30 class PlotTest(PlotTestBase):
31 """ Unit test suite for the curve plotter. The tests themselves are stored in this class,
32 the screenshot comparison logic is in PlotTestBase.
34 The class variable below can be turned on to regenerate base line files (reference images).
35 All baselines start with the name of the corresponding test, plus a possible suffix.
36 The baselines directory is set relative to the path of this script.
38 The decorator @runOnly can be used to run/rebuild a single test.
40 REBUILD_BASELINES = False
42 def __init__(self, methodName):
43 PlotTestBase.__init__(self, methodName)
48 def generateSine(self, alpha=1.0):
51 y = np.sin(x*alpha/np.pi)
54 def generateExp(self, alpha=1.0):
56 x = np.arange(20) + 1.0
61 ### The tests themselves
65 # Non GUI tests (some of them still need to show the widget to work properly but no
66 # screenshot comparison is made).
68 def testTableModel(self):
70 from curveplot.TableModel import TableModel
73 t.addColumn([1.0,2.0,3.0,4.0])
74 self.assertRaises(ValueError, t.addColumn, [1.0,2.0])
75 t.addColumn([1.0,2.0,3.0,4.0])
76 t.addColumn([1.0, 4.0, 9.0, 16.0])
77 self.assertEqual((4,3), t.getShape())
79 self.assertTrue(np.isnan(t.getData()[0,1]))
80 t.setColumnTitle(1, "a title")
81 self.assertEqual("a title", t.getColumnTitle(1))
82 self.assertEqual("", t.getColumnTitle(0))
84 def testGetAllPlotSets(self):
86 ids, titles = PlotController.GetAllPlotSets()
87 self.assertEqual([], ids)
88 self.assertEqual([], titles)
90 id1 = PlotController.AddPlotSet("toto")
91 id2 = PlotController.AddPlotSet("tutu")
92 id3 = PlotController.AddPlotSet("titi")
93 ids, titles = PlotController.GetAllPlotSets()
94 self.assertEqual([id1,id2,id3], ids)
95 self.assertEqual(["toto","tutu","titi"], titles)
97 def testGetCurrentXX(self):
99 self.assertEqual(-1, PlotController.GetCurrentCurveID())
100 self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
102 x, y = self.generateSine()
103 _, psID1 = PlotController.AddCurve(x, y, append=False)
104 self.assertEqual(psID1, PlotController.GetCurrentPlotSetID())
105 _, psID2 = PlotController.AddCurve(x, y, append=True)
106 self.assertEqual(psID1, psID2) # doesn't hurt!
107 self.assertEqual(psID2, PlotController.GetCurrentPlotSetID())
108 psID3 = PlotController.AddPlotSet("ps")
109 self.assertEqual(psID3, PlotController.GetCurrentPlotSetID())
110 PlotController.DeletePlotSet(psID3)
111 PlotController.DeletePlotSet(psID2)
112 self.assertEqual(-1, PlotController.GetCurrentCurveID())
113 self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
115 def testGetPlotSetID(self):
117 x, y = self.generateSine()
118 crvID, psID = PlotController.AddCurve(x, y, append=False)
119 self.assertEqual(psID, PlotController.GetPlotSetID(crvID))
120 self.assertEqual(-1, PlotController.GetPlotSetID(145)) # invalid ID
121 PlotController.DeletePlotSet(psID)
122 self.assertEqual(-1, PlotController.GetPlotSetID(crvID)) # invalid ID
124 def testGetPlotSetIDByName(self):
126 self.assertEqual(-1,PlotController.GetPlotSetIDByName("invalid"))
127 psID = PlotController.AddPlotSet("ps")
128 self.assertEqual(psID,PlotController.GetPlotSetIDByName("ps"))
129 PlotController.DeletePlotSet(psID)
130 self.assertEqual(-1,PlotController.GetPlotSetIDByName("ps"))
132 def testIsValidPlotSetID(self):
134 self.assertEqual(False,PlotController.IsValidPlotSetID(0))
135 psID = PlotController.AddPlotSet("ps")
136 self.assertEqual(True,PlotController.IsValidPlotSetID(psID))
137 PlotController.DeletePlotSet(psID)
138 self.assertEqual(False,PlotController.IsValidPlotSetID(psID))
143 def testAddCurve(self):
144 x, y = self.generateSine()
145 tw = self.showTabWidget()
146 PlotController.AddCurve(x, y, curve_label="My curve", x_label="Lèés X (unicode!)", y_label="Et des ŷ", append=False)
147 self.assertTrue(self.areScreenshotEqual(tw))
149 def testAddCurveAppend(self):
150 x, y = self.generateSine()
151 tw = self.showTabWidget()
152 PlotController.AddCurve(x, y, curve_label="My curve", x_label="The X-s", y_label="The Y-s", append=False)
153 PlotController.AddCurve(x, y*1.5, curve_label="My curve 2", append=True)
154 self.assertTrue(self.areScreenshotEqual(tw))
156 def testAddPlotSet(self):
157 tw = self.showTabWidget()
158 PlotController.AddPlotSet("My plotset")
159 self.assertTrue(self.areScreenshotEqual(tw))
161 def testClearPlotSet(self):
162 x, y = self.generateSine()
163 tw = self.showTabWidget()
164 PlotController.AddCurve(x, y, curve_label="My curve", x_label="The X-s", y_label="The Y-s", append=False)
165 _, psID = PlotController.AddCurve(x, y, curve_label="My curve 2", append=True)
166 clearedID = PlotController.ClearPlotSet()
167 self.assertEqual(clearedID, psID)
168 self.assertTrue(self.areScreenshotEqual(tw))
170 def testClearPlotSet2(self):
171 tw = self.showTabWidget()
172 self.assertRaises(ValueError, PlotController.ClearPlotSet, -789)
173 psID = PlotController.AddPlotSet("My plotset")
174 clearedID = PlotController.ClearPlotSet(psID)
175 self.assertEqual(psID, clearedID)
176 self.assertTrue(self.areScreenshotEqual(tw))
178 def testCopyCurve(self):
179 x, y = self.generateSine()
180 tw = self.showTabWidget()
181 crvID, _ = PlotController.AddCurve(x, y, curve_label="My curve", x_label="The X-s", y_label="The Y-s", append=False)
182 psID = PlotController.AddPlotSet("Another plotset")
183 newID = PlotController.CopyCurve(crvID, psID)
184 PlotController.SetCurrentPlotSet(psID)
185 self.assertNotEqual(crvID, newID)
186 self.assertTrue(self.areScreenshotEqual(tw))
188 def testDeleteCurrentItem_curve(self):
189 x, y = self.generateSine()
190 tw = self.showTabWidget()
191 PlotController.AddCurve(x, y, append=False)
192 crvID, _ = PlotController.AddCurve(x, y*1.5, append=True)
193 PlotController.SetCurrentCurve(crvID)
194 b, anID = PlotController.DeleteCurrentItem() # currently selected curve
196 self.assertEqual(crvID, anID)
197 self.assertTrue(self.areScreenshotEqual(tw))
199 def testDeleteCurrentItem_plotSet(self):
200 tw = self.showTabWidget()
201 PlotController.AddPlotSet("tutu")
202 psID = PlotController.AddPlotSet("tata")
203 b, anID = PlotController.DeleteCurrentItem()
205 self.assertEqual(psID, anID)
206 self.assertTrue(self.areScreenshotEqual(tw))
208 def testDeleteCurrentItem_void(self):
210 b, anID = PlotController.DeleteCurrentItem() # nothing selected
212 self.assertEqual(-1, anID)
214 def testDeleteCurve1(self):
215 tw = self.showTabWidget()
216 x, y = self.generateSine()
217 crvID, _ = PlotController.AddCurve(x, y, append=False)
218 PlotController.AddCurve(x, y*1.5, append=True)
219 cID = PlotController.DeleteCurve(crvID)
220 self.assertEqual(crvID, cID)
221 self.assertTrue(self.areScreenshotEqual(tw))
223 def testDeleteCurve2(self):
224 tw = self.showTabWidget()
225 x, y = self.generateSine()
226 crvID, _ = PlotController.AddCurve(x, y, append=False)
227 PlotController.AddCurve(x, y*1.5, append=True)
228 PlotController.SetCurrentCurve(crvID)
229 cID = PlotController.DeleteCurve() # current curve
230 self.assertEqual(crvID, cID)
231 self.assertTrue(self.areScreenshotEqual(tw))
233 def testDeleteCurve3(self):
234 """ resulting in an empty plot set, legend should be hidden """
235 tw = self.showTabWidget()
236 x, y = self.generateSine()
237 crvID, _ = PlotController.AddCurve(x, y, append=False)
238 cID = PlotController.DeleteCurve(crvID)
239 self.assertEqual(crvID, cID)
240 self.assertTrue(self.areScreenshotEqual(tw))
242 def testDeletePlotSet1(self):
243 tw = self.showTabWidget()
244 psID = PlotController.AddPlotSet("tutu")
245 PlotController.AddPlotSet("tata")
246 psID2 = PlotController.DeletePlotSet(psID)
247 self.assertEqual(psID2, psID)
248 self.assertTrue(self.areScreenshotEqual(tw))
250 def testDeletePlotSet2(self):
251 tw = self.showTabWidget()
252 psID1 = PlotController.DeletePlotSet()
253 self.assertEqual(-1, psID1) # nothing selected yet
254 psID2 = PlotController.AddPlotSet("tutu")
255 PlotController.AddPlotSet("tata")
256 PlotController.SetCurrentPlotSet(psID2)
257 psID3 = PlotController.DeletePlotSet() # current plot set
258 self.assertEqual(psID3, psID2)
259 self.assertTrue(self.areScreenshotEqual(tw))
261 def testSetCurrentCurve(self):
262 tw = self.showTabWidget()
263 self.assertRaises(ValueError, PlotController.SetCurrentCurve, 23)
264 x, y = self.generateSine()
265 crvID, psID = PlotController.AddCurve(x, y, append=False)
266 _, _ = PlotController.AddCurve(x, y, append=False) # in a new plot set
267 psID2 = PlotController.SetCurrentCurve(crvID)
268 self.assertEqual(psID, psID2)
269 self.assertTrue(self.areScreenshotEqual(tw))
271 def testSetCurrentCurve2(self):
272 tw = self.showTabWidget()
273 x, y = self.generateSine()
274 crvID, psID = PlotController.AddCurve(x, y, append=False)
275 PlotController.SetCurrentCurve(crvID)
276 _, crvID2 = PlotController.AddCurve(x, y, append=False) # in a new plot set
277 PlotController.SetCurrentCurve(crvID2)
278 # on first plot set curve should not be selected anymore
279 PlotController.SetCurrentPlotSet(psID)
280 self.assertTrue(self.areScreenshotEqual(tw))
282 def testSetCurrentCurve3(self):
283 tw = self.showTabWidget()
284 x, y = self.generateSine()
285 crvID, _ = PlotController.AddCurve(x, y, append=False)
286 # Selecting and de-selecting
287 PlotController.SetCurrentCurve(crvID)
288 PlotController.SetCurrentCurve(-1)
289 self.assertTrue(self.areScreenshotEqual(tw))
291 def testSetCurrentPlotSet(self):
292 tw = self.showTabWidget()
293 psID = PlotController.AddPlotSet("tutu")
294 PlotController.AddPlotSet("tata")
295 PlotController.SetCurrentPlotSet(psID)
296 self.assertTrue(self.areScreenshotEqual(tw))
297 self.assertRaises(ValueError, PlotController.SetCurrentPlotSet, 124) # invalid ps_id
299 def testSetLabelX(self):
300 tw = self.showTabWidget()
301 ps_id = PlotController.AddPlotSet("My plotset")
302 PlotController.SetXLabel("The X-s éà", ps_id)
303 self.assertTrue(self.areScreenshotEqual(tw))
305 def testSetLabelY(self):
306 tw = self.showTabWidget()
307 ps_id = PlotController.AddPlotSet("My plotset")
308 PlotController.SetYLabel("Tutu", ps_id)
309 PlotController.SetYLabel("The Y-s uûàç", ps_id)
310 self.assertTrue(self.areScreenshotEqual(tw))
312 def testSetPlotSetTitle(self):
313 tw = self.showTabWidget()
314 ps_id = PlotController.AddPlotSet("tutu")
315 PlotController.AddPlotSet("tata")
316 PlotController.SetPlotSetTitle("un titre àé", ps_id)
317 PlotController.SetCurrentPlotSet(ps_id)
318 self.assertTrue(self.areScreenshotEqual(tw))
320 # def testToggleCurveBrowser(self):
322 # raise NotImplementedError
324 def testPlotCurveFromTable(self):
325 tw = self.showTabWidget()
326 from curveplot.TableModel import TableModel
329 t.addColumn([1.0,2.0,3.0,4.0])
330 t.addColumn([1.0,2.0,3.0,4.0])
331 t.addColumn([1.0,4.0,9.0,16.0])
332 t.setColumnTitle(0, "X-s")
333 t.setColumnTitle(1, "Identity")
334 t.setColumnTitle(2, "Square")
335 cont = PlotController.GetInstance()
336 cont.plotCurveFromTable(t, y_col_index=1, append=False)
337 cont.plotCurveFromTable(t, y_col_index=2, append=True)
338 self.assertTrue(self.areScreenshotEqual(tw))
340 def testSettingsCurveColor(self):
341 tw = self.showTabWidget()
342 x, y = self.generateSine()
343 crvID, _ = PlotController.AddCurve(x, y, append=False)
344 PlotController.SetCurrentCurve(crvID)
345 # Emulate changing the curve color from the settings box:
346 dlg_test = PlotSettings()
348 dlg_test.setRGB(0,0,0)
349 dlg_test.showLegendCheckBox.setChecked(True)
352 t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
353 t[0][1].onSettings(dlg_test=dlg_test)
354 self.assertTrue(self.areScreenshotEqual(tw))
356 def testExtendCurve(self):
357 tw = self.showTabWidget()
358 x, y = self.generateSine()
359 crvID, _ = PlotController.AddCurve(x, y, append=False)
360 PlotController.SetCurrentCurve(crvID)
361 PlotController.ExtendCurve(crvID, x+100.0, y*2.0)
362 # Curve must remain blue, bold and with first marker:
363 self.assertTrue(self.areScreenshotEqual(tw))
365 def testResetCurve(self):
366 tw = self.showTabWidget()
367 x, y = self.generateSine()
368 crvID, _ = PlotController.AddCurve(x, y, append=False)
369 PlotController.SetCurrentCurve(crvID)
370 PlotController.ResetCurve(crvID)
371 PlotController.ExtendCurve(crvID, x+100.0, y*x)
372 # Curve must remain blue, bold and with first marker:
373 self.assertTrue(self.areScreenshotEqual(tw))
375 def testSettingsCurveMarker(self):
376 tw = self.showTabWidget()
377 x, y = self.generateSine()
378 crvID, _ = PlotController.AddCurve(x, y, append=False)
379 PlotController.SetCurrentCurve(crvID)
380 # Emulate changing the marker from the settings box:
381 dlg_test = PlotSettings()
383 dlg_test.markerCurve.setCurrentIndex(2)
384 dlg_test.showLegendCheckBox.setChecked(True)
387 t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
388 t[0][1].onSettings(dlg_test=dlg_test)
389 self.assertTrue(self.areScreenshotEqual(tw))
391 def testSetCurveMarker(self):
392 tw = self.showTabWidget()
393 x, y = self.generateSine()
394 crvID, _ = PlotController.AddCurve(x, y, append=False)
395 PlotController.SetCurveMarker(crvID, "v")
396 self.assertTrue(self.areScreenshotEqual(tw))
398 def testSetCurveLabel(self):
399 tw = self.showTabWidget()
400 x, y = self.generateSine()
401 crvID, _ = PlotController.AddCurve(x, y, curve_label="titi", append=False)
402 _, _ = PlotController.AddCurve(x, y, curve_label="toto", append=True)
403 PlotController.SetCurrentCurve(crvID)
404 PlotController.SetCurveLabel(crvID, "tata")
405 self.assertTrue(self.areScreenshotEqual(tw))
407 def testToggleXLog(self):
408 tw = self.showTabWidget()
409 x, y = self.generateExp()
410 _, psID = PlotController.AddCurve(x, y, curve_label="titi", append=False)
411 PlotController.SetXLog(psID, True)
412 PlotController.SetYSciNotation(psID, True)
413 self.assertTrue(self.areScreenshotEqual(tw))
415 def testToggleYLog(self):
416 tw = self.showTabWidget()
417 x, y = self.generateExp()
418 _, psID = PlotController.AddCurve(x, y, curve_label="titi", append=False)
419 PlotController.SetYLog(psID, True)
420 PlotController.SetYSciNotation(psID, True)
421 self.assertTrue(self.areScreenshotEqual(tw))
423 def testSetXSciNotation(self):
424 tw = self.showTabWidget()
425 x, y = self.generateSine()
426 _, psID = PlotController.AddCurve(x*1.0e6, y*1.0e6, curve_label="titi", append=False)
427 PlotController.SetXSciNotation(psID, True)
428 self.assertTrue(self.areScreenshotEqual(tw))
430 def testSetYSciNotation(self):
431 tw = self.showTabWidget()
432 x, y = self.generateSine()
433 _, psID = PlotController.AddCurve(x*1.0e6, y*1.0e6, curve_label="titi", append=False)
434 PlotController.SetYSciNotation(psID, True)
435 self.assertTrue(self.areScreenshotEqual(tw))
437 def testRegisterCallback(self):
444 x, y = self.generateExp()
445 crvId, _ = PlotController.AddCurve(x, y)
446 PlotController.RegisterCallback(fun)
447 PlotController.SetCurrentCurve(crvId)
448 self.assertEqual(crvId, a_callb)
450 def testDeleteCallback(self):
457 x, y = self.generateExp()
458 crvId, _ = PlotController.AddCurve(x, y)
459 PlotController.RegisterCallback(fun)
460 PlotController.ClearCallbacks()
461 PlotController.SetCurrentCurve(crvId)
462 _, _ = PlotController.AddCurve(x, y)
463 self.assertEqual(crvId, a_callb)
465 def testAddCurveEmptyPs(self):
466 """ Adding a curve when no ps was active was buggy """
468 x, y = self.generateSine()
469 PlotController.AddPlotSet("toto")
470 # No current plot set:
471 PlotController.SetCurrentPlotSet(-1)
472 # Should create a new plot set:
473 PlotController.AddCurve(x, y, append=True)
474 l, _ = PlotController.GetAllPlotSets()
475 self.assertEqual(2, len(l))
477 def test_onCurrentCurveChange(self):
479 x, y = self.generateSine()
480 crvID, _ = PlotController.AddCurve(x, y)
481 PlotController.SetCurrentCurve(crvID)
482 PlotController.DeleteCurve(crvID)
483 crvID2, _ = PlotController.AddCurve(x, y)
485 PlotController.SetCurrentCurve(crvID2)
487 def testSetLegendVisible(self):
488 tw = self.showTabWidget()
489 x, y = self.generateSine()
490 _, psID = PlotController.AddCurve(x, y, curve_label="titi", append=False)
491 PlotController.SetLegendVisible(psID, False) # by default legend is always visible in the tests
492 self.assertTrue(self.areScreenshotEqual(tw))
494 def testLockRepaint(self):
495 tw = self.showTabWidget()
496 x, y = self.generateSine()
497 PlotController.LockRepaint()
499 _, psID = PlotController.AddCurve(x, y*float(i+1), append=True)
500 PlotController.UnlockRepaint()
501 self.assertTrue(self.areScreenshotEqual(tw))
503 def testDelPlotSetSelectPrev(self):
504 """ When deleting a full plot set, the previous plot set should become active """
506 x, y = self.generateSine()
507 _, psID0 = PlotController.AddCurve(x, y, append=True) # creates a new plot set
508 _, psID1 = PlotController.AddCurve(x, y, append=False) # creates a new plot set
509 PlotController.DeletePlotSet(psID1)
510 PlotController.AddCurve(x, y, append=True) # should NOT create a new plot set
511 psID2 = PlotController.GetCurrentPlotSetID()
512 self.assertEqual(psID0, psID2)
513 l, _ = PlotController.GetAllPlotSets()
514 self.assertEqual(1, len(l))
516 # Even if not in main:
517 processDecorator(__name__)
519 if __name__ == "__main__":