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

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

Additional guard against unwanted GUI options on data load.

  • Property mode set to 100644
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 *
7from mock import MagicMock
[31c5b58]8from 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
[a281ab8]39            def setData(self, data_item=None):
[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]
159        spied_list = [spy_progress_bar_update.called()[i]['args'][0] for i in xrange(5)]
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
[d3475fe]172        filename = ["cyl_400_20.txt", "P123_D2O_10_percent.dat", "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
327        # Test the current selection
[5032ea68]328        item1D = self.form.model.item(0)
329        item2D = self.form.model.item(1)
330        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]331        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
332
333        # Select all data
334        self.form.cbSelect.setCurrentIndex(0)
335
336        # Test the current selection
[5032ea68]337        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]338        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
339
340        # select 1d data
341        self.form.cbSelect.setCurrentIndex(2)
342
343        # Test the current selection
[5032ea68]344        self.assertTrue(item1D.checkState() == QtCore.Qt.Checked)
[488c49d]345        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
346
347        # unselect 1d data
348        self.form.cbSelect.setCurrentIndex(3)
349
350        # Test the current selection
[5032ea68]351        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]352        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
353
354        # select 2d data
355        self.form.cbSelect.setCurrentIndex(4)
356
357        # Test the current selection
[5032ea68]358        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]359        self.assertTrue(item2D.checkState() == QtCore.Qt.Checked)       
360
361        # unselect 2d data
362        self.form.cbSelect.setCurrentIndex(5)
363
364        # Test the current selection
[5032ea68]365        self.assertTrue(item1D.checkState() == QtCore.Qt.Unchecked)
[488c49d]366        self.assertTrue(item2D.checkState() == QtCore.Qt.Unchecked)       
367
368        # choose impossible index and assure the code raises
369        #with self.assertRaises(Exception):
370        #    self.form.cbSelect.setCurrentIndex(6)
371
[481ff26]372    def testFreezeTheory(self):
373        """
374        Assure theory freeze functionality works
375        """
376        # Not yet tested - agree on design first.
377        pass
378
379    def testRecursivelyCloneItem(self):
380        """
381        Test the rescursive QAbstractItem/QStandardItem clone
382        """
383        # Create an item with several branches
384        item1 = QtGui.QStandardItem()
385        item2 = QtGui.QStandardItem()
386        item3 = QtGui.QStandardItem()
387        item4 = QtGui.QStandardItem()
388        item5 = QtGui.QStandardItem()
389        item6 = QtGui.QStandardItem()
390
391        item4.appendRow(item5)
392        item2.appendRow(item4)
393        item2.appendRow(item6)
394        item1.appendRow(item2)
395        item1.appendRow(item3)
396
397        # Clone
398        new_item = self.form.recursivelyCloneItem(item1)
399
400        # assure the trees look identical
401        self.assertEqual(item1.rowCount(), new_item.rowCount())
402        self.assertEqual(item1.child(0).rowCount(), new_item.child(0).rowCount())
403        self.assertEqual(item1.child(1).rowCount(), new_item.child(1).rowCount())
404        self.assertEqual(item1.child(0).child(0).rowCount(), new_item.child(0).child(0).rowCount())
405
[f721030]406    def testReadData(self):
407        """
[5032ea68]408        Test the low level readData() method
[f721030]409        """
410        filename = ["cyl_400_20.txt"]
411        self.form.manager.add_data = MagicMock()
412
413        # Initialize signal spy instances
[f82ab8c]414        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
415        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]416
417        # Read in the file
418        self.form.readData(filename)
419
420        # Expected two status bar updates
[2155824]421        self.assertEqual(spy_status_update.count(), 2)
[f721030]422        self.assertIn(filename[0], str(spy_status_update.called()[0]['args'][0]))
423
424
425        # Check that the model contains the item
426        self.assertEqual(self.form.model.rowCount(), 1)
427        self.assertEqual(self.form.model.columnCount(), 1)
428
429        # The 0th item header should be the name of the file
430        model_item = self.form.model.index(0,0)
431        model_name = str(self.form.model.data(model_item).toString())
432        self.assertEqual(model_name, filename[0])
433
[31c5b58]434    def skip_testDisplayHelp(self): # Skip due to help path change
[481ff26]435        """
436        Test that the Help window gets shown correctly
437        """
438        partial_url = "sasgui/guiframe/data_explorer_help.html"
439        button1 = self.form.cmdHelp
440        button2 = self.form.cmdHelp_2
441
442        # Click on the Help button
443        QTest.mouseClick(button1, Qt.LeftButton)
[464cd07]444        QtGui.qApp.processEvents()
[481ff26]445
446        # Check the browser
447        self.assertIn(partial_url, str(self.form._helpView.url()))
448        # Close the browser
449        self.form._helpView.close()
450
451        # Click on the Help_2 button
452        QTest.mouseClick(button2, Qt.LeftButton)
[464cd07]453        QtGui.qApp.processEvents()
[481ff26]454        # Check the browser
455        self.assertIn(partial_url, str(self.form._helpView.url()))
456
[5032ea68]457    def testLoadFile(self):
458        """
459        Test the threaded call to readData()
460        """
[f82ab8c]461        #self.form.loadFile()
[5032ea68]462        pass
[f721030]463
464    def testGetWList(self):
465        """
[f82ab8c]466        Test the list of known extensions
[f721030]467        """
[481ff26]468        w_list = self.form.getWlist()
469
[f721030]470        defaults = 'All (*.*);;canSAS files (*.xml);;SESANS files' +\
[f4a1433]471            ' (*.ses);;ASCII files (*.txt);;' +\
[f721030]472            'IGOR/DAT 2D Q_map files (*.dat);;IGOR 1D files (*.abs);;'+\
[f4a1433]473            'DANSE files (*.sans)'
[481ff26]474        default_list = defaults.split(';;')
475
[e540cd2]476        for def_format in default_list:
477            self.assertIn(def_format, w_list)
[5032ea68]478       
[f721030]479    def testLoadComplete(self):
480        """
[5032ea68]481        Test the callback method updating the data object
[f721030]482        """
[a281ab8]483        message="Loading Data Complete"
[5032ea68]484        data_dict = {"a1":Data1D()}
[a281ab8]485        output_data = (data_dict, message)
[5032ea68]486
487        self.form.manager.add_data = MagicMock()
488
489        # Initialize signal spy instances
[f82ab8c]490        spy_status_update = QtSignalSpy(self.form, self.form.communicator.statusBarUpdateSignal)
491        spy_data_received = QtSignalSpy(self.form, self.form.communicator.fileDataReceivedSignal)
[f721030]492
[5032ea68]493        # Read in the file
[a281ab8]494        self.form.loadComplete(output_data)
[f721030]495
[5032ea68]496        # "Loading data complete" no longer sent in LoadFile but in callback
497        self.assertIn("Loading Data Complete", str(spy_status_update.called()[0]['args'][0]))
[f721030]498
[5032ea68]499        # Expect one Data Received signal
[f721030]500        self.assertEqual(spy_data_received.count(), 1)
501
[5032ea68]502        # Assure returned dictionary has correct data
503        # We don't know the data ID, so need to iterate over dict
504        data_dict = spy_data_received.called()[0]['args'][0]
505        for data_key, data_value in data_dict.iteritems():
506            self.assertIsInstance(data_value, Data1D)
507
508        # Assure add_data on data_manager was called (last call)
509        self.assertTrue(self.form.manager.add_data.called)
510
[6d05e1d]511    def testNewPlot1D(self):
[1042dba]512        """
513        Creating new plots from Data1D/2D
514        """
515        loader = Loader()
516        manager = DataManager()
[8cb6cd6]517        PlotHelper.clear()
518        self.form.enableGraphCombo(None)
519
520        # Make sure the controls are disabled
521        self.assertFalse(self.form.cbgraph.isEnabled())
522        self.assertFalse(self.form.cmdAppend.isEnabled())
[1042dba]523
524        # get Data1D
525        p_file="cyl_400_20.txt"
526        output_object = loader.load(p_file)
[f4a1433]527        new_data = [manager.create_gui_data(output_object[0], p_file)]
[1042dba]528
529        # Mask retrieval of the data
530        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
531
[8cb6cd6]532        # Mask plotting
533        self.form.parent.workspace = MagicMock()
534
[1042dba]535        # Call the plotting method
536        self.form.newPlot()
537
[8cb6cd6]538        # The plot was registered
539        self.assertEqual(len(PlotHelper.currentPlots()), 1)
540
541        self.assertTrue(self.form.cbgraph.isEnabled())
542        self.assertTrue(self.form.cmdAppend.isEnabled())
543
[6d05e1d]544    def testNewPlot2D(self):
545        """
546        Creating new plots from Data1D/2D
547        """
548        loader = Loader()
549        manager = DataManager()
550        PlotHelper.clear()
551        self.form.enableGraphCombo(None)
552
553        # Make sure the controls are disabled
554        self.assertFalse(self.form.cbgraph.isEnabled())
555        self.assertFalse(self.form.cmdAppend.isEnabled())
556
557        # get Data2D
[f4a1433]558        p_file="P123_D2O_10_percent.dat"
[6d05e1d]559        output_object = loader.load(p_file)
[f4a1433]560        new_data = [manager.create_gui_data(output_object[0], p_file)]
[6d05e1d]561
562        # Mask retrieval of the data
563        self.form.plotsFromCheckedItems = MagicMock(return_value=new_data)
564
565        # Mask plotting
566        self.form.parent.workspace = MagicMock()
567
568        # Call the plotting method
569        self.form.newPlot()
570
571        # The plot was registered
572        self.assertEqual(len(PlotHelper.currentPlots()), 1)
573
574        self.assertTrue(self.form.cbgraph.isEnabled())
575        self.assertTrue(self.form.cmdAppend.isEnabled())
576
[83eb5208]577    @patch('sas.qtgui.Utilities.GuiUtils.plotsFromCheckedItems')
[31c5b58]578    def testAppendPlot(self, test_patch):
[8cb6cd6]579        """
580        Creating new plots from Data1D/2D
581        """
582        loader = Loader()
583        manager = DataManager()
584
585        PlotHelper.clear()
586        self.form.enableGraphCombo(None)
587
588        # Make sure the controls are disabled
589        self.assertFalse(self.form.cbgraph.isEnabled())
590        self.assertFalse(self.form.cmdAppend.isEnabled())
591
592        # get Data1D
593        p_file="cyl_400_20.txt"
594        output_object = loader.load(p_file)
[965fbd8]595        output_item = QtGui.QStandardItem()
[f4a1433]596        new_data = [(output_item, manager.create_gui_data(output_object[0], p_file))]
[8cb6cd6]597
598        # Mask plotting
599        self.form.parent.workspace = MagicMock()
600
601        # Mask the plot show call
602        Plotter.show = MagicMock()
603
604        # Mask retrieval of the data
[6d05e1d]605        test_patch.return_value = new_data
[8cb6cd6]606
607        # Call the plotting method
608        self.form.newPlot()
609
610        # Call the plotting method again, so we have 2 graphs
611        self.form.newPlot()
612
613        # See that we have two plots
614        self.assertEqual(len(PlotHelper.currentPlots()), 2)
615
616        # Add data to plot #1
617        self.form.cbgraph.setCurrentIndex(1)
618        self.form.appendPlot()
619
620        # See that we still have two plots
621        self.assertEqual(len(PlotHelper.currentPlots()), 2)
622
623    def testUpdateGraphCombo(self):
624        """
625        Test the combo box update
626        """
627        PlotHelper.clear()
628
[0268aed]629        graph_list=["1","2","3"]
[8cb6cd6]630        self.form.updateGraphCombo(graph_list)
631
632        self.assertEqual(self.form.cbgraph.count(), 3)
[0268aed]633        self.assertEqual(self.form.cbgraph.currentText(), '1')
[8cb6cd6]634
635        graph_list=[]
636        self.form.updateGraphCombo(graph_list)
637        self.assertEqual(self.form.cbgraph.count(), 0)
638
[f82ab8c]639    def testUpdateModelFromPerspective(self):
640        """
641        Assure the model update is correct
642        """
643        good_item = QtGui.QStandardItem()
644        bad_item = "I'm so bad"
645
646        self.form.model.reset = MagicMock()
647
648        self.form.updateModelFromPerspective(good_item)
649
650        # See that the model got reset
651        self.form.model.reset.assert_called_once()
652
653        # See that the bad item causes raise
654        with self.assertRaises(Exception):
655            self.form.updateModelFromPerspective(bad_item)
[5032ea68]656
[28a84e9]657    def testContextMenu(self):
658        """
659        See if the context menu is present
660        """
661        # get Data1D
662        p_file=["cyl_400_20.txt"]
663        # Read in the file
664        output, message = self.form.readData(p_file)
665        self.form.loadComplete((output, message))
666
667        # Pick up the treeview index corresponding to that file
668        index = self.form.treeView.indexAt(QtCore.QPoint(5,5))
669        self.form.show()
670
671        # Find out the center pointof the treeView row
672        rect = self.form.treeView.visualRect(index).center()
673
674        self.form.context_menu.exec_ = MagicMock()
675
676        # Move the mouse pointer to the first row
677        QTest.mouseMove(self.form.treeView.viewport(), pos=rect)
678
679        # This doesn't invoke the action/signal. Investigate why?
680        # QTest.mouseClick(self.form.treeView.viewport(), Qt.RightButton, pos=rect)
681
682        # Instead, send the signal directly
683        self.form.treeView.customContextMenuRequested.emit(rect)
684
685        # app.exec_() # debug
686
687        # See that the menu has been shown
688        self.form.context_menu.exec_.assert_called_once()
689
690    def testShowDataInfo(self):
691        """
692        Test of the showDataInfo method
693        """
694        # get Data1D
695        p_file=["cyl_400_20.txt"]
696        # Read in the file
697        output, message = self.form.readData(p_file)
698        self.form.loadComplete((output, message))
699
700        # select the data
701        self.form.treeView.selectAll()
702
703        # Call the tested method
704        self.form.showDataInfo()
705
706        # Test the properties
707        self.assertTrue(self.form.txt_widget.isReadOnly())
708        self.assertEqual(self.form.txt_widget.windowTitle(), "Data Info: cyl_400_20.txt")
709        self.assertIn("Waveln_max", self.form.txt_widget.toPlainText())
710
711        # Slider moved all the way up
712        self.assertEqual(self.form.txt_widget.verticalScrollBar().sliderPosition(), 0)
713
714    def testSaveDataAs(self):
715        """
716        Test the Save As context menu action
717        """
718        # get Data1D
719        p_file=["cyl_400_20.txt"]
720        # Read in the file
721        output, message = self.form.readData(p_file)
722        self.form.loadComplete((output, message))
723
724        # select the data
725        self.form.treeView.selectAll()
726
727        QFileDialog.getSaveFileName = MagicMock()
728
729        # Call the tested method
730        self.form.saveDataAs()
731        QFileDialog.getSaveFileName.assert_called_with(
732                                caption="Save As",
733                                directory='cyl_400_20_out.txt',
734                                filter='Text files (*.txt);;CanSAS 1D files(*.xml)',
735                                parent=None)
736        QFileDialog.getSaveFileName.assert_called_once()
737
738        # get Data2D
[f4a1433]739        p_file=["P123_D2O_10_percent.dat"]
[28a84e9]740        # Read in the file
741        output, message = self.form.readData(p_file)
742        self.form.loadComplete((output, message))
743
744        # select the data
745        index = self.form.model.index(1, 0)
746        selmodel = self.form.treeView.selectionModel()
747        selmodel.setCurrentIndex(index, QItemSelectionModel.NoUpdate)
748        selmodel.select(index, QItemSelectionModel.Select|QItemSelectionModel.Rows)
749
750        QFileDialog.getSaveFileName = MagicMock()
751
752        # Call the tested method
753        self.form.saveDataAs()
754        QFileDialog.getSaveFileName.assert_called_with(
755                                caption="Save As",
[f4a1433]756                                directory='P123_D2O_10_percent_out.dat',
[28a84e9]757                                filter='IGOR/DAT 2D file in Q_map (*.dat)',
758                                parent=None)
759        QFileDialog.getSaveFileName.assert_called_once()
760
[39551a68]761    def testQuickDataPlot(self):
762        """
763        Quick data plot generation.
[cad617b]764        """
765        # get Data1D
766        p_file=["cyl_400_20.txt"]
767        # Read in the file
768        output, message = self.form.readData(p_file)
769        self.form.loadComplete((output, message))
770
771        # select the data
772        self.form.treeView.selectAll()
773
774        Plotter.show = MagicMock() # for masking the display
775
776        self.form.quickDataPlot()
777        self.assertTrue(Plotter.show.called)
778
779    def testQuickData3DPlot(self):
780        """
781        Slow(er) 3D data plot generation.
782        """
783        # get Data1D
[f4a1433]784        p_file=["P123_D2O_10_percent.dat"]
[cad617b]785        # Read in the file
786        output, message = self.form.readData(p_file)
787        self.form.loadComplete((output, message))
788
789        # select the data
790        self.form.treeView.selectAll()
791
792        Plotter2D.show = MagicMock() # for masking the display
793
794        self.form.quickData3DPlot()
795
796        self.assertTrue(Plotter2D.show.called)
797
798    def testShowEditMask(self):
799        """
800        Edit mask on a 2D plot.
[39551a68]801
802        TODO: add content once plotting finalized
803        """
804        pass
[28a84e9]805
[cad617b]806
[f721030]807if __name__ == "__main__":
808    unittest.main()
Note: See TracBrowser for help on using the repository browser.