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
Line 
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
11from sas.sascalc.dataloader.loader import Loader
12from sas.sasgui.guiframe.data_manager import DataManager
13
14from DataExplorer import DataExplorerWindow
15from GuiManager import GuiManager
16from GuiUtils import *
17from UnitTesting.TestUtils import QtSignalSpy
18from Plotter import Plotter
19
20app = QApplication(sys.argv)
21
22class DataExplorerTest(unittest.TestCase):
23    '''Test the Data Explorer GUI'''
24    def setUp(self):
25        '''Create the GUI'''
26        class MyPerspective(object):
27            def communicator(self):
28                return Communicate()
29            def allowBatch(self):
30                return False
31            def setData(self, data_item=None):
32                return None
33            def title(self):
34                return "Dummy Perspective"
35
36        class dummy_manager(object):
37            def communicator(self):
38                return Communicate()
39            def perspective(self):
40                return MyPerspective()
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)
53        self.assertIsInstance(self.form.freezeView, QTreeView)
54        self.assertEqual(self.form.count(), 2)
55
56        self.assertEqual(self.form.cmdLoad.text(), "Load")
57        self.assertEqual(self.form.cmdDeleteData.text(), "Delete")
58        self.assertEqual(self.form.cmdDeleteTheory.text(), "Delete")
59        self.assertEqual(self.form.cmdFreeze.text(), "Freeze")
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)
65        self.assertEqual(self.form.cbSelect.currentIndex(), 0)
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
76        filename = "cyl_400_20.txt"
77        # Initialize signal spy instances
78        spy_file_read = QtSignalSpy(self.form, self.form.communicator.fileReadSignal)
79
80        # Return no files.
81        QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=None)
82
83        # Click on the Load button
84        QTest.mouseClick(loadButton, Qt.LeftButton)
85
86        # Test the getOpenFileName() dialog called once
87        self.assertTrue(QtGui.QFileDialog.getOpenFileNames.called)
88        QtGui.QFileDialog.getOpenFileNames.assert_called_once()
89
90        # Make sure the signal has not been emitted
91        #self.assertEqual(spy_file_read.count(), 0)
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
104        #self.assertEqual(spy_file_read.count(), 1)
105        #self.assertIn(filename, str(spy_file_read.called()[0]['args'][0]))
106
107    def testDeleteButton(self):
108        """
109        Functionality of the delete button
110        """
111        deleteButton = self.form.cmdDeleteData
112
113        # Mock the confirmation dialog with return=No
114        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.No)
115
116        # Populate the model
117        filename = ["cyl_400_20.txt", "Dec07031.ASC", "cyl_400_20.txt"]
118        self.form.readData(filename)
119
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)
130
131        # Click on the delete  button
132        QTest.mouseClick(deleteButton, Qt.LeftButton)
133
134        # Test the warning dialog called once
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)
148
149        # Assure the model contains no items
150        self.assertEqual(self.form.model.rowCount(), 0)
151
152        # Click delete once again to assure no nasty behaviour on empty model
153        QTest.mouseClick(deleteButton, Qt.LeftButton)
154
155    def testSendToButton(self):
156        """
157        Test that clicking the Send To button sends checked data to a perspective
158        """
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               
169        # Populate the model
170        filename = ["cyl_400_20.txt"]
171        self.form.readData(filename)
172
173        # setData is the method we want to see called
174        mocked_perspective = self.form.parent.perspective()
175        mocked_perspective.setData = MagicMock(filename)
176
177        # Assure the checkbox is on
178        self.form.cbSelect.setCurrentIndex(0)
179
180        # Click on the Send To  button
181        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
182
183        # Test the set_data method called once
184        #self.assertTrue(mocked_perspective.setData.called)
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()
198
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
211        item1D = self.form.model.item(0)
212        item2D = self.form.model.item(1)
213        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
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
220        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
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
227        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
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
234        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
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
241        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
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
248        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
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
255    def testReadData(self):
256        """
257        Test the low level readData() method
258        """
259        filename = ["cyl_400_20.txt"]
260        self.form.manager.add_data = MagicMock()
261
262        # Initialize signal spy instances
263        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
264        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
265
266        # Read in the file
267        self.form.readData(filename)
268
269        # Expected two status bar updates
270        self.assertEqual(spy_status_update.count(), 1)
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
283    def testLoadFile(self):
284        """
285        Test the threaded call to readData()
286        """
287        #self.form.loadFile()
288        pass
289
290    def testGetWList(self):
291        """
292        Test the list of known extensions
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)
300       
301    def testLoadComplete(self):
302        """
303        Test the callback method updating the data object
304        """
305        message="Loading Data Complete"
306        data_dict = {"a1":Data1D()}
307        output_data = (data_dict, message)
308
309        self.form.manager.add_data = MagicMock()
310
311        # Initialize signal spy instances
312        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
313        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
314
315        # Read in the file
316        self.form.loadComplete(output_data)
317
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]))
320
321        # Expect one Data Received signal
322        self.assertEqual(spy_data_received.count(), 1)
323
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
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
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)
374
375if __name__ == "__main__":
376    unittest.main()
Note: See TracBrowser for help on using the repository browser.