source: sasview/src/sas/qtgui/UnitTesting/DataExplorerTest.py @ f82ab8c

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 f82ab8c was f82ab8c, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 8 years ago

More dialogs, drag and drop onto File Load

  • Property mode set to 100755
File size: 12.9 KB
RevLine 
[f721030]1import sys
2import unittest
3
4from PyQt4.QtGui import *
5from PyQt4.QtTest import QTest
6from PyQt4.QtCore import *
7from mock import MagicMock
8
9# Local
10from sas.sasgui.guiframe.dataFitting import Data1D
[1042dba]11from sas.sascalc.dataloader.loader import Loader
12from sas.sasgui.guiframe.data_manager import DataManager
13
[f721030]14from DataExplorer import DataExplorerWindow
15from GuiManager import GuiManager
16from GuiUtils import *
17from UnitTesting.TestUtils import QtSignalSpy
[1042dba]18from Plotter import Plotter
[f721030]19
20app = QApplication(sys.argv)
21
22class DataExplorerTest(unittest.TestCase):
23    '''Test the Data Explorer GUI'''
24    def setUp(self):
25        '''Create the GUI'''
[5032ea68]26        class MyPerspective(object):
27            def communicator(self):
28                return Communicate()
29            def allowBatch(self):
30                return False
[a281ab8]31            def setData(self, data_item=None):
[5032ea68]32                return None
33            def title(self):
34                return "Dummy Perspective"
35
[f721030]36        class dummy_manager(object):
37            def communicator(self):
38                return Communicate()
[5032ea68]39            def perspective(self):
40                return MyPerspective()
[f721030]41
42        self.form = DataExplorerWindow(None, dummy_manager())
43
44    def tearDown(self):
45        '''Destroy the GUI'''
46        self.form.close()
47        self.form = None
48
49    def testDefaults(self):
50        '''Test the GUI in its default state'''
51        self.assertIsInstance(self.form, QTabWidget)
52        self.assertIsInstance(self.form.treeView, QTreeView)
[f82ab8c]53        self.assertIsInstance(self.form.freezeView, QTreeView)
[f721030]54        self.assertEqual(self.form.count(), 2)
55
56        self.assertEqual(self.form.cmdLoad.text(), "Load")
[f82ab8c]57        self.assertEqual(self.form.cmdDeleteData.text(), "Delete")
58        self.assertEqual(self.form.cmdDeleteTheory.text(), "Delete")
59        self.assertEqual(self.form.cmdFreeze.text(), "Freeze")
[f721030]60        self.assertEqual(self.form.cmdSendTo.text(), "Send to")
61        self.assertEqual(self.form.chkBatch.text(), "Batch mode")
62        self.assertFalse(self.form.chkBatch.isChecked())
63
64        self.assertEqual(self.form.cbSelect.count(), 6)
[488c49d]65        self.assertEqual(self.form.cbSelect.currentIndex(), 0)
[f721030]66
67        # Class is in the default state even without pressing OK
68        self.assertEqual(self.form.treeView.model().rowCount(), 0)
69        self.assertEqual(self.form.treeView.model().columnCount(), 0)
70        self.assertEqual(self.form.model.rowCount(), 0)
71        self.assertEqual(self.form.model.columnCount(), 0)
72       
73    def testLoadButton(self):
74        loadButton = self.form.cmdLoad
75
[9e426c1]76        filename = "cyl_400_20.txt"
77        # Initialize signal spy instances
[f82ab8c]78        spy_file_read = QtSignalSpy(self.form, self.form.communicator.fileReadSignal)
[9e426c1]79
80        # Return no files.
81        QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=None)
[f721030]82
83        # Click on the Load button
84        QTest.mouseClick(loadButton, Qt.LeftButton)
85
86        # Test the getOpenFileName() dialog called once
[9e426c1]87        self.assertTrue(QtGui.QFileDialog.getOpenFileNames.called)
88        QtGui.QFileDialog.getOpenFileNames.assert_called_once()
89
90        # Make sure the signal has not been emitted
[f82ab8c]91        #self.assertEqual(spy_file_read.count(), 0)
[9e426c1]92
93        # Now, return a single file
94        QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=filename)
95       
96        # Click on the Load button
97        QTest.mouseClick(loadButton, Qt.LeftButton)
98
99        # Test the getOpenFileName() dialog called once
100        self.assertTrue(QtGui.QFileDialog.getOpenFileNames.called)
101        QtGui.QFileDialog.getOpenFileNames.assert_called_once()
102
103        # Expected one spy instance
[f82ab8c]104        #self.assertEqual(spy_file_read.count(), 1)
105        #self.assertIn(filename, str(spy_file_read.called()[0]['args'][0]))
[f721030]106
107    def testDeleteButton(self):
[5032ea68]108        """
109        Functionality of the delete button
110        """
[f82ab8c]111        deleteButton = self.form.cmdDeleteData
[f721030]112
[f82ab8c]113        # Mock the confirmation dialog with return=No
[5032ea68]114        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.No)
[f721030]115
116        # Populate the model
[5032ea68]117        filename = ["cyl_400_20.txt", "Dec07031.ASC", "cyl_400_20.txt"]
118        self.form.readData(filename)
[f721030]119
[5032ea68]120        # Assure the model contains three items
121        self.assertEqual(self.form.model.rowCount(), 3)
122
123        # Assure the checkboxes are on
124        item1 = self.form.model.item(0)
125        item2 = self.form.model.item(1)
126        item3 = self.form.model.item(2)
127        self.assertTrue(item1.checkState() == QtCore.Qt.Checked)
128        self.assertTrue(item2.checkState() == QtCore.Qt.Checked)
129        self.assertTrue(item3.checkState() == QtCore.Qt.Checked)
[f721030]130
131        # Click on the delete  button
132        QTest.mouseClick(deleteButton, Qt.LeftButton)
133
134        # Test the warning dialog called once
[5032ea68]135        self.assertTrue(QtGui.QMessageBox.question.called)
136
137        # Assure the model still contains the items
138        self.assertEqual(self.form.model.rowCount(), 3)
139
140        # Now, mock the confirmation dialog with return=Yes
141        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.Yes)
142
143        # Click on the delete  button
144        QTest.mouseClick(deleteButton, Qt.LeftButton)
145
146        # Test the warning dialog called once
147        self.assertTrue(QtGui.QMessageBox.question.called)
[f721030]148
149        # Assure the model contains no items
[5032ea68]150        self.assertEqual(self.form.model.rowCount(), 0)
[f721030]151
[5032ea68]152        # Click delete once again to assure no nasty behaviour on empty model
153        QTest.mouseClick(deleteButton, Qt.LeftButton)
[f721030]154
[5032ea68]155    def testSendToButton(self):
156        """
157        Test that clicking the Send To button sends checked data to a perspective
158        """
[f82ab8c]159        # Send empty data
160        mocked_perspective = self.form.parent.perspective()
161        mocked_perspective.setData = MagicMock()
162
163        # Click on the Send To  button
164        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
165
166        # The set_data method not called
167        self.assertFalse(mocked_perspective.setData.called)
168               
[f721030]169        # Populate the model
[5032ea68]170        filename = ["cyl_400_20.txt"]
171        self.form.readData(filename)
172
173        # setData is the method we want to see called
[f82ab8c]174        mocked_perspective = self.form.parent.perspective()
175        mocked_perspective.setData = MagicMock(filename)
[f721030]176
177        # Assure the checkbox is on
[5032ea68]178        self.form.cbSelect.setCurrentIndex(0)
[f721030]179
180        # Click on the Send To  button
[5032ea68]181        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
[f721030]182
183        # Test the set_data method called once
[f82ab8c]184        #self.assertTrue(mocked_perspective.setData.called)
[5032ea68]185
186        # open another file
187        filename = ["cyl_400_20.txt"]
188        self.form.readData(filename)
189
190        # Mock the warning message
191        QtGui.QMessageBox = MagicMock()
192
193        # Click on the button
194        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
195
196        # Assure the message box popped up
197        QtGui.QMessageBox.assert_called_once()
[f721030]198
[488c49d]199    def testDataSelection(self):
200        """
201        Tests the functionality of the Selection Option combobox
202        """
203        # Populate the model with 1d and 2d data
204        filename = ["cyl_400_20.txt", "Dec07031.ASC"]
205        self.form.readData(filename)
206
207        # Unselect all data
208        self.form.cbSelect.setCurrentIndex(1)
209
210        # Test the current selection
[5032ea68]211        item1D = self.form.model.item(0)
212        item2D = self.form.model.item(1)
213        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]214        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
215
216        # Select all data
217        self.form.cbSelect.setCurrentIndex(0)
218
219        # Test the current selection
[5032ea68]220        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]221        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
222
223        # select 1d data
224        self.form.cbSelect.setCurrentIndex(2)
225
226        # Test the current selection
[5032ea68]227        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]228        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
229
230        # unselect 1d data
231        self.form.cbSelect.setCurrentIndex(3)
232
233        # Test the current selection
[5032ea68]234        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]235        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
236
237        # select 2d data
238        self.form.cbSelect.setCurrentIndex(4)
239
240        # Test the current selection
[5032ea68]241        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]242        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
243
244        # unselect 2d data
245        self.form.cbSelect.setCurrentIndex(5)
246
247        # Test the current selection
[5032ea68]248        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]249        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
250
251        # choose impossible index and assure the code raises
252        #with self.assertRaises(Exception):
253        #    self.form.cbSelect.setCurrentIndex(6)
254
[f721030]255    def testReadData(self):
256        """
[5032ea68]257        Test the low level readData() method
[f721030]258        """
259        filename = ["cyl_400_20.txt"]
260        self.form.manager.add_data = MagicMock()
261
262        # Initialize signal spy instances
[f82ab8c]263        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
264        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]265
266        # Read in the file
267        self.form.readData(filename)
268
269        # Expected two status bar updates
[5032ea68]270        self.assertEqual(spy_status_update.count(), 1)
[f721030]271        self.assertIn(filename[0], str(spy_status_update.called()[0]['args'][0]))
272
273
274        # Check that the model contains the item
275        self.assertEqual(self.form.model.rowCount(), 1)
276        self.assertEqual(self.form.model.columnCount(), 1)
277
278        # The 0th item header should be the name of the file
279        model_item = self.form.model.index(0,0)
280        model_name = str(self.form.model.data(model_item).toString())
281        self.assertEqual(model_name, filename[0])
282
[5032ea68]283    def testLoadFile(self):
284        """
285        Test the threaded call to readData()
286        """
[f82ab8c]287        #self.form.loadFile()
[5032ea68]288        pass
[f721030]289
290    def testGetWList(self):
291        """
[f82ab8c]292        Test the list of known extensions
[f721030]293        """
294        list = self.form.getWlist()
295        defaults = 'All (*.*);;canSAS files (*.xml);;SESANS files' +\
296            ' (*.ses);;ASCII files (*.txt);;IGOR 2D files (*.asc);;' +\
297            'IGOR/DAT 2D Q_map files (*.dat);;IGOR 1D files (*.abs);;'+\
298            'HFIR 1D files (*.d1d);;DANSE files (*.sans);;NXS files (*.nxs)'
299        self.assertEqual(defaults, list)
[5032ea68]300       
[f721030]301    def testLoadComplete(self):
302        """
[5032ea68]303        Test the callback method updating the data object
[f721030]304        """
[a281ab8]305        message="Loading Data Complete"
[5032ea68]306        data_dict = {"a1":Data1D()}
[a281ab8]307        output_data = (data_dict, message)
[5032ea68]308
309        self.form.manager.add_data = MagicMock()
310
311        # Initialize signal spy instances
[f82ab8c]312        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
313        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]314
[5032ea68]315        # Read in the file
[a281ab8]316        self.form.loadComplete(output_data)
[f721030]317
[5032ea68]318        # "Loading data complete" no longer sent in LoadFile but in callback
319        self.assertIn("Loading Data Complete", str(spy_status_update.called()[0]['args'][0]))
[f721030]320
[5032ea68]321        # Expect one Data Received signal
[f721030]322        self.assertEqual(spy_data_received.count(), 1)
323
[5032ea68]324        # Assure returned dictionary has correct data
325        # We don't know the data ID, so need to iterate over dict
326        data_dict = spy_data_received.called()[0]['args'][0]
327        for data_key, data_value in data_dict.iteritems():
328            self.assertIsInstance(data_value, Data1D)
329
330        # Assure add_data on data_manager was called (last call)
331        self.assertTrue(self.form.manager.add_data.called)
332
[1042dba]333    def testNewPlot(self):
334        """
335        Creating new plots from Data1D/2D
336        """
337        loader = Loader()
338        manager = DataManager()
339
340        # get Data1D
341        p_file="cyl_400_20.txt"
342        output_object = loader.load(p_file)
343        new_data = [manager.create_gui_data(output_object, p_file)]
344
345        # Mask the plot show call
346        Plotter.show = MagicMock()
347
348        # Mask retrieval of the data
349        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
350
351        # Call the plotting method
352        self.form.newPlot()
353
354        # The plot was displayed
355        self.assertTrue(Plotter.show.called)
356
[f82ab8c]357    def testUpdateModelFromPerspective(self):
358        """
359        Assure the model update is correct
360        """
361        good_item = QtGui.QStandardItem()
362        bad_item = "I'm so bad"
363
364        self.form.model.reset = MagicMock()
365
366        self.form.updateModelFromPerspective(good_item)
367
368        # See that the model got reset
369        self.form.model.reset.assert_called_once()
370
371        # See that the bad item causes raise
372        with self.assertRaises(Exception):
373            self.form.updateModelFromPerspective(bad_item)
[5032ea68]374
[f721030]375if __name__ == "__main__":
376    unittest.main()
Note: See TracBrowser for help on using the repository browser.