Compare commits
19 Commits
tests
...
segfault-d
| Author | SHA1 | Date | |
|---|---|---|---|
| 72c51c5744 | |||
| 1e203873c9 | |||
| a80b568894 | |||
| 2edc68151d | |||
| aa03291e42 | |||
| 5d97dd6224 | |||
| bed086f95f | |||
| aa79f1b0a1 | |||
| bbb6d6c00c | |||
| c6f034f2d3 | |||
| a624cf37a4 | |||
| efd023ae3a | |||
| d65e97c9a7 | |||
| 4fcc10f3da | |||
| c781601246 | |||
| 831b03a744 | |||
| b94294b579 | |||
| b14f6e68b4 | |||
| 7d169fdd53 |
@@ -1,29 +1,62 @@
|
|||||||
stages:
|
stages:
|
||||||
- Test
|
- Tests
|
||||||
|
- OptionalTests
|
||||||
|
|
||||||
|
.install-grum-test: &install-grum-test
|
||||||
|
- pip install pytest pytest-random-order pytest-cov
|
||||||
|
- pip install -e ./
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install -y ffmpeg libnss3 libxcomposite1 libxtst6
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
stage: Test
|
stage: Tests
|
||||||
|
image: python:3.8
|
||||||
variables:
|
variables:
|
||||||
QT_QPA_PLATFORM: "offscreen"
|
QT_QPA_PLATFORM: "offscreen"
|
||||||
XDG_RUNTIME_DIR: "/tmp/runtime-root"
|
XDG_RUNTIME_DIR: "/tmp/runtime-root"
|
||||||
|
PYTHONFAULTHANDLER: 1
|
||||||
script:
|
script:
|
||||||
- pip install pytest pytest-random-order pytest-cov
|
- *install-grum-test
|
||||||
- pip install -e ./
|
- coverage run --source=./grum -m pytest ./tests --junitxml=report-junit.xml
|
||||||
- pip install PyQtWebEngine
|
|
||||||
|
|
||||||
- apt-get update
|
|
||||||
- apt-get install -y ffmpeg libnss3 libxcomposite1 libxtst6
|
|
||||||
|
|
||||||
# - python -m unittest discover -f ./tests
|
|
||||||
# - coverage run --source=./grum -m unittest discover -f ./tests
|
|
||||||
- coverage run --source=./grum -m pytest ./tests
|
|
||||||
- coverage report
|
- coverage report
|
||||||
- coverage xml
|
- coverage xml
|
||||||
|
|
||||||
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
|
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
|
||||||
artifacts:
|
artifacts:
|
||||||
|
when: always
|
||||||
reports:
|
reports:
|
||||||
cobertura: coverage.xml
|
cobertura: coverage.xml
|
||||||
|
junit: report-junit.xml
|
||||||
|
|
||||||
|
tests-3.6:
|
||||||
|
stage: OptionalTests
|
||||||
|
image: python:3.6
|
||||||
|
needs: ["tests"]
|
||||||
|
allow_failure: true
|
||||||
|
variables:
|
||||||
|
QT_QPA_PLATFORM: "offscreen"
|
||||||
|
XDG_RUNTIME_DIR: "/tmp/runtime-root"
|
||||||
|
PYTHONFAULTHANDLER: 1
|
||||||
|
script:
|
||||||
|
- *install-grum-test
|
||||||
|
- pytest ./tests
|
||||||
|
|
||||||
|
tests-3.7:
|
||||||
|
extends: "tests-3.6"
|
||||||
|
image: python:3.7
|
||||||
|
|
||||||
|
#tests-3.8:
|
||||||
|
# extends: "tests-3.6"
|
||||||
|
# image: python:3.8
|
||||||
|
|
||||||
|
tests-3.9:
|
||||||
|
extends: "tests-3.6"
|
||||||
|
image: python:3.9
|
||||||
|
|
||||||
|
tests-3.10:
|
||||||
|
extends: "tests-3.6"
|
||||||
|
image: python:3.10
|
||||||
|
|
||||||
|
tests-3.11:
|
||||||
|
extends: "tests-3.6"
|
||||||
|
image: python:3.11
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ class MainWindow(QMainWindow):
|
|||||||
rst.start()
|
rst.start()
|
||||||
rst.server.register_function(self.new_plot)
|
rst.server.register_function(self.new_plot)
|
||||||
rst.server.register_function(self.append_data)
|
rst.server.register_function(self.append_data)
|
||||||
|
rst.server.register_function(self.extend_data)
|
||||||
|
rst.server.register_function(self.set_data)
|
||||||
|
|
||||||
self.sig_make_new_plot.connect(self.on_make_new_plot)
|
self.sig_make_new_plot.connect(self.on_make_new_plot)
|
||||||
|
|
||||||
@@ -116,14 +118,27 @@ class MainWindow(QMainWindow):
|
|||||||
item = self.lst.get(name)
|
item = self.lst.get(name)
|
||||||
desc = item.value
|
desc = item.value
|
||||||
desc.append(point)
|
desc.append(point)
|
||||||
alarm = True
|
self.sync_item_and_plots(item)
|
||||||
for sub in self.mdi.subWindowList():
|
|
||||||
if name in sub.plots:
|
def extend_data(self, name, data):
|
||||||
plot = sub.plots[name]
|
"""
|
||||||
plot.setData(*desc.data)
|
Extend the current data of the (existing) plot <name>.by <data>
|
||||||
alarm = False
|
The data is forwarded to the extend method of PlotDescription.
|
||||||
item.timestamps.modification.update()
|
"""
|
||||||
item.set_alarm(alarm)
|
item = self.lst.get(name)
|
||||||
|
desc = item.value
|
||||||
|
desc.extend(data)
|
||||||
|
self.sync_item_and_plots(item)
|
||||||
|
|
||||||
|
def set_data(self, name, data):
|
||||||
|
"""
|
||||||
|
Set <data> as the data of the (existing) plot <name>.
|
||||||
|
The data is assigned to the data attribute of PlotDescription.
|
||||||
|
"""
|
||||||
|
item = self.lst.get(name)
|
||||||
|
desc = item.value
|
||||||
|
desc.data = data
|
||||||
|
self.sync_item_and_plots(item)
|
||||||
|
|
||||||
|
|
||||||
# Signal callbacks
|
# Signal callbacks
|
||||||
@@ -196,6 +211,17 @@ class MainWindow(QMainWindow):
|
|||||||
self.lst.set(name, desc)
|
self.lst.set(name, desc)
|
||||||
return desc
|
return desc
|
||||||
|
|
||||||
|
def sync_item_and_plots(self, item):
|
||||||
|
name, desc = item.key, item.value
|
||||||
|
alarm = True
|
||||||
|
for sub in self.mdi.subWindowList():
|
||||||
|
if name in sub.plots:
|
||||||
|
plot = sub.plots[name]
|
||||||
|
plot.setData(*desc.data)
|
||||||
|
alarm = False
|
||||||
|
item.timestamps.modification.update()
|
||||||
|
item.set_alarm(alarm)
|
||||||
|
|
||||||
def plot_single_item(self, item):
|
def plot_single_item(self, item):
|
||||||
item.timestamps.access.update()
|
item.timestamps.access.update()
|
||||||
item.set_alarm(False)
|
item.set_alarm(False)
|
||||||
|
|||||||
@@ -14,12 +14,21 @@ class PlotDescription:
|
|||||||
def data(self):
|
def data(self):
|
||||||
return (self.xs, self.ys)
|
return (self.xs, self.ys)
|
||||||
|
|
||||||
|
@data.setter
|
||||||
|
def data(self, value):
|
||||||
|
self.xs, self.ys = value
|
||||||
|
|
||||||
|
|
||||||
def append(self, xy):
|
def append(self, xy):
|
||||||
x, y = xy
|
x, y = xy
|
||||||
self.xs.append(x)
|
self.xs.append(x)
|
||||||
self.ys.append(y)
|
self.ys.append(y)
|
||||||
|
|
||||||
|
def extend(self, data):
|
||||||
|
xs, ys = data
|
||||||
|
self.xs.extend(xs)
|
||||||
|
self.ys.extend(ys)
|
||||||
|
|
||||||
|
|
||||||
def make_plot(self, plotwidget, style):
|
def make_plot(self, plotwidget, style):
|
||||||
res = plotwidget.plot(self.xs, self.ys, name=self.name, **style)
|
res = plotwidget.plot(self.xs, self.ys, name=self.name, **style)
|
||||||
|
|||||||
@@ -16,4 +16,10 @@ class RPCClient(xrc.ServerProxy):
|
|||||||
return head + help
|
return head + help
|
||||||
|
|
||||||
|
|
||||||
|
def __dir__(self):
|
||||||
|
d1 = super().__dir__()
|
||||||
|
d2 = self.utils.info().keys()
|
||||||
|
return [*d1, *d2]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ classifiers =
|
|||||||
package_dir =
|
package_dir =
|
||||||
= .
|
= .
|
||||||
packages = find:
|
packages = find:
|
||||||
python_requires = >=3.8
|
python_requires = >=3.6
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
where = .
|
where = .
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -2,7 +2,7 @@ from setuptools import setup
|
|||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
setup(
|
setup(
|
||||||
install_requires=["pyqt5", "pyqtgraph", "h5py"],
|
install_requires=["pyqt5", "pyqtgraph", "h5py", "PyQtWebEngine"],
|
||||||
entry_points={"console_scripts": ["grum=grum:main"]},
|
entry_points={"console_scripts": ["grum=grum:main"]},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
from grum.dictlist.dictlistwidget import DictListWidget
|
|
||||||
from grum.menus.rclickmenu import RClickMenu
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DictListWidgetMock(DictListWidget):
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.items = {}
|
|
||||||
self.nkeep = None
|
|
||||||
|
|
||||||
def get_DictListWidgetMock():
|
|
||||||
return DictListWidgetMock()
|
|
||||||
|
|
||||||
# def test_defaults():
|
|
||||||
# dlw = get_DictListWidgetMock()
|
|
||||||
|
|
||||||
# assert dlw.items == {}
|
|
||||||
# assert dlw.nkeep == None
|
|
||||||
|
|
||||||
# def test_add_menu():
|
|
||||||
# dlw = get_DictListWidgetMock()
|
|
||||||
# dlw._add_menu()
|
|
||||||
|
|
||||||
# assert dlw.menu == RClickMenu(dlw)
|
|
||||||
@@ -21,6 +21,7 @@ from grum.rpc import RPCServerThread
|
|||||||
class TestMainWin:
|
class TestMainWin:
|
||||||
|
|
||||||
def setup_method(self):
|
def setup_method(self):
|
||||||
|
print("setup")
|
||||||
self.app = QApplication(sys.argv)
|
self.app = QApplication(sys.argv)
|
||||||
theme.apply(self.app)
|
theme.apply(self.app)
|
||||||
# ctrl_c.setup(self.app)
|
# ctrl_c.setup(self.app)
|
||||||
@@ -29,8 +30,10 @@ class TestMainWin:
|
|||||||
|
|
||||||
|
|
||||||
def teardown_method(self):
|
def teardown_method(self):
|
||||||
|
print("teardown")
|
||||||
self.mw.rst.wait_for_stop()
|
self.mw.rst.wait_for_stop()
|
||||||
self.app.quit()
|
self.app.quit()
|
||||||
|
print("app quit called")
|
||||||
del self.mw
|
del self.mw
|
||||||
del self.app
|
del self.app
|
||||||
|
|
||||||
@@ -165,19 +168,6 @@ class TestMainWin:
|
|||||||
mw.plot_multiple_items.assert_called_once_with([sine_item, cosine_item])
|
mw.plot_multiple_items.assert_called_once_with([sine_item, cosine_item])
|
||||||
|
|
||||||
|
|
||||||
def test_on_sort_by_name(self):
|
|
||||||
mw = self.mw
|
|
||||||
mw.lst = DictList()
|
|
||||||
mw.new_plot("bb", {})
|
|
||||||
mw.new_plot("dd", {})
|
|
||||||
mw.new_plot("aa", {})
|
|
||||||
mw.new_plot("cc", {})
|
|
||||||
|
|
||||||
assert mw.lst.lst.items == 111
|
|
||||||
assert [key for key in mw.lst.lst.items.keys()] == ['bb', 'dd', 'aa', 'cc']
|
|
||||||
mw.on_sort_by_name()
|
|
||||||
assert mw.lst.lst.items == 111
|
|
||||||
|
|
||||||
def test_plot_single_item(self):
|
def test_plot_single_item(self):
|
||||||
mw = self.mw
|
mw = self.mw
|
||||||
sine_item = mw.lst.lst.get("sine")
|
sine_item = mw.lst.lst.get("sine")
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ class TestMDIArea:
|
|||||||
def setup_method(self):
|
def setup_method(self):
|
||||||
print("setup")
|
print("setup")
|
||||||
self.app = QApplication(sys.argv)
|
self.app = QApplication(sys.argv)
|
||||||
self.mw = MainWindow(add_examples=True)
|
self.mw = MainWindow(add_examples=True, offline=True)
|
||||||
self.mw.show()
|
self.mw.show()
|
||||||
|
|
||||||
|
|
||||||
def teardown_method(self):
|
def teardown_method(self):
|
||||||
print("teardown")
|
print("teardown")
|
||||||
self.mw.rst.wait_for_stop()
|
# self.mw.rst.wait_for_stop()
|
||||||
self.app.quit()
|
self.app.quit()
|
||||||
print("app quit called")
|
print("app quit called")
|
||||||
del self.mw
|
del self.mw
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ def test_make_plot():
|
|||||||
)
|
)
|
||||||
app = QApplication(sys.argv)
|
app = QApplication(sys.argv)
|
||||||
theme.apply(app)
|
theme.apply(app)
|
||||||
mw = MainWindow(add_examples=True)
|
mw = MainWindow(add_examples=True, offline=True)
|
||||||
|
|
||||||
mdi_sub = MDISubPlot("mdi", pd)
|
mdi_sub = MDISubPlot("mdi", pd)
|
||||||
pw = pg.PlotWidget()
|
pw = pg.PlotWidget()
|
||||||
|
|||||||
Reference in New Issue
Block a user