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

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

Update for unit tests and minor functionality quirks

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