source: sasview/src/sas/qtgui/MainWindow/UnitTesting/DataExplorerTest.py @ 7fb471d

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 7fb471d was 7fb471d, checked in by Piotr Rozyczko <rozyczko@…>, 6 years ago

Update for unit tests and minor functionality quirks

  • Property mode set to 100755
File size: 27.3 KB
RevLine 
[f721030]1import sys
2import unittest
3
4from PyQt4.QtGui import *
5from PyQt4.QtTest import QTest
6from PyQt4.QtCore import *
[7fb471d]7from unittest.mock import MagicMock
8from unittest.mock import patch
[cad617b]9from mpl_toolkits.mplot3d import Axes3D
[31c5b58]10
11# set up import paths
12import path_prepare
[f721030]13
14# Local
[dc5ef15]15from sas.qtgui.Plotting.PlotterData import Data1D
[1042dba]16from sas.sascalc.dataloader.loader import Loader
[dc5ef15]17from sas.qtgui.MainWindow.DataManager import DataManager
[1042dba]18
[83eb5208]19from sas.qtgui.MainWindow.DataExplorer import DataExplorerWindow
20from sas.qtgui.MainWindow.GuiManager import GuiManager
21from sas.qtgui.Utilities.GuiUtils import *
[f721030]22from UnitTesting.TestUtils import QtSignalSpy
[83eb5208]23from sas.qtgui.Plotting.Plotter import Plotter
24from sas.qtgui.Plotting.Plotter2D import Plotter2D
25import sas.qtgui.Plotting.PlotHelper as PlotHelper
[f721030]26
[88e1f57]27if not QApplication.instance():
28    app = QApplication(sys.argv)
[f721030]29
30class DataExplorerTest(unittest.TestCase):
31    '''Test the Data Explorer GUI'''
32    def setUp(self):
33        '''Create the GUI'''
[5032ea68]34        class MyPerspective(object):
35            def communicator(self):
36                return Communicate()
37            def allowBatch(self):
38                return False
[f7d14a1]39            def setData(self, data_item=None, is_batch=False):
[5032ea68]40                return None
41            def title(self):
42                return "Dummy Perspective"
43
[f721030]44        class dummy_manager(object):
45            def communicator(self):
46                return Communicate()
[5032ea68]47            def perspective(self):
48                return MyPerspective()
[8cb6cd6]49            def workspace(self):
50                return None
[f721030]51
52        self.form = DataExplorerWindow(None, dummy_manager())
53
54    def tearDown(self):
55        '''Destroy the GUI'''
56        self.form.close()
57        self.form = None
58
59    def testDefaults(self):
60        '''Test the GUI in its default state'''
[481ff26]61        # Tab widget
[f721030]62        self.assertIsInstance(self.form, QTabWidget)
63        self.assertEqual(self.form.count(), 2)
64
[481ff26]65        # Buttons - data tab
[6fd4e36]66        self.assertEqual(self.form.cmdLoad.text(), "Load data")
[f82ab8c]67        self.assertEqual(self.form.cmdDeleteData.text(), "Delete")
68        self.assertEqual(self.form.cmdDeleteTheory.text(), "Delete")
[481ff26]69        self.assertEqual(self.form.cmdFreeze.text(), "Freeze Theory")
[6fd4e36]70        self.assertEqual(self.form.cmdSendTo.text(), "Send data to")
71        self.assertEqual(self.form.cmdSendTo.iconSize(), QSize(48, 48))
[481ff26]72        self.assertIsInstance(self.form.cmdSendTo.icon(), QIcon)
[f721030]73        self.assertEqual(self.form.chkBatch.text(), "Batch mode")
74        self.assertFalse(self.form.chkBatch.isChecked())
75
[481ff26]76        # Buttons - theory tab
77
78        # Combo boxes
[f721030]79        self.assertEqual(self.form.cbSelect.count(), 6)
[488c49d]80        self.assertEqual(self.form.cbSelect.currentIndex(), 0)
[f721030]81
[481ff26]82        # Models - data
83        self.assertIsInstance(self.form.model, QStandardItemModel)
[f721030]84        self.assertEqual(self.form.treeView.model().rowCount(), 0)
85        self.assertEqual(self.form.treeView.model().columnCount(), 0)
86        self.assertEqual(self.form.model.rowCount(), 0)
87        self.assertEqual(self.form.model.columnCount(), 0)
[481ff26]88        self.assertIsInstance(self.form.data_proxy, QSortFilterProxyModel)
89        self.assertEqual(self.form.data_proxy.sourceModel(), self.form.model)
90        self.assertEqual("[^()]", str(self.form.data_proxy.filterRegExp().pattern()))
91        self.assertIsInstance(self.form.treeView, QTreeView)
92
93        # Models - theory
94        self.assertIsInstance(self.form.theory_model, QStandardItemModel)
95        self.assertEqual(self.form.freezeView.model().rowCount(), 0)
96        self.assertEqual(self.form.freezeView.model().columnCount(), 0)
97        self.assertEqual(self.form.theory_model.rowCount(), 0)
98        self.assertEqual(self.form.theory_model.columnCount(), 0)
99        self.assertIsInstance(self.form.theory_proxy, QSortFilterProxyModel)
100        self.assertEqual(self.form.theory_proxy.sourceModel(), self.form.theory_model)
101        self.assertEqual("[^()]", str(self.form.theory_proxy.filterRegExp().pattern()))
102        self.assertIsInstance(self.form.freezeView, QTreeView)
103
[e540cd2]104    def testWidgets(self):
105        """
106        Test if all required widgets got added
[0cd8612]107        """
[f721030]108    def testLoadButton(self):
109        loadButton = self.form.cmdLoad
110
[9e426c1]111        filename = "cyl_400_20.txt"
112        # Initialize signal spy instances
[f82ab8c]113        spy_file_read = QtSignalSpy(self.form, self.form.communicator.fileReadSignal)
[9e426c1]114
115        # Return no files.
116        QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=None)
[f721030]117
118        # Click on the Load button
119        QTest.mouseClick(loadButton, Qt.LeftButton)
120
121        # Test the getOpenFileName() dialog called once
[9e426c1]122        self.assertTrue(QtGui.QFileDialog.getOpenFileNames.called)
123        QtGui.QFileDialog.getOpenFileNames.assert_called_once()
124
125        # Make sure the signal has not been emitted
[e540cd2]126        self.assertEqual(spy_file_read.count(), 0)
[9e426c1]127
128        # Now, return a single file
129        QtGui.QFileDialog.getOpenFileNames = MagicMock(return_value=filename)
[e540cd2]130
[9e426c1]131        # Click on the Load button
132        QTest.mouseClick(loadButton, Qt.LeftButton)
[e540cd2]133        QtGui.qApp.processEvents()
[9e426c1]134
135        # Test the getOpenFileName() dialog called once
136        self.assertTrue(QtGui.QFileDialog.getOpenFileNames.called)
137        QtGui.QFileDialog.getOpenFileNames.assert_called_once()
138
139        # Expected one spy instance
[f82ab8c]140        #self.assertEqual(spy_file_read.count(), 1)
141        #self.assertIn(filename, str(spy_file_read.called()[0]['args'][0]))
[f721030]142
[e540cd2]143    def testLoadFiles(self):
144        """
145        Test progress bar update while loading of multiple files
146        """
147        # Set up the spy on progress bar update signal
148        spy_progress_bar_update = QtSignalSpy(self.form,
149            self.form.communicator.progressBarUpdateSignal)
150
151        # Populate the model
[f4a1433]152        filename = ["cyl_400_20.txt", "P123_D2O_10_percent.dat", "cyl_400_20.txt"]
[e540cd2]153        self.form.readData(filename)
154
155        # 0, 0, 33, 66, -1 -> 5 signals reaching progressBar
156        self.assertEqual(spy_progress_bar_update.count(), 5)
157
158        expected_list = [0, 0, 33, 66, -1]
[7fb471d]159        spied_list = [spy_progress_bar_update.called()[i]['args'][0] for i in range(5)]
[e540cd2]160        self.assertEqual(expected_list, spied_list)
161       
[f721030]162    def testDeleteButton(self):
[5032ea68]163        """
164        Functionality of the delete button
165        """
[f82ab8c]166        deleteButton = self.form.cmdDeleteData
[f721030]167
[f82ab8c]168        # Mock the confirmation dialog with return=No
[5032ea68]169        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.No)
[f721030]170
171        # Populate the model
[f7d14a1]172        filename = ["cyl_400_20.txt", "cyl_400_20.txt", "cyl_400_20.txt"]
[5032ea68]173        self.form.readData(filename)
[f721030]174
[5032ea68]175        # Assure the model contains three items
176        self.assertEqual(self.form.model.rowCount(), 3)
177
178        # Assure the checkboxes are on
179        item1 = self.form.model.item(0)
180        item2 = self.form.model.item(1)
181        item3 = self.form.model.item(2)
182        self.assertTrue(item1.checkState() == QtCore.Qt.Checked)
183        self.assertTrue(item2.checkState() == QtCore.Qt.Checked)
184        self.assertTrue(item3.checkState() == QtCore.Qt.Checked)
[f721030]185
186        # Click on the delete  button
187        QTest.mouseClick(deleteButton, Qt.LeftButton)
188
189        # Test the warning dialog called once
[5032ea68]190        self.assertTrue(QtGui.QMessageBox.question.called)
191
192        # Assure the model still contains the items
193        self.assertEqual(self.form.model.rowCount(), 3)
194
195        # Now, mock the confirmation dialog with return=Yes
196        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.Yes)
197
198        # Click on the delete  button
199        QTest.mouseClick(deleteButton, Qt.LeftButton)
200
201        # Test the warning dialog called once
202        self.assertTrue(QtGui.QMessageBox.question.called)
[f721030]203
204        # Assure the model contains no items
[5032ea68]205        self.assertEqual(self.form.model.rowCount(), 0)
[f721030]206
[5032ea68]207        # Click delete once again to assure no nasty behaviour on empty model
208        QTest.mouseClick(deleteButton, Qt.LeftButton)
[f721030]209
[481ff26]210    def testDeleteTheory(self):
211        """
212        Test that clicking "Delete" in theories tab removes selected indices
213        """
214        deleteButton = self.form.cmdDeleteTheory
215
216        # Mock the confirmation dialog with return=No
217        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.No)
218
219        # Populate the model
220        item1 = QtGui.QStandardItem(True)
221        item1.setCheckable(True)
222        item1.setCheckState(QtCore.Qt.Checked)
223        item1.setText("item 1")
224        self.form.theory_model.appendRow(item1)
225        item2 = QtGui.QStandardItem(True)
226        item2.setCheckable(True)
227        item2.setCheckState(QtCore.Qt.Unchecked)
228        item2.setText("item 2")
229        self.form.theory_model.appendRow(item2)
230
231        # Assure the model contains two items
232        self.assertEqual(self.form.theory_model.rowCount(), 2)
233
234        # Assure the checkboxes are on
235        self.assertTrue(item1.checkState() == QtCore.Qt.Checked)
236        self.assertTrue(item2.checkState() == QtCore.Qt.Unchecked)
237
238        # Click on the delete  button
239        QTest.mouseClick(deleteButton, Qt.LeftButton)
240
241        # Test the warning dialog called once
242        self.assertTrue(QtGui.QMessageBox.question.called)
243
244        # Assure the model still contains the items
245        self.assertEqual(self.form.theory_model.rowCount(), 2)
246
247        # Now, mock the confirmation dialog with return=Yes
248        QtGui.QMessageBox.question = MagicMock(return_value=QtGui.QMessageBox.Yes)
249
250        # Click on the delete  button
251        QTest.mouseClick(deleteButton, Qt.LeftButton)
252
253        # Test the warning dialog called once
254        self.assertTrue(QtGui.QMessageBox.question.called)
255
256        # Assure the model contains 1 item
257        self.assertEqual(self.form.theory_model.rowCount(), 1)
258
259        # Set the remaining item to checked
260        self.form.theory_model.item(0).setCheckState(QtCore.Qt.Checked)
261
262        # Click on the delete button again
263        QTest.mouseClick(deleteButton, Qt.LeftButton)
264
265        # Assure the model contains no items
266        self.assertEqual(self.form.theory_model.rowCount(), 0)
267
268        # Click delete once again to assure no nasty behaviour on empty model
269        QTest.mouseClick(deleteButton, Qt.LeftButton)
270
271
[5032ea68]272    def testSendToButton(self):
273        """
274        Test that clicking the Send To button sends checked data to a perspective
275        """
[f82ab8c]276        # Send empty data
277        mocked_perspective = self.form.parent.perspective()
278        mocked_perspective.setData = MagicMock()
279
280        # Click on the Send To  button
281        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
282
283        # The set_data method not called
284        self.assertFalse(mocked_perspective.setData.called)
285               
[f721030]286        # Populate the model
[5032ea68]287        filename = ["cyl_400_20.txt"]
288        self.form.readData(filename)
289
290        # setData is the method we want to see called
[f82ab8c]291        mocked_perspective = self.form.parent.perspective()
292        mocked_perspective.setData = MagicMock(filename)
[f721030]293
294        # Assure the checkbox is on
[5032ea68]295        self.form.cbSelect.setCurrentIndex(0)
[f721030]296
297        # Click on the Send To  button
[5032ea68]298        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
[f721030]299
300        # Test the set_data method called once
[f82ab8c]301        #self.assertTrue(mocked_perspective.setData.called)
[5032ea68]302
303        # open another file
304        filename = ["cyl_400_20.txt"]
305        self.form.readData(filename)
306
307        # Mock the warning message
308        QtGui.QMessageBox = MagicMock()
309
310        # Click on the button
311        QTest.mouseClick(self.form.cmdSendTo, Qt.LeftButton)
312
313        # Assure the message box popped up
314        QtGui.QMessageBox.assert_called_once()
[f721030]315
[488c49d]316    def testDataSelection(self):
317        """
318        Tests the functionality of the Selection Option combobox
319        """
320        # Populate the model with 1d and 2d data
[f4a1433]321        filename = ["cyl_400_20.txt", "P123_D2O_10_percent.dat"]
[488c49d]322        self.form.readData(filename)
323
324        # Unselect all data
325        self.form.cbSelect.setCurrentIndex(1)
326
[7fb471d]327        self.form.show()
328        app.exec_()
329
[488c49d]330        # Test the current selection
[5032ea68]331        item1D = self.form.model.item(0)
332        item2D = self.form.model.item(1)
333        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]334        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
335
336        # Select all data
337        self.form.cbSelect.setCurrentIndex(0)
338
339        # Test the current selection
[5032ea68]340        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]341        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
342
343        # select 1d data
344        self.form.cbSelect.setCurrentIndex(2)
345
346        # Test the current selection
[5032ea68]347        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]348        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
349
350        # unselect 1d data
351        self.form.cbSelect.setCurrentIndex(3)
352
353        # Test the current selection
[5032ea68]354        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]355        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
356
357        # select 2d data
358        self.form.cbSelect.setCurrentIndex(4)
359
360        # Test the current selection
[5032ea68]361        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]362        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
363
364        # unselect 2d data
365        self.form.cbSelect.setCurrentIndex(5)
366
367        # Test the current selection
[5032ea68]368        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]369        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
370
371        # choose impossible index and assure the code raises
372        #with self.assertRaises(Exception):
373        #    self.form.cbSelect.setCurrentIndex(6)
374
[481ff26]375    def testFreezeTheory(self):
376        """
377        Assure theory freeze functionality works
378        """
379        # Not yet tested - agree on design first.
380        pass
381
382    def testRecursivelyCloneItem(self):
383        """
384        Test the rescursive QAbstractItem/QStandardItem clone
385        """
386        # Create an item with several branches
387        item1 = QtGui.QStandardItem()
388        item2 = QtGui.QStandardItem()
389        item3 = QtGui.QStandardItem()
390        item4 = QtGui.QStandardItem()
391        item5 = QtGui.QStandardItem()
392        item6 = QtGui.QStandardItem()
393
394        item4.appendRow(item5)
395        item2.appendRow(item4)
396        item2.appendRow(item6)
397        item1.appendRow(item2)
398        item1.appendRow(item3)
399
400        # Clone
401        new_item = self.form.recursivelyCloneItem(item1)
402
403        # assure the trees look identical
404        self.assertEqual(item1.rowCount(), new_item.rowCount())
405        self.assertEqual(item1.child(0).rowCount(), new_item.child(0).rowCount())
406        self.assertEqual(item1.child(1).rowCount(), new_item.child(1).rowCount())
407        self.assertEqual(item1.child(0).child(0).rowCount(), new_item.child(0).child(0).rowCount())
408
[f721030]409    def testReadData(self):
410        """
[5032ea68]411        Test the low level readData() method
[f721030]412        """
413        filename = ["cyl_400_20.txt"]
414        self.form.manager.add_data = MagicMock()
415
416        # Initialize signal spy instances
[f82ab8c]417        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
418        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]419
420        # Read in the file
421        self.form.readData(filename)
422
423        # Expected two status bar updates
[2155824]424        self.assertEqual(spy_status_update.count(), 2)
[f721030]425        self.assertIn(filename[0], str(spy_status_update.called()[0]['args'][0]))
426
427
428        # Check that the model contains the item
429        self.assertEqual(self.form.model.rowCount(), 1)
430        self.assertEqual(self.form.model.columnCount(), 1)
431
432        # The 0th item header should be the name of the file
433        model_item = self.form.model.index(0,0)
434        model_name = str(self.form.model.data(model_item).toString())
435        self.assertEqual(model_name, filename[0])
436
[31c5b58]437    def skip_testDisplayHelp(self): # Skip due to help path change
[481ff26]438        """
439        Test that the Help window gets shown correctly
440        """
441        partial_url = "sasgui/guiframe/data_explorer_help.html"
442        button1 = self.form.cmdHelp
443        button2 = self.form.cmdHelp_2
444
445        # Click on the Help button
446        QTest.mouseClick(button1, Qt.LeftButton)
[464cd07]447        QtGui.qApp.processEvents()
[481ff26]448
449        # Check the browser
450        self.assertIn(partial_url, str(self.form._helpView.url()))
451        # Close the browser
452        self.form._helpView.close()
453
454        # Click on the Help_2 button
455        QTest.mouseClick(button2, Qt.LeftButton)
[464cd07]456        QtGui.qApp.processEvents()
[481ff26]457        # Check the browser
458        self.assertIn(partial_url, str(self.form._helpView.url()))
459
[5032ea68]460    def testLoadFile(self):
461        """
462        Test the threaded call to readData()
463        """
[f82ab8c]464        #self.form.loadFile()
[5032ea68]465        pass
[f721030]466
467    def testGetWList(self):
468        """
[f82ab8c]469        Test the list of known extensions
[f721030]470        """
[481ff26]471        w_list = self.form.getWlist()
472
[f721030]473        defaults = 'All (*.*);;canSAS files (*.xml);;SESANS files' +\
[f4a1433]474            ' (*.ses);;ASCII files (*.txt);;' +\
[f721030]475            'IGOR/DAT 2D Q_map files (*.dat);;IGOR 1D files (*.abs);;'+\
[f4a1433]476            'DANSE files (*.sans)'
[481ff26]477        default_list = defaults.split(';;')
478
[e540cd2]479        for def_format in default_list:
480            self.assertIn(def_format, w_list)
[5032ea68]481       
[f721030]482    def testLoadComplete(self):
483        """
[5032ea68]484        Test the callback method updating the data object
[f721030]485        """
[a281ab8]486        message="Loading Data Complete"
[5032ea68]487        data_dict = {"a1":Data1D()}
[a281ab8]488        output_data = (data_dict, message)
[5032ea68]489
490        self.form.manager.add_data = MagicMock()
491
492        # Initialize signal spy instances
[f82ab8c]493        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
494        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]495
[5032ea68]496        # Read in the file
[a281ab8]497        self.form.loadComplete(output_data)
[f721030]498
[5032ea68]499        # "Loading data complete" no longer sent in LoadFile but in callback
500        self.assertIn("Loading Data Complete", str(spy_status_update.called()[0]['args'][0]))
[f721030]501
[5032ea68]502        # Expect one Data Received signal
[f721030]503        self.assertEqual(spy_data_received.count(), 1)
504
[5032ea68]505        # Assure returned dictionary has correct data
506        # We don't know the data ID, so need to iterate over dict
507        data_dict = spy_data_received.called()[0]['args'][0]
[7fb471d]508        for data_key, data_value in data_dict.items():
[5032ea68]509            self.assertIsInstance(data_value, Data1D)
510
511        # Assure add_data on data_manager was called (last call)
512        self.assertTrue(self.form.manager.add_data.called)
513
[6d05e1d]514    def testNewPlot1D(self):
[1042dba]515        """
516        Creating new plots from Data1D/2D
517        """
518        loader = Loader()
519        manager = DataManager()
[8cb6cd6]520        PlotHelper.clear()
521        self.form.enableGraphCombo(None)
522
523        # Make sure the controls are disabled
524        self.assertFalse(self.form.cbgraph.isEnabled())
525        self.assertFalse(self.form.cmdAppend.isEnabled())
[1042dba]526
527        # get Data1D
528        p_file="cyl_400_20.txt"
529        output_object = loader.load(p_file)
[f4a1433]530        new_data = [manager.create_gui_data(output_object[0], p_file)]
[1042dba]531
532        # Mask retrieval of the data
533        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
534
[8cb6cd6]535        # Mask plotting
536        self.form.parent.workspace = MagicMock()
537
[1042dba]538        # Call the plotting method
539        self.form.newPlot()
540
[8cb6cd6]541        # The plot was registered
542        self.assertEqual(len(PlotHelper.currentPlots()), 1)
543
544        self.assertTrue(self.form.cbgraph.isEnabled())
545        self.assertTrue(self.form.cmdAppend.isEnabled())
546
[6d05e1d]547    def testNewPlot2D(self):
548        """
549        Creating new plots from Data1D/2D
550        """
551        loader = Loader()
552        manager = DataManager()
553        PlotHelper.clear()
554        self.form.enableGraphCombo(None)
555
556        # Make sure the controls are disabled
557        self.assertFalse(self.form.cbgraph.isEnabled())
558        self.assertFalse(self.form.cmdAppend.isEnabled())
559
560        # get Data2D
[f4a1433]561        p_file="P123_D2O_10_percent.dat"
[6d05e1d]562        output_object = loader.load(p_file)
[f4a1433]563        new_data = [manager.create_gui_data(output_object[0], p_file)]
[6d05e1d]564
565        # Mask retrieval of the data
566        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
567
568        # Mask plotting
569        self.form.parent.workspace = MagicMock()
570
571        # Call the plotting method
572        self.form.newPlot()
573
574        # The plot was registered
575        self.assertEqual(len(PlotHelper.currentPlots()), 1)
576
577        self.assertTrue(self.form.cbgraph.isEnabled())
578        self.assertTrue(self.form.cmdAppend.isEnabled())
579
[83eb5208]580    @patch('sas.qtgui.Utilities.GuiUtils.plotsFromCheckedItems')
[31c5b58]581    def testAppendPlot(self, test_patch):
[8cb6cd6]582        """
583        Creating new plots from Data1D/2D
584        """
585        loader = Loader()
586        manager = DataManager()
587
588        PlotHelper.clear()
589        self.form.enableGraphCombo(None)
590
591        # Make sure the controls are disabled
592        self.assertFalse(self.form.cbgraph.isEnabled())
593        self.assertFalse(self.form.cmdAppend.isEnabled())
594
595        # get Data1D
596        p_file="cyl_400_20.txt"
597        output_object = loader.load(p_file)
[965fbd8]598        output_item = QtGui.QStandardItem()
[f4a1433]599        new_data = [(output_item, manager.create_gui_data(output_object[0], p_file))]
[8cb6cd6]600
601        # Mask plotting
602        self.form.parent.workspace = MagicMock()
603
604        # Mask the plot show call
605        Plotter.show = MagicMock()
606
607        # Mask retrieval of the data
[6d05e1d]608        test_patch.return_value = new_data
[8cb6cd6]609
610        # Call the plotting method
611        self.form.newPlot()
612
613        # Call the plotting method again, so we have 2 graphs
614        self.form.newPlot()
615
616        # See that we have two plots
617        self.assertEqual(len(PlotHelper.currentPlots()), 2)
618
619        # Add data to plot #1
620        self.form.cbgraph.setCurrentIndex(1)
621        self.form.appendPlot()
622
623        # See that we still have two plots
624        self.assertEqual(len(PlotHelper.currentPlots()), 2)
625
626    def testUpdateGraphCombo(self):
627        """
628        Test the combo box update
629        """
630        PlotHelper.clear()
631
[0268aed]632        graph_list=["1","2","3"]
[8cb6cd6]633        self.form.updateGraphCombo(graph_list)
634
635        self.assertEqual(self.form.cbgraph.count(), 3)
[0268aed]636        self.assertEqual(self.form.cbgraph.currentText(), '1')
[8cb6cd6]637
638        graph_list=[]
639        self.form.updateGraphCombo(graph_list)
640        self.assertEqual(self.form.cbgraph.count(), 0)
641
[f82ab8c]642    def testUpdateModelFromPerspective(self):
643        """
644        Assure the model update is correct
645        """
646        good_item = QtGui.QStandardItem()
647        bad_item = "I'm so bad"
648
649        self.form.model.reset = MagicMock()
650
651        self.form.updateModelFromPerspective(good_item)
652
653        # See that the model got reset
654        self.form.model.reset.assert_called_once()
655
656        # See that the bad item causes raise
657        with self.assertRaises(Exception):
658            self.form.updateModelFromPerspective(bad_item)
[5032ea68]659
[28a84e9]660    def testContextMenu(self):
661        """
662        See if the context menu is present
663        """
664        # get Data1D
665        p_file=["cyl_400_20.txt"]
666        # Read in the file
667        output, message = self.form.readData(p_file)
668        self.form.loadComplete((output, message))
669
670        # Pick up the treeview index corresponding to that file
671        index = self.form.treeView.indexAt(QtCore.QPoint(5,5))
672        self.form.show()
673
674        # Find out the center pointof the treeView row
675        rect = self.form.treeView.visualRect(index).center()
676
677        self.form.context_menu.exec_ = MagicMock()
678
679        # Move the mouse pointer to the first row
680        QTest.mouseMove(self.form.treeView.viewport(), pos=rect)
681
682        # This doesn't invoke the action/signal. Investigate why?
683        # QTest.mouseClick(self.form.treeView.viewport(), Qt.RightButton, pos=rect)
684
685        # Instead, send the signal directly
686        self.form.treeView.customContextMenuRequested.emit(rect)
687
688        # app.exec_() # debug
689
690        # See that the menu has been shown
691        self.form.context_menu.exec_.assert_called_once()
692
693    def testShowDataInfo(self):
694        """
695        Test of the showDataInfo method
696        """
697        # get Data1D
698        p_file=["cyl_400_20.txt"]
699        # Read in the file
700        output, message = self.form.readData(p_file)
701        self.form.loadComplete((output, message))
702
703        # select the data
704        self.form.treeView.selectAll()
705
706        # Call the tested method
707        self.form.showDataInfo()
708
709        # Test the properties
710        self.assertTrue(self.form.txt_widget.isReadOnly())
711        self.assertEqual(self.form.txt_widget.windowTitle(), "Data Info: cyl_400_20.txt")
712        self.assertIn("Waveln_max", self.form.txt_widget.toPlainText())
713
714        # Slider moved all the way up
715        self.assertEqual(self.form.txt_widget.verticalScrollBar().sliderPosition(), 0)
716
717    def testSaveDataAs(self):
718        """
719        Test the Save As context menu action
720        """
721        # get Data1D
722        p_file=["cyl_400_20.txt"]
723        # Read in the file
724        output, message = self.form.readData(p_file)
725        self.form.loadComplete((output, message))
726
727        # select the data
728        self.form.treeView.selectAll()
729
730        QFileDialog.getSaveFileName = MagicMock()
731
732        # Call the tested method
733        self.form.saveDataAs()
734        QFileDialog.getSaveFileName.assert_called_with(
735                                caption="Save As",
736                                directory='cyl_400_20_out.txt',
737                                filter='Text files (*.txt);;CanSAS 1D files(*.xml)',
738                                parent=None)
739        QFileDialog.getSaveFileName.assert_called_once()
740
741        # get Data2D
[f4a1433]742        p_file=["P123_D2O_10_percent.dat"]
[28a84e9]743        # Read in the file
744        output, message = self.form.readData(p_file)
745        self.form.loadComplete((output, message))
746
747        # select the data
748        index = self.form.model.index(1, 0)
749        selmodel = self.form.treeView.selectionModel()
750        selmodel.setCurrentIndex(index, QItemSelectionModel.NoUpdate)
751        selmodel.select(index, QItemSelectionModel.Select|QItemSelectionModel.Rows)
752
753        QFileDialog.getSaveFileName = MagicMock()
754
755        # Call the tested method
756        self.form.saveDataAs()
757        QFileDialog.getSaveFileName.assert_called_with(
758                                caption="Save As",
[f4a1433]759                                directory='P123_D2O_10_percent_out.dat',
[28a84e9]760                                filter='IGOR/DAT 2D file in Q_map (*.dat)',
761                                parent=None)
762        QFileDialog.getSaveFileName.assert_called_once()
763
[39551a68]764    def testQuickDataPlot(self):
765        """
766        Quick data plot generation.
[cad617b]767        """
768        # get Data1D
769        p_file=["cyl_400_20.txt"]
770        # Read in the file
771        output, message = self.form.readData(p_file)
772        self.form.loadComplete((output, message))
773
774        # select the data
775        self.form.treeView.selectAll()
776
777        Plotter.show = MagicMock() # for masking the display
778
779        self.form.quickDataPlot()
780        self.assertTrue(Plotter.show.called)
781
782    def testQuickData3DPlot(self):
783        """
784        Slow(er) 3D data plot generation.
785        """
786        # get Data1D
[f4a1433]787        p_file=["P123_D2O_10_percent.dat"]
[cad617b]788        # Read in the file
789        output, message = self.form.readData(p_file)
790        self.form.loadComplete((output, message))
791
792        # select the data
793        self.form.treeView.selectAll()
794
795        Plotter2D.show = MagicMock() # for masking the display
796
797        self.form.quickData3DPlot()
798
799        self.assertTrue(Plotter2D.show.called)
800
801    def testShowEditMask(self):
802        """
803        Edit mask on a 2D plot.
[39551a68]804
805        TODO: add content once plotting finalized
806        """
807        pass
[28a84e9]808
[cad617b]809
[f721030]810if __name__ == "__main__":
811    unittest.main()
Note: See TracBrowser for help on using the repository browser.