summaryrefslogtreecommitdiff
path: root/silx/app/view/test/test_view.py
diff options
context:
space:
mode:
Diffstat (limited to 'silx/app/view/test/test_view.py')
-rw-r--r--silx/app/view/test/test_view.py402
1 files changed, 402 insertions, 0 deletions
diff --git a/silx/app/view/test/test_view.py b/silx/app/view/test/test_view.py
new file mode 100644
index 0000000..010cda5
--- /dev/null
+++ b/silx/app/view/test/test_view.py
@@ -0,0 +1,402 @@
+# coding: utf-8
+# /*##########################################################################
+#
+# Copyright (c) 2016-2017 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+"""Module testing silx.app.view"""
+
+__authors__ = ["V. Valls"]
+__license__ = "MIT"
+__date__ = "07/06/2018"
+
+
+import unittest
+import weakref
+import numpy
+import tempfile
+import shutil
+import os.path
+try:
+ import h5py
+except ImportError:
+ h5py = None
+
+from silx.gui import qt
+from silx.app.view.Viewer import Viewer
+from silx.app.view.About import About
+from silx.app.view.DataPanel import DataPanel
+from silx.app.view.CustomNxdataWidget import CustomNxdataWidget
+from silx.gui.hdf5._utils import Hdf5DatasetMimeData
+from silx.gui.test.utils import TestCaseQt
+from silx.io import commonh5
+
+_tmpDirectory = None
+
+
+def setUpModule():
+ global _tmpDirectory
+ _tmpDirectory = tempfile.mkdtemp(prefix=__name__)
+
+ if h5py is not None:
+ # create h5 data
+ filename = _tmpDirectory + "/data.h5"
+ f = h5py.File(filename, "w")
+ g = f.create_group("arrays")
+ g.create_dataset("scalar", data=10)
+ g.create_dataset("integers", data=numpy.array([10, 20, 30]))
+ f.close()
+
+ # create h5 data
+ filename = _tmpDirectory + "/data2.h5"
+ f = h5py.File(filename, "w")
+ g = f.create_group("arrays")
+ g.create_dataset("scalar", data=20)
+ g.create_dataset("integers", data=numpy.array([10, 20, 30]))
+ f.close()
+
+
+def tearDownModule():
+ global _tmpDirectory
+ shutil.rmtree(_tmpDirectory)
+ _tmpDirectory = None
+
+
+class TestViewer(TestCaseQt):
+ """Test for Viewer class"""
+
+ def testConstruct(self):
+ widget = Viewer()
+ self.qWaitForWindowExposed(widget)
+
+ def testDestroy(self):
+ widget = Viewer()
+ ref = weakref.ref(widget)
+ widget = None
+ self.qWaitForDestroy(ref)
+
+
+class TestAbout(TestCaseQt):
+ """Test for About box class"""
+
+ def testConstruct(self):
+ widget = About()
+ self.qWaitForWindowExposed(widget)
+
+ def testLicense(self):
+ widget = About()
+ widget.getHtmlLicense()
+ self.qWaitForWindowExposed(widget)
+
+ def testDestroy(self):
+ widget = About()
+ ref = weakref.ref(widget)
+ widget = None
+ self.qWaitForDestroy(ref)
+
+
+class TestDataPanel(TestCaseQt):
+
+ def testConstruct(self):
+ widget = DataPanel()
+ self.qWaitForWindowExposed(widget)
+
+ def testDestroy(self):
+ widget = DataPanel()
+ ref = weakref.ref(widget)
+ widget = None
+ self.qWaitForDestroy(ref)
+
+ def testHeaderLabelPaintEvent(self):
+ widget = DataPanel()
+ data = numpy.array([1, 2, 3, 4, 5])
+ widget.setData(data)
+ # Expected to execute HeaderLabel.paintEvent
+ widget.setVisible(True)
+ self.qWaitForWindowExposed(widget)
+
+ def testData(self):
+ widget = DataPanel()
+ data = numpy.array([1, 2, 3, 4, 5])
+ widget.setData(data)
+ self.assertIs(widget.getData(), data)
+ self.assertIs(widget.getCustomNxdataItem(), None)
+
+ def testDataNone(self):
+ widget = DataPanel()
+ widget.setData(None)
+ self.assertIs(widget.getData(), None)
+ self.assertIs(widget.getCustomNxdataItem(), None)
+
+ def testCustomDataItem(self):
+ class CustomDataItemMock(object):
+ def getVirtualGroup(self):
+ return None
+
+ def text(self):
+ return ""
+
+ data = CustomDataItemMock()
+ widget = DataPanel()
+ widget.setCustomDataItem(data)
+ self.assertIs(widget.getData(), None)
+ self.assertIs(widget.getCustomNxdataItem(), data)
+
+ def testCustomDataItemNone(self):
+ data = None
+ widget = DataPanel()
+ widget.setCustomDataItem(data)
+ self.assertIs(widget.getData(), None)
+ self.assertIs(widget.getCustomNxdataItem(), data)
+
+ @unittest.skipIf(h5py is None, "Could not import h5py")
+ def testRemoveDatasetsFrom(self):
+ f = h5py.File(os.path.join(_tmpDirectory, "data.h5"))
+ try:
+ widget = DataPanel()
+ widget.setData(f["arrays/scalar"])
+ widget.removeDatasetsFrom(f)
+ self.assertIs(widget.getData(), None)
+ finally:
+ widget.setData(None)
+ f.close()
+
+ @unittest.skipIf(h5py is None, "Could not import h5py")
+ def testReplaceDatasetsFrom(self):
+ f = h5py.File(os.path.join(_tmpDirectory, "data.h5"))
+ f2 = h5py.File(os.path.join(_tmpDirectory, "data2.h5"))
+ try:
+ widget = DataPanel()
+ widget.setData(f["arrays/scalar"])
+ self.assertEqual(widget.getData()[()], 10)
+ widget.replaceDatasetsFrom(f, f2)
+ self.assertEqual(widget.getData()[()], 20)
+ finally:
+ widget.setData(None)
+ f.close()
+ f2.close()
+
+
+class TestCustomNxdataWidget(TestCaseQt):
+
+ def testConstruct(self):
+ widget = CustomNxdataWidget()
+ self.qWaitForWindowExposed(widget)
+
+ def testDestroy(self):
+ widget = CustomNxdataWidget()
+ ref = weakref.ref(widget)
+ widget = None
+ self.qWaitForDestroy(ref)
+
+ def testCreateNxdata(self):
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ model.createNewNxdata()
+ model.createNewNxdata("Foo")
+ widget.setVisible(True)
+ self.qWaitForWindowExposed(widget)
+
+ def testCreateNxdataFromDataset(self):
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ signal = commonh5.Dataset("foo", data=numpy.array([[[5]]]))
+ model.createFromSignal(signal)
+ widget.setVisible(True)
+ self.qWaitForWindowExposed(widget)
+
+ def testCreateNxdataFromNxdata(self):
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ data = numpy.array([[[5]]])
+ nxdata = commonh5.Group("foo")
+ nxdata.attrs["NX_class"] = "NXdata"
+ nxdata.attrs["signal"] = "signal"
+ nxdata.create_dataset("signal", data=data)
+ model.createFromNxdata(nxdata)
+ widget.setVisible(True)
+ self.qWaitForWindowExposed(widget)
+
+ def testCreateBadNxdata(self):
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ signal = commonh5.Dataset("foo", data=numpy.array([[[5]]]))
+ model.createFromSignal(signal)
+ axis = commonh5.Dataset("foo", data=numpy.array([[[5]]]))
+ nxdataIndex = model.index(0, 0)
+ item = model.itemFromIndex(nxdataIndex)
+ item.setAxesDatasets([axis])
+ nxdata = item.getVirtualGroup()
+ self.assertIsNotNone(nxdata)
+ self.assertFalse(item.isValid())
+
+ @unittest.skipIf(h5py is None, "Could not import h5py")
+ def testRemoveDatasetsFrom(self):
+ f = h5py.File(os.path.join(_tmpDirectory, "data.h5"))
+ try:
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ dataset = f["arrays/integers"]
+ model.createFromSignal(dataset)
+ widget.removeDatasetsFrom(f)
+ finally:
+ model.clear()
+ f.close()
+
+ @unittest.skipIf(h5py is None, "Could not import h5py")
+ def testReplaceDatasetsFrom(self):
+ f = h5py.File(os.path.join(_tmpDirectory, "data.h5"))
+ f2 = h5py.File(os.path.join(_tmpDirectory, "data2.h5"))
+ try:
+ widget = CustomNxdataWidget()
+ model = widget.model()
+ dataset = f["arrays/integers"]
+ model.createFromSignal(dataset)
+ widget.replaceDatasetsFrom(f, f2)
+ finally:
+ model.clear()
+ f.close()
+ f2.close()
+
+
+class TestCustomNxdataWidgetInteraction(TestCaseQt):
+ """Test CustomNxdataWidget with user interaction"""
+
+ def setUp(self):
+ TestCaseQt.setUp(self)
+
+ self.widget = CustomNxdataWidget()
+ self.model = self.widget.model()
+ data = numpy.array([[[5]]])
+ dataset = commonh5.Dataset("foo", data=data)
+ self.model.createFromSignal(dataset)
+ self.selectionModel = self.widget.selectionModel()
+
+ def tearDown(self):
+ self.selectionModel = None
+ self.model.clear()
+ self.model = None
+ self.widget = None
+ TestCaseQt.tearDown(self)
+
+ def testSelectedNxdata(self):
+ index = self.model.index(0, 0)
+ self.selectionModel.setCurrentIndex(index, qt.QItemSelectionModel.ClearAndSelect)
+ nxdata = self.widget.selectedNxdata()
+ self.assertEqual(len(nxdata), 1)
+ self.assertIsNot(nxdata[0], None)
+
+ def testSelectedItems(self):
+ index = self.model.index(0, 0)
+ self.selectionModel.setCurrentIndex(index, qt.QItemSelectionModel.ClearAndSelect)
+ items = self.widget.selectedItems()
+ self.assertEqual(len(items), 1)
+ self.assertIsNot(items[0], None)
+ self.assertIsInstance(items[0], qt.QStandardItem)
+
+ def testRowsAboutToBeRemoved(self):
+ self.model.removeRow(0)
+ self.qWaitForWindowExposed(self.widget)
+
+ def testPaintItems(self):
+ self.widget.expandAll()
+ self.widget.setVisible(True)
+ self.qWaitForWindowExposed(self.widget)
+
+ def testCreateDefaultContextMenu(self):
+ nxDataIndex = self.model.index(0, 0)
+ menu = self.widget.createDefaultContextMenu(nxDataIndex)
+ self.assertIsNot(menu, None)
+ self.assertIsInstance(menu, qt.QMenu)
+
+ signalIndex = self.model.index(0, 0, nxDataIndex)
+ menu = self.widget.createDefaultContextMenu(signalIndex)
+ self.assertIsNot(menu, None)
+ self.assertIsInstance(menu, qt.QMenu)
+
+ axesIndex = self.model.index(1, 0, nxDataIndex)
+ menu = self.widget.createDefaultContextMenu(axesIndex)
+ self.assertIsNot(menu, None)
+ self.assertIsInstance(menu, qt.QMenu)
+
+ def testDropNewDataset(self):
+ dataset = commonh5.Dataset("foo", numpy.array([1, 2, 3, 4]))
+ mimedata = Hdf5DatasetMimeData(dataset=dataset)
+ self.model.dropMimeData(mimedata, qt.Qt.CopyAction, -1, -1, qt.QModelIndex())
+ self.assertEqual(self.model.rowCount(qt.QModelIndex()), 2)
+
+ def testDropNewNxdata(self):
+ data = numpy.array([[[5]]])
+ nxdata = commonh5.Group("foo")
+ nxdata.attrs["NX_class"] = "NXdata"
+ nxdata.attrs["signal"] = "signal"
+ nxdata.create_dataset("signal", data=data)
+ mimedata = Hdf5DatasetMimeData(dataset=nxdata)
+ self.model.dropMimeData(mimedata, qt.Qt.CopyAction, -1, -1, qt.QModelIndex())
+ self.assertEqual(self.model.rowCount(qt.QModelIndex()), 2)
+
+ def testDropAxisDataset(self):
+ dataset = commonh5.Dataset("foo", numpy.array([1, 2, 3, 4]))
+ mimedata = Hdf5DatasetMimeData(dataset=dataset)
+ nxDataIndex = self.model.index(0, 0)
+ axesIndex = self.model.index(1, 0, nxDataIndex)
+ self.model.dropMimeData(mimedata, qt.Qt.CopyAction, -1, -1, axesIndex)
+ self.assertEqual(self.model.rowCount(qt.QModelIndex()), 1)
+ item = self.model.itemFromIndex(axesIndex)
+ self.assertIsNot(item.getDataset(), None)
+
+ def testMimeData(self):
+ nxDataIndex = self.model.index(0, 0)
+ signalIndex = self.model.index(0, 0, nxDataIndex)
+ mimeData = self.model.mimeData([signalIndex])
+ self.assertIsNot(mimeData, None)
+ self.assertIsInstance(mimeData, qt.QMimeData)
+
+ def testRemoveNxdataItem(self):
+ nxdataIndex = self.model.index(0, 0)
+ item = self.model.itemFromIndex(nxdataIndex)
+ self.model.removeNxdataItem(item)
+
+ def testAppendAxisToNxdataItem(self):
+ nxdataIndex = self.model.index(0, 0)
+ item = self.model.itemFromIndex(nxdataIndex)
+ self.model.appendAxisToNxdataItem(item)
+
+ def testRemoveAxisItem(self):
+ nxdataIndex = self.model.index(0, 0)
+ axesIndex = self.model.index(1, 0, nxdataIndex)
+ item = self.model.itemFromIndex(axesIndex)
+ self.model.removeAxisItem(item)
+
+
+def suite():
+ test_suite = unittest.TestSuite()
+ loader = unittest.defaultTestLoader.loadTestsFromTestCase
+ test_suite.addTest(loader(TestViewer))
+ test_suite.addTest(loader(TestAbout))
+ test_suite.addTest(loader(TestDataPanel))
+ test_suite.addTest(loader(TestCustomNxdataWidget))
+ test_suite.addTest(loader(TestCustomNxdataWidgetInteraction))
+ return test_suite
+
+
+if __name__ == '__main__':
+ unittest.main(defaultTest='suite')