Salome HOME
a8bf16f0054c5fbfc5f0375f3689e3c7f2f9464d
[modules/gui.git] / tools / CurvePlot / src / python / test / plot_test.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2007-2022  CEA/DEN, EDF R&D
3 #
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.
8 #
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.
13 #
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
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20 # Author : A. Bruneton
21 #
22 from curveplot import *
23 from curveplot.PlotTestBase import PlotTestBase, processDecorator
24 from curveplot.PlotSettings import PlotSettings
25
26 from pyqtside.QtWidgets import QApplication
27 import sys
28 qapp = QApplication(sys.argv)
29
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.
33    
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.
37   
38   The decorator @runOnly can be used to run/rebuild a single test.
39   """
40   REBUILD_BASELINES = False
41
42   def __init__(self, methodName):
43     PlotTestBase.__init__(self, methodName)
44
45   ###
46   ### Data generation
47   ###
48   def generateSine(self, alpha=1.0):
49     import numpy as np
50     x = np.arange(100)
51     y = np.sin(x*alpha/np.pi)
52     return x, y
53
54   def generateExp(self, alpha=1.0):
55     import numpy as np
56     x = np.arange(20) + 1.0
57     y = np.exp(x*alpha)
58     return x, y
59
60   ###
61   ### The tests themselves
62   ###
63
64   #
65   # Non GUI tests (some of them still need to show the widget to work properly but no
66   # screenshot comparison is made).
67   #
68   def testTableModel(self):
69     import numpy as np
70     from curveplot.TableModel import TableModel
71     t = TableModel(None)
72     t.setTitle("coucou")
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())
78     t.removeValue(0, 1)
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))
83
84   def testGetAllPlotSets(self):
85     self.showTabWidget()
86     ids, titles = PlotController.GetAllPlotSets()
87     self.assertEqual([], ids)
88     self.assertEqual([], titles)
89
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)
96
97   def testGetCurrentXX(self):
98     self.showTabWidget()
99     self.assertEqual(-1, PlotController.GetCurrentCurveID())
100     self.assertEqual(-1, PlotController.GetCurrentPlotSetID())
101
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())
114
115   def testGetPlotSetID(self):
116     self.showTabWidget()
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
123
124   def testGetPlotSetIDByName(self):
125     self.showTabWidget()
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"))
131
132   def testIsValidPlotSetID(self):
133     self.showTabWidget()
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))
139
140   #
141   # GUI tests
142   #
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))
148
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))
155
156   def testAddPlotSet(self):
157     tw = self.showTabWidget()
158     PlotController.AddPlotSet("My plotset")
159     self.assertTrue(self.areScreenshotEqual(tw))
160
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))
169
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))
177
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))
187
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
195     self.assertFalse(b)
196     self.assertEqual(crvID, anID)
197     self.assertTrue(self.areScreenshotEqual(tw))
198
199   def testDeleteCurrentItem_plotSet(self):
200     tw = self.showTabWidget()
201     PlotController.AddPlotSet("tutu")
202     psID = PlotController.AddPlotSet("tata")
203     b, anID = PlotController.DeleteCurrentItem()
204     self.assertTrue(b)
205     self.assertEqual(psID, anID)
206     self.assertTrue(self.areScreenshotEqual(tw))
207
208   def testDeleteCurrentItem_void(self):
209     self.showTabWidget()
210     b, anID = PlotController.DeleteCurrentItem()  # nothing selected
211     self.assertTrue(b)
212     self.assertEqual(-1, anID)
213
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))
222
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))
232
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))
241
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))
249
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))
260
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))
270
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))
281
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))
290
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
298
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))
304
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))
311
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))
319
320 #   def testToggleCurveBrowser(self):
321 #     # hard to test ...
322 #     raise NotImplementedError
323
324   def testPlotCurveFromTable(self):
325     tw = self.showTabWidget()
326     from curveplot.TableModel import TableModel
327     t = TableModel(None)
328     t.setTitle("coucou")
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))
339
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()
347     def fun():
348       dlg_test.setRGB(0,0,0)
349       dlg_test.showLegendCheckBox.setChecked(True)
350       return True
351     dlg_test.exec_ = fun
352     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
353     t[0][1].onSettings(dlg_test=dlg_test)
354     self.assertTrue(self.areScreenshotEqual(tw))
355
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))
364
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))
374
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()
382     def fun():
383       dlg_test.markerCurve.setCurrentIndex(2)
384       dlg_test.showLegendCheckBox.setChecked(True)
385       return True
386     dlg_test.exec_ = fun
387     t = list(PlotController.GetInstance()._curveTabsView._XYViews.items())
388     t[0][1].onSettings(dlg_test=dlg_test)
389     self.assertTrue(self.areScreenshotEqual(tw))
390
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))
397
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))
406
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))
414
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))
422
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))
429
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))
436
437   def testRegisterCallback(self):
438     global a_callb
439     a_callb = 0
440     def fun(crv_id):
441       global a_callb
442       a_callb = crv_id
443     self.showTabWidget()
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)
449
450   def testDeleteCallback(self):
451     global a_callb
452     a_callb = 0
453     def fun(crv_id):
454       global a_callb
455       a_callb = crv_id
456     self.showTabWidget()
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)
464
465   def testAddCurveEmptyPs(self):
466     """ Adding a curve when no ps was active was buggy """
467     self.showTabWidget()
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))
476
477   def test_onCurrentCurveChange(self):
478     self.showTabWidget()
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)
484     # was throwing:
485     PlotController.SetCurrentCurve(crvID2)
486
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))
493
494   def testLockRepaint(self):
495     tw = self.showTabWidget()
496     x, y = self.generateSine()
497     PlotController.LockRepaint()
498     for i in range(10):
499       _, psID = PlotController.AddCurve(x, y*float(i+1), append=True)
500     PlotController.UnlockRepaint()
501     self.assertTrue(self.areScreenshotEqual(tw))
502
503   def testDelPlotSetSelectPrev(self):
504     """ When deleting a full plot set, the previous plot set should become active """
505     self.showTabWidget()
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))
515
516 # Even if not in main:
517 processDecorator(__name__)
518
519 if __name__ == "__main__":
520   import unittest
521   unittest.main()