source: sasview/src/sas/qtgui/Calculators/UnitTesting/DataOperationUtilityTest.py @ d5c5d3d

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 d5c5d3d was d5c5d3d, checked in by celinedurniak <celine.durniak@…>, 7 years ago

Implemented new GUI for data operation panel

  • Property mode set to 100644
File size: 17.2 KB
Line 
1import sys
2import time
3import numpy
4import logging
5import unittest
6from PyQt4 import QtGui
7from PyQt4 import QtCore
8from PyQt4.QtTest import QTest
9from PyQt4.QtCore import Qt
10from mock import MagicMock
11from mock import patch
12
13from twisted.internet import threads
14
15from sas.qtgui.Calculators.DataOperationUtilityPanel import DataOperationUtilityPanel
16from sas.qtgui.Utilities.GuiUtils import *
17from sas.qtgui.Plotting.PlotterData import Data1D
18from sas.qtgui.Plotting.PlotterData import Data2D
19from sas.qtgui.MainWindow.DataState import DataState
20
21if not QtGui.QApplication.instance():
22    app = QtGui.QApplication(sys.argv)
23
24BG_COLOR_ERR = 'background-color: rgb(244, 170, 164);'
25
26class DataOperationUtilityTest(unittest.TestCase):
27    """Test the ResolutionCalculator"""
28    def setUp(self):
29        """Create the ResolutionCalculator"""
30
31        class dummy_manager(object):
32            def communicator(self):
33                return Communicate()
34
35        self.widget = DataOperationUtilityPanel(dummy_manager())
36
37    def tearDown(self):
38        """Destroy the DataOperationUtility"""
39        self.widget.close()
40        self.widget = None
41
42    def testDefaults(self):
43        """Test the GUI in its default state"""
44
45        self.assertIsInstance(self.widget, QtGui.QDialog)
46
47        self.assertEqual(self.widget.windowTitle(), "Data Operation")
48        self.assertEqual(self.widget.groupBox.title(), "Data Operation "
49                                                       "[ + (add); "
50                                                       "- (subtract); "
51                                                       "* (multiply); "
52                                                       "/ (divide); "
53                                                       "| (append)]")
54        # size
55        self.assertEqual(self.widget.size().height(), 425)
56        self.assertEqual(self.widget.size().width(), 951)
57
58        # content of line edits
59        self.assertEqual(self.widget.txtNumber.text(), '1.0')
60        self.assertEqual(self.widget.txtOutputData.text(), 'MyNewDataName')
61
62        # content of comboboxes and default text / index
63        self.assertFalse(self.widget.cbData1.isEditable())
64        self.assertEqual(self.widget.cbData1.count(), 1)
65        self.assertEqual(self.widget.cbData1.currentText(),
66                         'No Data Available')
67
68        self.assertFalse(self.widget.cbData2.isEditable())
69        self.assertEqual(self.widget.cbData2.count(), 1)
70        self.assertEqual(self.widget.cbData2.currentText(),
71                         'No Data Available')
72
73        self.assertFalse(self.widget.cbOperator.isEditable())
74        self.assertEqual(self.widget.cbOperator.count(), 5)
75        self.assertEqual(self.widget.cbOperator.currentText(), '+')
76        self.assertListEqual([self.widget.cbOperator.itemText(i) for i in
77                              range(self.widget.cbOperator.count())],
78                             ['+', '-', '*', '/', '|'])
79
80        # Tooltips
81        self.assertEqual(str(self.widget.cmdCompute.toolTip()), "Generate the Data "
82                                                           "and send to Data "
83                                                           "Explorer.")
84        self.assertEqual(str(self.widget.cmdClose.toolTip()), "Close this panel.")
85        self.assertEqual(str(self.widget.cmdHelp.toolTip()),
86                         "Get help on Data Operations.")
87        self.assertEqual(self.widget.txtNumber.toolTip(), "If no Data2 loaded, "
88                                                "enter a number to be "
89                                                "applied to Data1 using "
90                                                "the operator")
91        self.assertEqual(str(self.widget.cbOperator.toolTip()), "Add: +\n"
92                                                           "Subtract: - \n"
93                                                           "Multiply: *\n"
94                                                           "Divide: /\n"
95                                                           "Append(Combine): |")
96
97        self.assertFalse(self.widget.cmdCompute.isEnabled())
98        self.assertFalse(self.widget.txtNumber.isEnabled())
99
100        self.assertIsInstance(self.widget.layoutOutput,QtGui.QHBoxLayout)
101        self.assertIsInstance(self.widget.layoutData1,QtGui.QHBoxLayout)
102        self.assertIsInstance(self.widget.layoutData2,QtGui.QHBoxLayout)
103
104        # To store input datafiles
105        self.assertIsNone(self.widget.filenames)
106        self.assertEqual(self.widget.list_data_items, [])
107        self.assertIsNone(self.widget.data1)
108        self.assertIsNone(self.widget.data2)
109        # To store the result
110        self.assertIsNone(self.widget.output)
111        self.assertFalse(self.widget.data2OK)
112        self.assertFalse(self.widget.data1OK)
113
114        self.widget.newPlot = MagicMock()
115        self.assertTrue(self.widget.newPlot.called_once())
116        self.assertTrue(self.widget.newPlot.called_once())
117        self.assertTrue(self.widget.newPlot.called_once())
118
119    def testHelp(self):
120        """ Assure help file is shown """
121        # this should not rise
122        self.widget.onHelp()
123
124    def testOnReset(self):
125        """ Test onReset function """
126        # modify gui
127        self.widget.txtNumber.setText('2.3')
128        self.widget.onReset()
129        self.assertEqual(self.widget.txtNumber.text(), '1.0')
130
131    def testOnClose(self):
132        """ test Closing window """
133        closeButton = self.widget.cmdClose
134        QTest.mouseClick(closeButton, Qt.LeftButton)
135
136
137    # @patch('DataOperationUtilityPanel.')
138    def testOnCompute(self):
139        """ Test onCompute function """
140
141        # define the data
142        self.widget.data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
143                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
144        self.widget.data2 = 1
145
146        # mock update of plot
147        self.widget.updatePlot = MagicMock()
148
149        # enable onCompute to run (check on data type)
150        self.widget.onCheckChosenData = MagicMock(return_value=True)
151
152        # run onCompute
153        self.widget.onCompute()
154
155        # check output:
156        # x unchanged, y incremented by 1 (=data2) and updatePlot called
157        self.assertListEqual(self.widget.output.x.tolist(),
158                             self.widget.data1.x.tolist())
159        self.assertListEqual(self.widget.output.y.tolist(), [12.0, 13.0, 14.0])
160        self.assertTrue(self.widget.updatePlot.called_once())
161
162        self.widget.onPrepareOutputData = MagicMock()
163
164        self.assertTrue(self.widget.onPrepareOutputData.called_once())
165
166        # GuiManager.updateModelFromDataOperationPanel
167
168    def testOnSelectData1(self):
169        """ Test ComboBox for Data1 """
170        # Case 1: no data loaded
171        self.widget.onSelectData1()
172        self.assertIsNone(self.widget.data1)
173        self.assertFalse(self.widget.data1OK)
174        self.assertFalse(self.widget.cmdCompute.isEnabled())
175
176        # Case 2: data1 is a datafile
177        self.widget.filenames = MagicMock(
178            return_value={'datafile1': 'details'})
179        self.widget.updatePlot = MagicMock()
180
181        self.widget.cbData1.addItems(['Select Data', 'datafile1'])
182        self.widget.cbData1.setCurrentIndex(self.widget.cbData1.count()-1)
183        self.assertTrue(self.widget.updatePlot.called_once())
184        # Compute button disabled if data2OK == False
185        self.assertEqual(self.widget.cmdCompute.isEnabled(), self.widget.data2OK)
186
187    def testOnSelectData2(self):
188        """ Test ComboBox for Data2 """
189        self.widget.updatePlot = MagicMock()
190        # Case 1: no data loaded
191        self.widget.onSelectData2()
192        self.assertIsNone(self.widget.data2)
193        self.assertFalse(self.widget.data2OK)
194        self.assertFalse(self.widget.cmdCompute.isEnabled())
195
196        # Case 2: when empty combobox
197        self.widget.cbData2.clear()
198        self.widget.onSelectData2()
199        self.assertFalse(self.widget.txtNumber.isEnabled())
200        self.assertFalse(self.widget.cmdCompute.isEnabled())
201
202        # Case 3: when Data2 is Number
203        # add 'Number' to combobox Data2
204        self.widget.cbData2.addItem('Number')
205        # select 'Number' for cbData2
206        self.widget.cbData2.setCurrentIndex(self.widget.cbData2.count()-1)
207        self.widget.onSelectData2()
208        # check that line edit is now enabled
209        self.assertTrue(self.widget.txtNumber.isEnabled())
210        # Compute button enabled only if data1OK True
211        self.assertEqual(self.widget.cmdCompute.isEnabled(), self.widget.data1OK)
212        self.assertIsInstance(self.widget.data2, float)
213        # call updatePlot
214        self.assertTrue(self.widget.updatePlot.called_once())
215
216        # Case 4: when Data2 is a file
217        self.widget.filenames = MagicMock(
218            return_value={'datafile2': 'details'})
219        self.widget.cbData2.addItems(['Select Data', 'Number', 'datafile2'])
220        self.widget.cbData2.setCurrentIndex(self.widget.cbData2.count() - 1)
221        self.assertTrue(self.widget.updatePlot.called_once())
222        # editing of txtNumber is disabled when Data2 is a file
223        self.assertFalse(self.widget.txtNumber.isEnabled())
224        # Compute button enabled only if data1OK True
225        self.assertEqual(self.widget.cmdCompute.isEnabled(),
226                         self.widget.data1OK)
227        # call updatePlot
228        self.assertTrue(self.widget.updatePlot.called_once())
229
230    def testUpdateCombobox(self):
231        """ Test change of contents of comboboxes for Data1 and Data2 """
232        # Create input data
233        data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
234                       dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
235
236        data2 = Data2D(image=[0.1] * 4,
237                       qx_data=[1.0, 2.0, 3.0, 4.0],
238                       qy_data=[10.0, 11.0, 12.0, 13.0],
239                       dqx_data=[0.1, 0.2, 0.3, 0.4],
240                       dqy_data=[0.1, 0.2, 0.3, 0.4],
241                       q_data=[1, 2, 3, 4],
242                       xmin=-1.0, xmax=5.0,
243                       ymin=-1.0, ymax=15.0,
244                       zmin=-1.0, zmax=20.0)
245
246        filenames = {'datafile2': DataState(data2),
247                                 'datafile1': DataState(data1)}
248
249        # call function
250        self.widget.updateCombobox(filenames)
251
252        # check modifications of comboboxes
253        AllItemsData1 = [self.widget.cbData1.itemText(indx)
254                         for indx in range(self.widget.cbData1.count())]
255        self.assertListEqual(AllItemsData1, ['Select Data',
256                                             'datafile2',
257                                             'datafile1'])
258
259        AllItemsData2 = [self.widget.cbData2.itemText(indx)
260                         for indx in range(self.widget.cbData2.count())]
261        self.assertListEqual(AllItemsData2,
262                             ['Select Data', 'Number',
263                              'datafile2', 'datafile1'])
264
265    def testOnSelectOperator(self):
266        """ Change GUI when operator changed """
267        self.assertEqual(self.widget.lblOperatorApplied.text(),self.widget.cbOperator.currentText())
268
269        self.widget.cbOperator.setCurrentIndex(2)
270        self.assertEqual(self.widget.lblOperatorApplied.text(),
271                         self.widget.cbOperator.currentText())
272
273    def testOnInputCoefficient(self):
274        """
275        Check input of number when a coefficient is required for operation
276        """
277        # clear input for coefficient -> error
278        self.widget.txtNumber.clear()
279        # check that color of background changed to notify error
280        self.assertIn(BG_COLOR_ERR, self.widget.txtNumber.styleSheet())
281
282
283    def testCheckChosenData(self):
284        """ Test check of data compatibility """
285        # Case 1: incompatible dimensions
286        self.widget.data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
287                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
288
289        self.widget.data2 = Data2D(image=[0.1] * 4,
290                           qx_data=[1.0, 2.0, 3.0, 4.0],
291                           qy_data=[10.0, 11.0, 12.0, 13.0],
292                           dqx_data=[0.1, 0.2, 0.3, 0.4],
293                           dqy_data=[0.1, 0.2, 0.3, 0.4],
294                           q_data=[1, 2, 3, 4],
295                           xmin=-1.0, xmax=5.0,
296                           ymin=-1.0, ymax=15.0,
297                           zmin=-1.0, zmax=20.0)
298
299        self.assertFalse(self.widget.onCheckChosenData())
300
301        # Case 2 : compatible 1 dimension
302        self.widget.data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
303                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
304
305        self.widget.data2 = Data1D(x=[1.0, 2.0, 3.0], y=[1.0, 2.0, 3.0],
306                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
307
308        self.assertTrue(self.widget.onCheckChosenData())
309
310        # Case 3: compatible 2 dimension
311        self.widget.data1 = Data2D(image=[0.1] * 4,
312                                   qx_data=[1.0, 2.0, 3.0, 4.0],
313                                   qy_data=[10.0, 11.0, 12.0, 13.0],
314                                   dqx_data=[0.1, 0.2, 0.3, 0.4],
315                                   dqy_data=[0.1, 0.2, 0.3, 0.4],
316                                   q_data=[1, 2, 3, 4],
317                                   xmin=-1.0, xmax=5.0,
318                                   ymin=-1.0, ymax=15.0,
319                                   zmin=-1.0, zmax=20.0)
320
321        self.widget.data2 = Data2D(image=[0.1] * 4,
322                                   qx_data=[1.0, 2.0, 3.0, 4.0],
323                                   qy_data=[10.0, 11.0, 12.0, 13.0],
324                                   dqx_data=[0.1, 0.2, 0.3, 0.4],
325                                   dqy_data=[0.1, 0.2, 0.3, 0.4],
326                                   q_data=[1, 2, 3, 4],
327                                   xmin=-1.0, xmax=5.0,
328                                   ymin=-1.0, ymax=15.0,
329                                   zmin=-1.0, zmax=20.0)
330
331        self.assertTrue(self.widget.onCheckChosenData())
332
333        # Case 4: Different 1D
334        self.widget.data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
335                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
336
337        self.widget.data2 = Data1D(x=[0.0, 1.0, 2.0], y=[1.0, 2.0, 3.0],
338                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
339
340        self.assertFalse(self.widget.onCheckChosenData())
341
342        # Case 5: Data2 is a Number
343        self.widget.cbData2.clear()
344        self.widget.cbData2.addItem('Number')
345        self.widget.cbData2.setCurrentIndex(0)
346        self.assertEqual(self.widget.cbData2.currentText(), 'Number')
347        self.assertTrue(self.widget.onCheckChosenData())
348
349    def testOnCheckOutputName(self):
350        """ Test OutputName for result of operation """
351        self.widget.txtOutputData.clear()
352        self.assertFalse(self.widget.onCheckOutputName())
353
354        self.widget.list_data_items = ['datafile1', 'datafile2']
355        self.widget.txtOutputData.setText('datafile0')
356        self.assertTrue(self.widget.onCheckOutputName())
357        self.assertIn('', self.widget.txtOutputData.styleSheet())
358
359        self.widget.txtOutputData.clear()
360        self.widget.txtOutputData.setText('datafile1')
361        self.assertFalse(self.widget.onCheckOutputName())
362        self.assertIn(BG_COLOR_ERR, self.widget.txtOutputData.styleSheet())
363
364    def testFindId(self):
365        """ Test function to find id of file in list of filenames"""
366        data_for_id = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
367                                   dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
368
369        self.widget.filenames = {'datafile2': DataState(data_for_id),
370                                 'datafile1': DataState(data_for_id)}
371
372        id_out = self.widget._findId('datafile2')
373        self.assertEqual(id_out, 'datafile2')
374
375    def testExtractData(self):
376        """
377        Test function to extract data to be computed from input filenames
378        """
379        data1 = Data1D(x=[1.0, 2.0, 3.0], y=[11.0, 12.0, 13.0],
380                       dx=[0.1, 0.2, 0.3], dy=[0.1, 0.2, 0.3])
381
382        data2 = Data2D(image=[0.1] * 4,
383                                   qx_data=[1.0, 2.0, 3.0, 4.0],
384                                   qy_data=[10.0, 11.0, 12.0, 13.0],
385                                   dqx_data=[0.1, 0.2, 0.3, 0.4],
386                                   dqy_data=[0.1, 0.2, 0.3, 0.4],
387                                   q_data=[1, 2, 3, 4],
388                                   xmin=-1.0, xmax=5.0,
389                                   ymin=-1.0, ymax=15.0,
390                                   zmin=-1.0, zmax=20.0)
391
392        self.widget.filenames = {'datafile2': DataState(data2),
393                                 'datafile1': DataState(data1)}
394
395        output1D = self.widget._extractData('datafile1')
396        self.assertTrue(isinstance(output1D, Data1D))
397
398        output2D = self.widget._extractData('datafile2')
399        self.assertIsInstance(output2D, Data2D)
400
401    # TODO
402    def testOnPrepareOutputData(self):
403        """ """
404        pass
405
406    # new_item = GuiUtils.createModelItemWithPlot(
407    #     QtCore.QVariant(self.output), name=self.txtOutputData.text())
408    # new_datalist_item = {str(self.txtOutputData.text()) + str(time.time()):
409    #                          self.output}
410    # self.communicator. \
411    #     updateModelFromDataOperationPanelSignal.emit(new_item,
412    #                                                  new_datalist_item)
413
414
415if __name__ == "__main__":
416    unittest.main()
Note: See TracBrowser for help on using the repository browser.