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

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

Add "delete" to the data explorer context menu

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