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

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 9f25bce was 0268aed, checked in by Piotr Rozyczko <rozyczko@…>, 8 years ago

Plotting residuals in fitting.
PlotHelper? updates.
Minor refactoring.

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