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

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

More functionality for quick plots + unit tests

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