source: sasview/src/sas/qtgui/Perspectives/Fitting/UnitTesting/FittingWidgetTest.py @ 351b53e

ESS_GUIESS_GUI_DocsESS_GUI_batch_fittingESS_GUI_bumps_abstractionESS_GUI_iss1116ESS_GUI_iss879ESS_GUI_iss959ESS_GUI_openclESS_GUI_orderingESS_GUI_sync_sascalc
Last change on this file since 351b53e was 351b53e, checked in by Piotr Rozyczko <rozyczko@…>, 7 years ago

More unit tests for fitting SASVIEW-499

  • Property mode set to 100644
File size: 15.3 KB
RevLine 
[811bec1]1import sys
2import unittest
3
4from PyQt4 import QtGui
5from PyQt4 import QtTest
6from PyQt4 import QtCore
7from mock import MagicMock
[351b53e]8from twisted.internet import threads
[811bec1]9
10# set up import paths
11import sas.qtgui.path_prepare
12
13# Local
14from sas.qtgui.GuiUtils import *
15from sas.qtgui.Perspectives.Fitting.FittingWidget import *
[351b53e]16from sas.qtgui.UnitTesting.TestUtils import QtSignalSpy
17
[811bec1]18from sas.sasgui.guiframe.dataFitting import Data1D
19
20app = QtGui.QApplication(sys.argv)
21
22class dummy_manager(object):
23    def communicate(self):
24        return Communicate()
25
26class FittingWidgetTest(unittest.TestCase):
27    """Test the fitting widget GUI"""
28
29    def setUp(self):
30        """Create the GUI"""
31        self.widget = FittingWidget(dummy_manager())
32
33    def tearDown(self):
34        """Destroy the GUI"""
35        self.widget.close()
36        self.widget = None
37
38    def testDefaults(self):
39        """Test the GUI in its default state"""
40        self.assertIsInstance(self.widget, QtGui.QWidget)
41        self.assertEqual(self.widget.windowTitle(), "Fitting")
42        self.assertEqual(self.widget.sizePolicy().Policy(), QtGui.QSizePolicy.Fixed)
43        self.assertIsInstance(self.widget.lstParams.model(), QtGui.QStandardItemModel)
44        self.assertIsInstance(self.widget.lstPoly.model(), QtGui.QStandardItemModel)
45        self.assertIsInstance(self.widget.lstMagnetic.model(), QtGui.QStandardItemModel)
46        self.assertFalse(self.widget.cbModel.isEnabled())
47        self.assertFalse(self.widget.cbStructureFactor.isEnabled())
48        self.assertFalse(self.widget.cmdFit.isEnabled())
49        self.assertTrue(self.widget.acceptsData())
50        self.assertFalse(self.widget.data_is_loaded)
51
52    def testSelectCategory(self):
53        """
54        Test if model categories have been loaded properly
55        """
56        fittingWindow =  self.widget
57
58        #Test loading from json categories
59        category_list = fittingWindow.master_category_dict.keys()
60
61        for category in category_list:
62            self.assertNotEqual(fittingWindow.cbCategory.findText(category),-1)
63
64        #Test what is current text in the combobox
65        self.assertEqual(fittingWindow.cbCategory.currentText(), CATEGORY_DEFAULT)
66
67    def testWidgetWithData(self):
68        """
69        Test the instantiation of the widget with initial data
70        """
71        data = Data1D(x=[1,2], y=[1,2])
72        GuiUtils.dataFromItem = MagicMock(return_value=data)
73        item = QtGui.QStandardItem("test")
74
[7248d75d]75        widget_with_data = FittingWidget(dummy_manager(), data=[item], id=3)
[811bec1]76
77        self.assertEqual(widget_with_data.data, data)
78        self.assertTrue(widget_with_data.data_is_loaded)
[7248d75d]79        # self.assertTrue(widget_with_data.cmdFit.isEnabled())
[811bec1]80        self.assertFalse(widget_with_data.acceptsData())
81
82    def notestSelectModel(self):
83        """
84        Test if models have been loaded properly
85        :return:
86        """
87        fittingWindow =  self.widget
88
89        #Test loading from json categories
90        model_list = fittingWindow.master_category_dict["Cylinder"]
91        self.assertTrue(['cylinder', True] in model_list)
92        self.assertTrue(['core_shell_cylinder', True] in model_list)
93        self.assertTrue(['barbell', True] in model_list)
94        self.assertTrue(['core_shell_bicelle', True] in model_list)
95        self.assertTrue(['flexible_cylinder', True] in model_list)
96        self.assertTrue(['flexible_cylinder_elliptical', True] in model_list)
97        self.assertTrue(['pearl_necklace', True] in model_list)
98        self.assertTrue(['capped_cylinder', True] in model_list)
99        self.assertTrue(['elliptical_cylinder', True] in model_list)
100        self.assertTrue(['pringle', True] in model_list)
101        self.assertTrue(['hollow_cylinder', True] in model_list)
102        self.assertTrue(['core_shell_bicelle_elliptical', True] in model_list)
103        self.assertTrue(['stacked_disks', True] in model_list)
104
105        #Test for existence in combobox
106        self.assertNotEqual(fittingWindow.cbModel.findText("cylinder"),-1)
107        self.assertNotEqual(fittingWindow.cbModel.findText("core_shell_cylinder"),-1)
108        self.assertNotEqual(fittingWindow.cbModel.findText("barbell"),-1)
109        self.assertNotEqual(fittingWindow.cbModel.findText("core_shell_bicelle"),-1)
110        self.assertNotEqual(fittingWindow.cbModel.findText("flexible_cylinder"),-1)
111        self.assertNotEqual(fittingWindow.cbModel.findText("flexible_cylinder_elliptical"),-1)
112        self.assertNotEqual(fittingWindow.cbModel.findText("pearl_necklace"),-1)
113        self.assertNotEqual(fittingWindow.cbModel.findText("capped_cylinder"),-1)
114        self.assertNotEqual(fittingWindow.cbModel.findText("elliptical_cylinder"),-1)
115        self.assertNotEqual(fittingWindow.cbModel.findText("pringle"),-1)
116        self.assertNotEqual(fittingWindow.cbModel.findText("hollow_cylinder"),-1)
117        self.assertNotEqual(fittingWindow.cbModel.findText("core_shell_bicelle_elliptical"),-1)
118        self.assertNotEqual(fittingWindow.cbModel.findText("stacked_disks"),-1)
119
120
121    def testSelectPolydispersity(self):
122        """
123        Test if models have been loaded properly
124        :return:
125        """
126        fittingWindow =  self.widget
127
128        #Test loading from json categories
[7248d75d]129        fittingWindow.SASModelToQModel("cylinder")
[811bec1]130        pd_index = fittingWindow.lstPoly.model().index(0,0)
131        self.assertEqual(str(pd_index.data().toString()), "Distribution of radius")
132        pd_index = fittingWindow.lstPoly.model().index(1,0)
133        self.assertEqual(str(pd_index.data().toString()), "Distribution of length")
134
135    def testSelectStructureFactor(self):
136        """
137        Test if structure factors have been loaded properly
138        :return:
139        """
140        fittingWindow =  self.widget
141
142        #Test for existence in combobox
143        self.assertNotEqual(fittingWindow.cbStructureFactor.findText("stickyhardsphere"),-1)
144        self.assertNotEqual(fittingWindow.cbStructureFactor.findText("hayter_msa"),-1)
145        self.assertNotEqual(fittingWindow.cbStructureFactor.findText("squarewell"),-1)
146        self.assertNotEqual(fittingWindow.cbStructureFactor.findText("hardsphere"),-1)
147
148        #Test what is current text in the combobox
149        self.assertTrue(fittingWindow.cbCategory.currentText(), "None")
150
151    def testSignals(self):
152        """
[351b53e]153        Test the widget emitted signals
[811bec1]154        """
155        pass
156
157    def  testSelectCategory(self):
158        """
159        Assure proper behaviour on changing category
160        """
[351b53e]161        self.widget.show()
162        self.assertEqual(self.widget._previous_category_index, 0)
163        # confirm the model combo contains no models
164        self.assertEqual(self.widget.cbModel.count(), 0)
165
166        # invoke the method by changing the index
167        self.widget.cbCategory.setCurrentIndex(1)
168
169        # test the model combo content
170        self.assertEqual(self.widget.cbModel.count(), 29)
171
172        # Try to change back to default
173        self.widget.cbCategory.setCurrentIndex(0)
174
175        # Observe no such luck
176        self.assertEqual(self.widget.cbCategory.currentIndex(), 1)
177        self.assertEqual(self.widget.cbModel.count(), 29)
178
179        # Set the structure factor
180        structure_index=self.widget.cbCategory.findText(CATEGORY_STRUCTURE)
181        self.widget.cbCategory.setCurrentIndex(structure_index)
182        # check the enablement of controls
183        self.assertFalse(self.widget.cbModel.isEnabled())
184        self.assertTrue(self.widget.cbStructureFactor.isEnabled())
[811bec1]185
186    def testSelectModel(self):
187        """
188        Assure proper behaviour on changing model
189        """
[351b53e]190        self.widget.show()
191        # Change the category index so we have some models
192        self.widget.cbCategory.setCurrentIndex(1)
193
194        # check the enablement of controls
195        self.assertTrue(self.widget.cbModel.isEnabled())
196        self.assertFalse(self.widget.cbStructureFactor.isEnabled())
197
198        # set up the model update spy
199        # spy = QtSignalSpy(self.widget._model_model, self.widget._model_model.itemChanged)
200
201        # mock the tested methods
202        self.widget.SASModelToQModel = MagicMock()
203        self.widget.createDefaultDataset = MagicMock()
204        self.widget.calculateDataForModel = MagicMock()
205        #
206        # Now change the model
207        self.widget.cbModel.setCurrentIndex(3)
208        self.assertEqual(self.widget.cbModel.currentText(),'correlation_length')
209
210        # No data sent -> no index set, only createDefaultDataset called
211        self.assertTrue(self.widget.createDefaultDataset.called)
212        self.assertTrue(self.widget.SASModelToQModel.called)
213        self.assertFalse(self.widget.calculateDataForModel.called)
214
215        # Let's set a dummy index on widget
216        self.widget._index = QtGui.QStandardItem()
217        # Reset the sasmodel index
218        self.widget.cbModel.setCurrentIndex(1)
219        self.assertEqual(self.widget.cbModel.currentText(),'be_polyelectrolyte')
220
221        # Observe calculateDataForModel called
222        self.assertTrue(self.widget.calculateDataForModel.called)
[811bec1]223
224    def testSelectFactor(self):
225        """
226        Assure proper behaviour on changing structure factor
227        """
[351b53e]228        self.widget.show()
229        # Change the category index so we have some models
230        self.widget.cbCategory.setCurrentIndex(1)
231        # Change the model to one that supports structure factors
232        model_index = self.widget.cbModel.findText('fractal_core_shell')
233        self.widget.cbModel.setCurrentIndex(model_index)
234
235        # Check that the factor combo is active and the default is chosen
236        self.assertTrue(self.widget.cbStructureFactor.isEnabled())
237        self.assertEqual(self.widget.cbStructureFactor.currentText(), STRUCTURE_DEFAULT)
238
239        # We have this many rows in the model
240        rowcount = self.widget._model_model.rowCount()
241        #self.assertEqual(self.widget._model_model.rowCount(), 8)
242
243        # Change structure factor to something more exciting
244        structure_index = self.widget.cbStructureFactor.findText('squarewell')
245        self.widget.cbStructureFactor.setCurrentIndex(structure_index)
246
247        # We have 4 more rows now
248        self.assertEqual(self.widget._model_model.rowCount(), rowcount+4)
249
250        # Switch models
251        self.widget.cbModel.setCurrentIndex(0)
252
253        # Observe factor reset to None
254        self.assertEqual(self.widget.cbStructureFactor.currentText(), STRUCTURE_DEFAULT)
255
256
257        # TODO once functionality fixed
258        ## Switch category to structure factor
259        #structure_index=self.widget.cbCategory.findText(CATEGORY_STRUCTURE)
260        #self.widget.cbCategory.setCurrentIndex(structure_index)
261        ## Choose the last factor
262        #last_index = self.widget.cbStructureFactor.count()
263        #self.widget.cbStructureFactor.setCurrentIndex(last_index-1)
[811bec1]264
265    def testReadCategoryInfo(self):
266        """
267        Check the category file reader
268        """
[351b53e]269        # Tested in default checks
[811bec1]270        pass
271
272    def testUpdateParamsFromModel(self):
273        """
274        Checks the sasmodel parameter update from QModel items
275        """
[351b53e]276        # Tested in default checks
[811bec1]277        pass
278
[351b53e]279    def notestCreateTheoryIndex(self):
[811bec1]280        """
[351b53e]281        Test the data->QIndex conversion
[811bec1]282        """
[351b53e]283        # set up the model update spy
284        spy = QtSignalSpy(self.widget._model_model, self.widget.communicate.updateTheoryFromPerspectiveSignal)
[811bec1]285
[351b53e]286        self.widget.show()
287        # Change the category index so we have some models
288        self.widget.cbCategory.setCurrentIndex(1)
[811bec1]289
[351b53e]290        # Create the index
291        self.widget.createTheoryIndex()
[811bec1]292
[351b53e]293        # Check the signal sent
294        print spy
[811bec1]295
[351b53e]296        # Check the index
[811bec1]297
[351b53e]298    def testCalculateDataForModel(self):
[811bec1]299        """
[351b53e]300        Check that the fitting 1D data object is ready
[811bec1]301        """
[351b53e]302        # Mock the thread creation
303        threads.deferToThread = MagicMock()
304        # Call the tested method
305        self.widget.calculateDataForModel()
306        # Test the mock
307        self.assertTrue(threads.deferToThread.called)
308        self.assertEqual(threads.deferToThread.call_args_list[0][0][0].__name__, "compute")
[811bec1]309
310    def testComplete1D(self):
311        """
312        Check that a new 1D plot is generated
313        """
[351b53e]314        # TODO when chisqr method coded
[811bec1]315        pass
316
317    def testComplete2D(self):
318        """
319        Check that a new 2D plot is generated
320        """
[351b53e]321        # TODO when chisqr method coded
[811bec1]322        pass
323
324    def testSetPolyModel(self):
325        """
326        Test the polydispersity model setup
327        """
[351b53e]328        self.widget.show()
329        # Change the category index so we have a model with no poly
330        self.widget.cbCategory.setCurrentIndex(1)
331        # Check the poly model
332        self.assertEqual(self.widget._poly_model.rowCount(), 0)
333        self.assertEqual(self.widget._poly_model.columnCount(), 0)
334
335        # Change the category index so we have a model available
336        self.widget.cbCategory.setCurrentIndex(2)
337
338        # Check the poly model
339        self.assertEqual(self.widget._poly_model.rowCount(), 3)
340        self.assertEqual(self.widget._poly_model.columnCount(), 7)
341
342        # Test the header
343        self.assertEqual(self.widget.lstPoly.horizontalHeader().count(), 7)
344        self.assertFalse(self.widget.lstPoly.horizontalHeader().stretchLastSection())
345
346        # Test presence of comboboxes in last column
347        for row in xrange(self.widget._poly_model.rowCount()):
348            func_index = self.widget._poly_model.index(row, 6)
349            self.assertTrue(isinstance(self.widget.lstPoly.indexWidget(func_index), QtGui.QComboBox))
350            self.assertIn('Distribution of', self.widget._poly_model.item(row, 0).text())
[811bec1]351
352    def testSetMagneticModel(self):
353        """
354        Test the magnetic model setup
355        """
[351b53e]356        self.widget.show()
357        # Change the category index so we have a model available
358        self.widget.cbCategory.setCurrentIndex(2)
359
360        # Check the magnetic model
361        self.assertEqual(self.widget._magnet_model.rowCount(), 9)
362        self.assertEqual(self.widget._magnet_model.columnCount(), 5)
363
364        # Test the header
365        self.assertEqual(self.widget.lstMagnetic.horizontalHeader().count(), 5)
366        self.assertFalse(self.widget.lstMagnetic.horizontalHeader().stretchLastSection())
367
368        # Test rows
369        for row in xrange(self.widget._magnet_model.rowCount()):
370            func_index = self.widget._magnet_model.index(row, 0)
371            self.assertIn(':', self.widget._magnet_model.item(row, 0).text())
372
[811bec1]373
374    def testAddExtraShells(self):
375        """
376        Test how the extra shells are presented
377        """
378        pass
379
380    def testModifyShellsInList(self):
381        """
382        Test the additional rows added by modifying the shells combobox
383        """
[351b53e]384        self.widget.show()
385        # Change the model to multi shell
386        self.widget.cbCategory.setCurrentIndex(2)
387        self.widget.cbModel.setCurrentIndex(4)
388
389        # Assure we have the combobox available
390        last_row = self.widget._last_model_row
391        func_index = self.widget._model_model.index(last_row-1, 1)
392        self.assertIsInstance(self.widget.lstParams.indexWidget(func_index), QtGui.QComboBox)
393
394        # Change the combo box index
395        self.widget.lstParams.indexWidget(func_index).setCurrentIndex(3)
396
397        # Check that the number of rows increased
398        more_rows = self.widget._model_model.rowCount() - last_row
399        self.assertEqual(more_rows, 6) # 6 new rows: 2 params per index
400
401        # Back to 0
402        self.widget.lstParams.indexWidget(func_index).setCurrentIndex(0)
403        self.assertEqual(self.widget._model_model.rowCount(), last_row)
[811bec1]404
405
406if __name__ == "__main__":
407    unittest.main()
Note: See TracBrowser for help on using the repository browser.