source: sasview/src/sas/qtgui/Perspectives/Inversion/UnitTesting/InversionPerspectiveTest.py @ 6ae7466

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 6ae7466 was 6ae7466, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 6 years ago

Complain when wrong data sent to perspective. SASVIEW-1165 SASVIEW-1166

  • Property mode set to 100644
File size: 13.7 KB
Line 
1import time
2import unittest
3from unittest.mock import MagicMock
4
5from PyQt5 import QtGui, QtWidgets
6
7from sas.qtgui.Utilities.GuiUtils import *
8from sas.qtgui.Perspectives.Inversion.InversionPerspective import InversionWindow
9from sas.qtgui.Perspectives.Inversion.InversionUtils import WIDGETS
10from sas.qtgui.Plotting.PlotterData import Data1D
11
12import sas.qtgui.Utilities.GuiUtils as GuiUtils
13
14if not QtWidgets.QApplication.instance():
15    app = QtWidgets.QApplication(sys.argv)
16
17
18class dummy_manager(object):
19    HELP_DIRECTORY_LOCATION = "html"
20    communicate = Communicate()
21    def communicator(self):
22        return self.communicate
23
24
25class InversionTest(unittest.TestCase):
26    """ Test the Inversion Perspective GUI """
27
28    def setUp(self):
29        """ Create the InversionWindow """
30
31        self.widget = InversionWindow(parent=dummy_manager())
32        self.widget._parent = QtWidgets.QMainWindow()
33        self.widget.showBatchOutput = MagicMock()
34        self.widget.startThread = MagicMock()
35        self.widget.startThreadAll = MagicMock()
36        self.widget.show()
37
38        self.fakeData1 = GuiUtils.HashableStandardItem("A")
39        self.fakeData2 = GuiUtils.HashableStandardItem("B")
40        reference_data1 = Data1D(x=[0.1, 0.2], y=[0.0, 0.0], dy=[0.0, 0.0])
41        reference_data1.filename = "Test A"
42        reference_data2 = Data1D(x=[0.1, 0.2], y=[0.0, 0.0], dy=[0.0, 0.0])
43        reference_data2.filename = "Test B"
44        GuiUtils.updateModelItem(self.fakeData1, reference_data1)
45        GuiUtils.updateModelItem(self.fakeData2, reference_data2)
46
47    def tearDown(self):
48        """ Destroy the InversionWindow """
49        self.widget.setClosable(False)
50        self.widget.close()
51        self.widget = None
52
53    def removeAllData(self):
54        """ Cleanup method to restore widget to its base state """
55        if len(self.widget.dataList) > 0:
56            remove_me = list(self.widget._dataList.keys())
57            self.widget.removeData(remove_me)
58
59    def baseGUIState(self):
60        """ Testing base state of Inversion """
61        # base class information
62        self.assertIsInstance(self.widget, QtWidgets.QWidget)
63        self.assertEqual(self.widget.windowTitle(), "P(r) Inversion Perspective")
64        self.assertFalse(self.widget.isClosable())
65        self.assertFalse(self.widget.isCalculating)
66        # mapper
67        self.assertIsInstance(self.widget.mapper, QtWidgets.QDataWidgetMapper)
68        self.assertNotEqual(self.widget.mapper.mappedSection(self.widget.dataList), -1)
69        # validators
70        self.assertIsInstance(self.widget.noOfTermsInput.validator(), QtGui.QIntValidator)
71        self.assertIsInstance(self.widget.regularizationConstantInput.validator(), QtGui.QDoubleValidator)
72        self.assertIsInstance(self.widget.maxDistanceInput.validator(), QtGui.QDoubleValidator)
73        self.assertIsInstance(self.widget.minQInput.validator(), QtGui.QDoubleValidator)
74        self.assertIsInstance(self.widget.maxQInput.validator(), QtGui.QDoubleValidator)
75        self.assertIsInstance(self.widget.slitHeightInput.validator(), QtGui.QDoubleValidator)
76        self.assertIsInstance(self.widget.slitWidthInput.validator(), QtGui.QDoubleValidator)
77        # model
78        self.assertEqual(self.widget.model.rowCount(), 22)
79        self.assertEqual(self.widget.model.columnCount(), 1)
80        self.assertEqual(self.widget.mapper.model(), self.widget.model)
81        # buttons
82        self.assertFalse(self.widget.calculateThisButton.isEnabled())
83        self.assertFalse(self.widget.removeButton.isEnabled())
84        self.assertTrue(self.widget.stopButton.isEnabled())
85        self.assertFalse(self.widget.stopButton.isVisible())
86        self.assertFalse(self.widget.regConstantSuggestionButton.isEnabled())
87        self.assertFalse(self.widget.noOfTermsSuggestionButton.isEnabled())
88        self.assertFalse(self.widget.explorerButton.isEnabled())
89        self.assertTrue(self.widget.helpButton.isEnabled())
90        # extra windows and charts
91        self.assertIsNone(self.widget.dmaxWindow)
92        self.assertIsNone(self.widget.prPlot)
93        self.assertIsNone(self.widget.dataPlot)
94        # threads
95        self.assertIsNone(self.widget.calcThread)
96        self.assertIsNone(self.widget.estimationThread)
97        self.assertIsNone(self.widget.estimationThreadNT)
98
99    def baseBatchState(self):
100        """ Testing the base batch fitting state """
101        self.assertFalse(self.widget.allowBatch())
102        self.assertFalse(self.widget.isBatch)
103        self.assertFalse(self.widget.calculateAllButton.isEnabled())
104        self.assertEqual(len(self.widget.batchResults), 0)
105        self.assertEqual(len(self.widget.batchComplete), 0)
106        self.widget.closeBatchResults()
107
108    def zeroDataSetState(self):
109        """ Testing the base data state of the GUI """
110        # data variables
111        self.assertIsNone(self.widget._data)
112        self.assertEqual(len(self.widget._dataList), 0)
113        self.assertEqual(self.widget.nTermsSuggested, 10)
114        # inputs
115        self.assertEqual(len(self.widget.dataList), 0)
116        self.assertEqual(self.widget.backgroundInput.text(), "0.0")
117        self.assertEqual(self.widget.minQInput.text(), "")
118        self.assertEqual(self.widget.maxQInput.text(), "")
119        self.assertEqual(self.widget.regularizationConstantInput.text(), "0.0001")
120        self.assertEqual(self.widget.noOfTermsInput.text(), "10")
121        self.assertEqual(self.widget.maxDistanceInput.text(), "140.0")
122
123    def oneDataSetState(self):
124        """ Testing the base data state of the GUI """
125        # Test the globals after first sent
126        self.assertEqual(len(self.widget._dataList), 1)
127        self.assertEqual(self.widget.dataList.count(), 1)
128        # See that the buttons are now enabled properly
129        self.widget.enableButtons()
130        self.assertFalse(self.widget.calculateAllButton.isEnabled())
131        self.assertTrue(self.widget.calculateThisButton.isEnabled())
132        self.assertTrue(self.widget.removeButton.isEnabled())
133        self.assertTrue(self.widget.explorerButton.isEnabled())
134
135    def twoDataSetState(self):
136        """ Testing the base data state of the GUI """
137        # Test the globals after first sent
138        self.assertEqual(len(self.widget._dataList), 2)
139        self.assertEqual(self.widget.dataList.count(), 2)
140        # See that the buttons are now enabled properly
141        self.widget.enableButtons()
142        self.assertTrue(self.widget.calculateThisButton.isEnabled())
143        self.assertTrue(self.widget.calculateAllButton.isEnabled())
144        self.assertTrue(self.widget.removeButton.isEnabled())
145        self.assertTrue(self.widget.explorerButton.isEnabled())
146
147    def testDefaults(self):
148        """ Test the GUI in its default state """
149        self.baseGUIState()
150        self.zeroDataSetState()
151        self.baseBatchState()
152        self.removeAllData()
153
154    def notestAllowBatch(self):
155        """ Batch P(r) Tests """
156        self.baseBatchState()
157        self.widget.setData([self.fakeData1])
158        self.oneDataSetState()
159        self.widget.setData([self.fakeData2])
160        self.twoDataSetState()
161        self.widget.calculateAllButton.click()
162        self.assertTrue(self.widget.isCalculating)
163        self.assertTrue(self.widget.isBatch)
164        self.assertTrue(self.widget.stopButton.isVisible())
165        self.assertTrue(self.widget.stopButton.isEnabled())
166        self.assertIsNotNone(self.widget.batchResultsWindow)
167        self.assertTrue(self.widget.batchResultsWindow.cmdHelp.isEnabled())
168        self.assertEqual(self.widget.batchResultsWindow.tblParams.columnCount(), 9)
169        self.assertEqual(self.widget.batchResultsWindow.tblParams.rowCount(), 2)
170        # Test stop button
171        self.widget.stopButton.click()
172        self.assertTrue(self.widget.batchResultsWindow.isVisible())
173        self.assertFalse(self.widget.stopButton.isVisible())
174        self.assertTrue(self.widget.stopButton.isEnabled())
175        self.assertFalse(self.widget.isBatch)
176        self.assertFalse(self.widget.isCalculating)
177        self.widget.batchResultsWindow.close()
178        self.assertIsNone(self.widget.batchResultsWindow)
179        # Last test
180        self.removeAllData()
181        self.baseBatchState()
182
183    def testSetData(self):
184        """ Check if sending data works as expected """
185        self.zeroDataSetState()
186        self.widget.setData([self.fakeData1])
187        self.oneDataSetState()
188        self.widget.setData([self.fakeData1])
189        self.oneDataSetState()
190        self.widget.setData([self.fakeData2])
191        self.twoDataSetState()
192        self.removeAllData()
193        self.zeroDataSetState()
194        self.removeAllData()
195
196    def testRemoveData(self):
197        """ Test data removal from widget """
198        self.widget.setData([self.fakeData1, self.fakeData2])
199        self.twoDataSetState()
200        # Remove data 0
201        self.widget.removeData()
202        self.oneDataSetState()
203        self.removeAllData()
204
205    def testClose(self):
206        """ Test methods related to closing the window """
207        self.assertFalse(self.widget.isClosable())
208        self.widget.close()
209        self.assertTrue(self.widget.isMinimized())
210        self.assertIsNone(self.widget.dmaxWindow)
211        self.widget.setClosable(False)
212        self.assertFalse(self.widget.isClosable())
213        self.widget.close()
214        self.assertTrue(self.widget.isMinimized())
215        self.widget.setClosable(True)
216        self.assertTrue(self.widget.isClosable())
217        self.widget.setClosable()
218        self.assertTrue(self.widget.isClosable())
219        self.removeAllData()
220
221    def testGetNFunc(self):
222        """ test nfunc getter """
223        # Float
224        self.widget.noOfTermsInput.setText("10.0")
225        self.assertEqual(self.widget.getNFunc(), 10)
226        # Int
227        self.widget.noOfTermsInput.setText("980")
228        self.assertEqual(self.widget.getNFunc(), 980)
229        # Empty
230        with self.assertLogs(level='ERROR') as cm:
231            self.widget.noOfTermsInput.setText("")
232            n = self.widget.getNFunc()
233            self.assertEqual(cm.output, ['ERROR:sas.qtgui.Perspectives.Inversion.InversionPerspective:Incorrect number of terms specified: '])
234        self.assertEqual(self.widget.getNFunc(), 10)
235        # string
236        with self.assertLogs(level='ERROR') as cm:
237            self.widget.noOfTermsInput.setText("Nordvest Pizza")
238            n = self.widget.getNFunc()
239            self.assertEqual(cm.output, ['ERROR:sas.qtgui.Perspectives.Inversion.InversionPerspective:Incorrect number of terms specified: Nordvest Pizza'])
240        self.assertEqual(self.widget.getNFunc(), 10)
241        self.removeAllData()
242
243    def testSetCurrentData(self):
244        """ test current data setter """
245        self.widget.setData([self.fakeData1, self.fakeData2])
246
247        # Check that the current data is reference2
248        self.assertEqual(self.widget._data, self.fakeData2)
249        # Set the ref to none
250        self.widget.setCurrentData(None)
251        self.assertEqual(self.widget._data, self.fakeData2)
252        # Set the ref to wrong type
253        with self.assertRaises(AttributeError):
254            self.widget.setCurrentData("Afandi Kebab")
255        # Set the reference to ref1
256        self.widget.setCurrentData(self.fakeData1)
257        self.assertEqual(self.widget._data, self.fakeData1)
258        self.removeAllData()
259
260    def testModelChanged(self):
261        """ Test setting the input and the model and vice-versa """
262        # Initial values
263        self.assertEqual(self.widget._calculator.get_dmax(), 140.0)
264        self.assertEqual(self.widget._calculator.get_qmax(), -1.0)
265        self.assertEqual(self.widget._calculator.get_qmin(), -1.0)
266        self.assertEqual(self.widget._calculator.slit_height, 0.0)
267        self.assertEqual(self.widget._calculator.slit_width, 0.0)
268        self.assertEqual(self.widget._calculator.alpha, 0.0001)
269        # Set new values
270        self.widget.maxDistanceInput.setText("1.0")
271        self.widget.maxQInput.setText("3.0")
272        self.widget.minQInput.setText("5.0")
273        self.widget.slitHeightInput.setText("7.0")
274        self.widget.slitWidthInput.setText("9.0")
275        self.widget.regularizationConstantInput.setText("11.0")
276        # Check new values
277        self.assertEqual(self.widget._calculator.get_dmax(), 1.0)
278        self.assertEqual(self.widget._calculator.get_qmax(), 3.0)
279        self.assertEqual(self.widget._calculator.get_qmin(), 5.0)
280        self.assertEqual(self.widget._calculator.slit_height, 7.0)
281        self.assertEqual(self.widget._calculator.slit_width, 9.0)
282        self.assertEqual(self.widget._calculator.alpha, 11.0)
283        # Change model directly
284        self.widget.model.setItem(WIDGETS.W_MAX_DIST, QtGui.QStandardItem("2.0"))
285        self.widget.model.setItem(WIDGETS.W_QMIN, QtGui.QStandardItem("4.0"))
286        self.widget.model.setItem(WIDGETS.W_QMAX, QtGui.QStandardItem("6.0"))
287        self.widget.model.setItem(WIDGETS.W_SLIT_HEIGHT, QtGui.QStandardItem("8.0"))
288        self.widget.model.setItem(WIDGETS.W_SLIT_WIDTH, QtGui.QStandardItem("10.0"))
289        self.widget.model.setItem(WIDGETS.W_REGULARIZATION, QtGui.QStandardItem("12.0"))
290        # Check values
291        self.assertEqual(self.widget._calculator.get_dmax(), 2.0)
292        self.assertEqual(self.widget._calculator.get_qmin(), 4.0)
293        self.assertEqual(self.widget._calculator.get_qmax(), 6.0)
294        self.assertEqual(self.widget._calculator.slit_height, 8.0)
295        self.assertEqual(self.widget._calculator.slit_width, 10.0)
296        self.assertEqual(self.widget._calculator.alpha, 12.0)
297        self.removeAllData()
298
299    def testOpenExplorerWindow(self):
300        """ open Dx window """
301        self.assertIsNone(self.widget.dmaxWindow)
302        self.assertFalse(self.widget.explorerButton.isEnabled())
303        self.widget.openExplorerWindow()
304        self.assertIsNotNone(self.widget.dmaxWindow)
305        self.assertTrue(self.widget.dmaxWindow.isVisible())
306        self.assertTrue(self.widget.dmaxWindow.windowTitle() == "Dmax Explorer")
307
308
309if __name__ == "__main__":
310    unittest.main()
Note: See TracBrowser for help on using the repository browser.