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

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

Code review issues, fixing matplotlib behaviour in unit testing, minor fixes.

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