source: sasview/src/sas/qtgui/Perspectives/Inversion/UnitTesting/InversionPerspectiveTest.py @ 35e36fd

ESS_GUIESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 35e36fd was 144fe21, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

new unit test runner script + test fixes. SASVIEW-970

  • Property mode set to 100644
File size: 13.7 KB
RevLine 
[d79bb7e]1import time
[50bfab0]2import unittest
3from unittest.mock import MagicMock
4
5from PyQt5 import QtGui, QtWidgets
6
[d79bb7e]7from sas.qtgui.Utilities.GuiUtils import *
[50bfab0]8from sas.qtgui.Perspectives.Inversion.InversionPerspective import InversionWindow
[0662f53]9from sas.qtgui.Perspectives.Inversion.InversionUtils import WIDGETS
[50bfab0]10from sas.qtgui.Plotting.PlotterData import Data1D
11
12import sas.qtgui.Utilities.GuiUtils as GuiUtils
13
[144fe21]14if not QtWidgets.QApplication.instance():
15    app = QtWidgets.QApplication(sys.argv)
[50bfab0]16
[0662f53]17
[d79bb7e]18class dummy_manager(object):
19    HELP_DIRECTORY_LOCATION = "html"
20    communicate = Communicate()
21    def communicator(self):
22        return self.communicate
23
24
[50bfab0]25class InversionTest(unittest.TestCase):
[0662f53]26    """ Test the Inversion Perspective GUI """
27
[50bfab0]28    def setUp(self):
[0662f53]29        """ Create the InversionWindow """
[144fe21]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()
[d79bb7e]36        self.widget.show()
[144fe21]37
[0662f53]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])
[d79bb7e]41        reference_data1.filename = "Test A"
[0662f53]42        reference_data2 = Data1D(x=[0.1, 0.2], y=[0.0, 0.0], dy=[0.0, 0.0])
[d79bb7e]43        reference_data2.filename = "Test B"
44        GuiUtils.updateModelItem(self.fakeData1, reference_data1)
45        GuiUtils.updateModelItem(self.fakeData2, reference_data2)
[50bfab0]46
47    def tearDown(self):
[0662f53]48        """ Destroy the InversionWindow """
[d79bb7e]49        self.widget.setClosable(False)
[50bfab0]50        self.widget.close()
51        self.widget = None
52
[0662f53]53    def removeAllData(self):
54        """ Cleanup method to restore widget to its base state """
[d79bb7e]55        if len(self.widget.dataList) > 0:
56            remove_me = list(self.widget._dataList.keys())
57            self.widget.removeData(remove_me)
[0662f53]58
59    def baseGUIState(self):
60        """ Testing base state of Inversion """
61        # base class information
[50bfab0]62        self.assertIsInstance(self.widget, QtWidgets.QWidget)
63        self.assertEqual(self.widget.windowTitle(), "P(r) Inversion Perspective")
[0662f53]64        self.assertFalse(self.widget.isClosable())
[72ecbdf2]65        self.assertFalse(self.widget.isCalculating)
[0662f53]66        # mapper
[50bfab0]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)
[0662f53]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())
[72ecbdf2]84        self.assertTrue(self.widget.stopButton.isEnabled())
85        self.assertFalse(self.widget.stopButton.isVisible())
[0662f53]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.assertTrue(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(), "")
[d79bb7e]118        self.assertEqual(self.widget.maxQInput.text(), "")
[0662f53]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
[d79bb7e]129        self.widget.enableButtons()
[0662f53]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())
[50bfab0]134
[0662f53]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)
[50bfab0]139        self.assertEqual(self.widget.dataList.count(), 2)
[0662f53]140        # See that the buttons are now enabled properly
[d79bb7e]141        self.widget.enableButtons()
[50bfab0]142        self.assertTrue(self.widget.calculateThisButton.isEnabled())
[d79bb7e]143        self.assertTrue(self.widget.calculateAllButton.isEnabled())
[50bfab0]144        self.assertTrue(self.widget.removeButton.isEnabled())
145        self.assertTrue(self.widget.explorerButton.isEnabled())
146
[0662f53]147    def testDefaults(self):
148        """ Test the GUI in its default state """
149        self.baseGUIState()
150        self.zeroDataSetState()
151        self.baseBatchState()
[d79bb7e]152        self.removeAllData()
[50bfab0]153
154    def testAllowBatch(self):
[0662f53]155        """ Batch P(r) Tests """
156        self.baseBatchState()
[d79bb7e]157        self.widget.setData([self.fakeData1])
158        self.oneDataSetState()
159        self.widget.setData([self.fakeData2])
160        self.twoDataSetState()
161        self.widget.calculateAllButton.click()
[72ecbdf2]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())
[6bd0d81]166        self.assertIsNotNone(self.widget.batchResultsWindow)
167        self.assertTrue(self.widget.batchResultsWindow.cmdHelp.isEnabled())
[d79bb7e]168        self.assertEqual(self.widget.batchResultsWindow.tblParams.columnCount(), 9)
169        self.assertEqual(self.widget.batchResultsWindow.tblParams.rowCount(), 2)
[72ecbdf2]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)
[d79bb7e]177        self.widget.batchResultsWindow.close()
[6bd0d81]178        self.assertIsNone(self.widget.batchResultsWindow)
[d79bb7e]179        # Last test
180        self.removeAllData()
181        self.baseBatchState()
[50bfab0]182
[0662f53]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()
[d79bb7e]194        self.removeAllData()
[0662f53]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()
[d79bb7e]203        self.removeAllData()
[50bfab0]204
[0662f53]205    def testClose(self):
206        """ Test methods related to closing the window """
207        self.assertFalse(self.widget.isClosable())
208        self.widget.close()
[d79bb7e]209        self.assertTrue(self.widget.isMinimized())
[6bd0d81]210        self.assertIsNone(self.widget.dmaxWindow)
[0662f53]211        self.widget.setClosable(False)
212        self.assertFalse(self.widget.isClosable())
213        self.widget.close()
[d79bb7e]214        self.assertTrue(self.widget.isMinimized())
[0662f53]215        self.widget.setClosable(True)
216        self.assertTrue(self.widget.isClosable())
217        self.widget.setClosable()
218        self.assertTrue(self.widget.isClosable())
[d79bb7e]219        self.removeAllData()
[50bfab0]220
221    def testGetNFunc(self):
[0662f53]222        """ test nfunc getter """
[50bfab0]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()
[72ecbdf2]233            self.assertEqual(cm.output, ['ERROR:sas.qtgui.Perspectives.Inversion.InversionPerspective:Incorrect number of terms specified: '])
[50bfab0]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()
[72ecbdf2]239            self.assertEqual(cm.output, ['ERROR:sas.qtgui.Perspectives.Inversion.InversionPerspective:Incorrect number of terms specified: Nordvest Pizza'])
[50bfab0]240        self.assertEqual(self.widget.getNFunc(), 10)
[d79bb7e]241        self.removeAllData()
[50bfab0]242
243    def testSetCurrentData(self):
[0662f53]244        """ test current data setter """
245        self.widget.setData([self.fakeData1, self.fakeData2])
[50bfab0]246
247        # Check that the current data is reference2
[0662f53]248        self.assertEqual(self.widget._data, self.fakeData2)
[50bfab0]249        # Set the ref to none
250        self.widget.setCurrentData(None)
[0662f53]251        self.assertEqual(self.widget._data, self.fakeData2)
[50bfab0]252        # Set the ref to wrong type
253        with self.assertRaises(AttributeError):
254            self.widget.setCurrentData("Afandi Kebab")
[0662f53]255        # Set the reference to ref1
256        self.widget.setCurrentData(self.fakeData1)
257        self.assertEqual(self.widget._data, self.fakeData1)
[d79bb7e]258        self.removeAllData()
[0662f53]259
[d79bb7e]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()
[0662f53]298
[6bd0d81]299    def testOpenExplorerWindow(self):
[0662f53]300        """ open Dx window """
[6bd0d81]301        self.assertIsNone(self.widget.dmaxWindow)
302        self.assertFalse(self.widget.explorerButton.isEnabled())
[0662f53]303        self.widget.openExplorerWindow()
[6bd0d81]304        self.assertIsNotNone(self.widget.dmaxWindow)
[0662f53]305        self.assertTrue(self.widget.dmaxWindow.isVisible())
[6bd0d81]306        self.assertTrue(self.widget.dmaxWindow.windowTitle() == "Dₐₓ Explorer")
[50bfab0]307
308
309if __name__ == "__main__":
310    unittest.main()
Note: See TracBrowser for help on using the repository browser.