Merge branch 'tests' into 'master'
Tests See merge request augustin_s/grum!5
This commit is contained in:
28
.gitlab-ci.yml
Normal file
28
.gitlab-ci.yml
Normal file
@ -0,0 +1,28 @@
|
||||
stages:
|
||||
- Test
|
||||
|
||||
tests:
|
||||
stage: Test
|
||||
variables:
|
||||
QT_QPA_PLATFORM: "offscreen"
|
||||
XDG_RUNTIME_DIR: "/tmp/runtime-root"
|
||||
|
||||
script:
|
||||
- pip install pytest pytest-random-order pytest-cov
|
||||
- pip install -e ./
|
||||
- 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 report
|
||||
- coverage xml
|
||||
|
||||
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
|
||||
artifacts:
|
||||
reports:
|
||||
cobertura: coverage.xml
|
||||
|
||||
|
@ -51,7 +51,7 @@ class MainWindow(QMainWindow):
|
||||
|
||||
self.setCentralWidget(splitter)
|
||||
|
||||
rst = RPCServerThread(host, port, doc_title_suffix=title)
|
||||
self.rst = rst = RPCServerThread(host, port, doc_title_suffix=title)
|
||||
rst.start()
|
||||
rst.server.register_function(self.new_plot)
|
||||
rst.server.register_function(self.append_data)
|
||||
|
@ -1,5 +1,9 @@
|
||||
from PyQt5.QtCore import QUrl
|
||||
from PyQt5.QtWebKitWidgets import QWebView
|
||||
|
||||
try:
|
||||
from PyQt5.QtWebKitWidgets import QWebView
|
||||
except ImportError:
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
|
||||
|
||||
|
||||
class WebView(QWebView):
|
||||
|
239
tests/test_mainwin.py
Normal file
239
tests/test_mainwin.py
Normal file
@ -0,0 +1,239 @@
|
||||
# import pytest
|
||||
import sys
|
||||
import unittest
|
||||
from math import isclose
|
||||
# from parameterized import parameterized
|
||||
from unittest import mock
|
||||
|
||||
from PyQt5.QtTest import QSignalSpy
|
||||
from PyQt5.QtWidgets import QApplication, QAction, QListWidget
|
||||
|
||||
from grum.cli import main
|
||||
from grum.dictlist.dictlistitem import DictListItem
|
||||
from grum.dictlist import DictList
|
||||
from grum import ctrl_c, theme, assets
|
||||
from grum.mainwin import MainWindow
|
||||
from grum.mdi import MDIArea, MDISubMultiPlot, MDISubPlot
|
||||
from grum.menus import BarMenu
|
||||
from grum.menus.rclickmenu import RClickMenu
|
||||
from grum.plotdesc import PlotDescription
|
||||
from grum.rpc import RPCServerThread
|
||||
|
||||
|
||||
class TestViewUnit(unittest.TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
print("setup")
|
||||
self.app = QApplication(sys.argv)
|
||||
theme.apply(self.app)
|
||||
# ctrl_c.setup(self.app)
|
||||
self.mw = MainWindow(add_examples=True)
|
||||
self.mw.show()
|
||||
|
||||
|
||||
def tearDown(self) -> None:
|
||||
print("teardown")
|
||||
self.mw.rst.wait_for_stop()
|
||||
self.app.quit()
|
||||
print("app quit called")
|
||||
del self.mw
|
||||
del self.app
|
||||
|
||||
|
||||
def test_defaults(self):
|
||||
mw = self.mw
|
||||
|
||||
assert mw.windowTitle() == "grum"
|
||||
# assert mw.windowIcon() == assets.icon()
|
||||
assert isinstance(mw.lst, DictList)
|
||||
|
||||
for key in mw.lst.lst.items:
|
||||
assert isinstance(mw.lst.lst.get(key), DictListItem)
|
||||
assert isinstance(mw.lst.lst.get(key).value, PlotDescription)
|
||||
|
||||
assert isinstance(mw.lst.menu, RClickMenu)
|
||||
assert isinstance(mw.menu_settings, BarMenu)
|
||||
|
||||
assert isinstance(mw.menu_settings.checkboxes["Open new plots"], QAction)
|
||||
|
||||
assert isinstance(mw.mdi, MDIArea)
|
||||
|
||||
|
||||
# @parameterized.expand([["Dotted line", "r"], ["Line", "r"], ["Dots", None]])
|
||||
def test_new_plot(self):
|
||||
mw = self.mw
|
||||
name = "plot_name"
|
||||
title = "plot_title"
|
||||
xlabel = "xlabel"
|
||||
ylabel = "ylabel"
|
||||
cfg = {"title": title, "xlabel": xlabel, "ylabel": ylabel}
|
||||
spy_sig_make_new_plot = QSignalSpy(mw.sig_make_new_plot)
|
||||
|
||||
mw.new_plot(name, cfg=cfg)
|
||||
|
||||
assert name in mw.lst.lst.items.keys()
|
||||
assert isinstance(mw.lst.lst.get(name).value, PlotDescription)
|
||||
assert mw.lst.lst.get(name).value.title == title
|
||||
assert mw.lst.lst.get(name).value.xlabel == xlabel
|
||||
assert mw.lst.lst.get(name).value.ylabel == ylabel
|
||||
|
||||
assert mw.menu_settings.checkboxes["Open new plots"].isChecked()
|
||||
assert len(spy_sig_make_new_plot) == 1 # assert called once
|
||||
assert spy_sig_make_new_plot[0][0] == name # assert called with name
|
||||
assert isinstance(spy_sig_make_new_plot[0][1], PlotDescription)
|
||||
|
||||
mw.menu_settings.checkboxes["Open new plots"].setChecked(False)
|
||||
assert mw.menu_settings.checkboxes["Open new plots"].isChecked() == False
|
||||
spy_sig_make_new_plot = QSignalSpy(mw.sig_make_new_plot)
|
||||
|
||||
mw.new_plot("new_name", cfg)
|
||||
|
||||
assert len(spy_sig_make_new_plot) == 0 # assert not called
|
||||
|
||||
mw.menu_settings.checkboxes["Open new plots"].setChecked(True)
|
||||
assert mw.menu_settings.checkboxes["Open new plots"].isChecked() == True
|
||||
spy_sig_make_new_plot = QSignalSpy(mw.sig_make_new_plot)
|
||||
new_name_item = mw.lst.lst.get("new_name")
|
||||
sub = MDISubPlot("new_name", new_name_item.value)
|
||||
mw.mdi.add(sub)
|
||||
|
||||
mw.new_plot("new_name", cfg)
|
||||
|
||||
assert len(spy_sig_make_new_plot) == 0 # assert not called
|
||||
|
||||
|
||||
def test_append_data(self):
|
||||
mw = self.mw
|
||||
sine_item = mw.lst.lst.get("sine")
|
||||
sine_item.set_alarm = mock.MagicMock()
|
||||
sine_item.value.append = mock.MagicMock()
|
||||
|
||||
point = (1, 2)
|
||||
|
||||
mw.append_data("sine", point)
|
||||
sine_item.value.append.assert_called_once_with(point)
|
||||
sine_item.set_alarm.assert_called_once_with(True)
|
||||
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mw.mdi.add(sub)
|
||||
sub.plot.setData = mock.MagicMock()
|
||||
|
||||
mw.append_data("sine", point)
|
||||
sub.plot.setData.assert_called_once_with(*sine_item.value.data)
|
||||
print(sine_item.set_alarm.call_args)
|
||||
assert sine_item.set_alarm.call_args[0][0] == False
|
||||
|
||||
|
||||
def test_on_make_new_plot(self):
|
||||
mw = self.mw
|
||||
|
||||
mw.make_subwin = mock.MagicMock()
|
||||
|
||||
args = (1, 2, "name")
|
||||
kwargs = {"title": "plot_title"}
|
||||
|
||||
mw.on_make_new_plot(args, kwargs)
|
||||
|
||||
mw.make_subwin.assert_called_once_with(MDISubPlot, args, kwargs)
|
||||
|
||||
|
||||
def test_on_dclick_list_item(self):
|
||||
|
||||
mw = self.mw
|
||||
mw.plot_single_item = mock.MagicMock()
|
||||
item = mw.lst.lst.get("sine")
|
||||
|
||||
mw.on_dclick_list_item(item)
|
||||
|
||||
mw.plot_single_item.assert_called_once_with(item)
|
||||
|
||||
|
||||
def test_on_plot_selected(self):
|
||||
mw = self.mw
|
||||
sine_item = mw.lst.lst.get("sine")
|
||||
cosine_item = mw.lst.lst.get("cosine")
|
||||
mw.lst.setCurrentItem(sine_item)
|
||||
assert mw.lst.selectedItems()
|
||||
mw.plot_single_item = mock.MagicMock()
|
||||
|
||||
mw.on_plot_selected()
|
||||
mw.plot_single_item.assert_called_once_with(sine_item)
|
||||
|
||||
mw.lst.setSelectionMode(QListWidget.MultiSelection)
|
||||
sine_item.setSelected(True)
|
||||
cosine_item.setSelected(True)
|
||||
|
||||
assert len(mw.lst.selectedItems()) == 2
|
||||
|
||||
mw.plot_multiple_items = mock.MagicMock()
|
||||
mw.on_plot_selected()
|
||||
mw.plot_multiple_items.assert_called_once_with([sine_item, cosine_item])
|
||||
|
||||
|
||||
def test_plot_single_item(self):
|
||||
mw = self.mw
|
||||
sine_item = mw.lst.lst.get("sine")
|
||||
sine_item.set_alarm = mock.MagicMock()
|
||||
mw.activate_or_make_subwin = mock.MagicMock()
|
||||
|
||||
mw.plot_single_item(sine_item)
|
||||
|
||||
sine_item.set_alarm.assert_called_once_with(False)
|
||||
mw.activate_or_make_subwin.assert_called_once_with(
|
||||
MDISubPlot, sine_item.key, sine_item.value
|
||||
)
|
||||
|
||||
|
||||
def test_plot_multiple_items(self):
|
||||
mw = self.mw
|
||||
sine_item = mw.lst.lst.get("sine")
|
||||
cosine_item = mw.lst.lst.get("cosine")
|
||||
names = ["sine", "cosine"]
|
||||
name = " | ".join(names)
|
||||
items = [sine_item, cosine_item]
|
||||
descs = (sine_item.value, cosine_item.value)
|
||||
|
||||
mw.activate_or_make_subwin = mock.MagicMock()
|
||||
|
||||
mw.plot_multiple_items(items)
|
||||
|
||||
mw.activate_or_make_subwin.assert_called_once_with(MDISubMultiPlot, name, descs)
|
||||
|
||||
|
||||
def test_activate_or_make_subwin(self):
|
||||
mw = self.mw
|
||||
sine_item = mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mw.mdi.add(sub)
|
||||
|
||||
cosine_item = mw.lst.get("cosine")
|
||||
|
||||
mw.mdi.setActiveSubWindow = mock.MagicMock()
|
||||
assert mw.mdi.findSubWindow("sine")
|
||||
|
||||
mw.activate_or_make_subwin(MDISubPlot, sine_item.key, sine_item.value)
|
||||
|
||||
mw.mdi.setActiveSubWindow.assert_called_once_with(sub)
|
||||
|
||||
mw.make_subwin = mock.MagicMock()
|
||||
mw.activate_or_make_subwin(MDISubPlot, cosine_item.key, cosine_item.value)
|
||||
mw.make_subwin.assert_called_once_with(
|
||||
MDISubPlot, cosine_item.key, cosine_item.value
|
||||
)
|
||||
|
||||
|
||||
def test_make_subwin(self):
|
||||
|
||||
mw = self.mw
|
||||
cosine_item = mw.lst.get("cosine")
|
||||
|
||||
mw.mdi.add = mock.MagicMock()
|
||||
# sub = MDISubPlot(cosine_item.key, cosine_item.value)
|
||||
|
||||
mw.make_subwin(MDISubPlot, cosine_item.key, cosine_item.value)
|
||||
|
||||
assert isinstance(mw.mdi.add.call_args[0][0], MDISubPlot)
|
||||
# mw.mdi.add.assert_called_once_with(sub)
|
||||
|
||||
|
||||
|
202
tests/test_mdiarea.py
Normal file
202
tests/test_mdiarea.py
Normal file
@ -0,0 +1,202 @@
|
||||
import sys
|
||||
import unittest
|
||||
from unittest import mock
|
||||
|
||||
from grum.mainwin import MainWindow
|
||||
from grum.mdi import MDIArea, MDISubMultiPlot, MDISubPlot
|
||||
from grum.mdi.mdisubwin import MDISubWindow
|
||||
from grum.theme import MDI_BKG
|
||||
|
||||
from PyQt5.QtGui import QPainter
|
||||
from PyQt5.QtWidgets import QApplication, QMdiArea
|
||||
|
||||
|
||||
class TestViewUnit(unittest.TestCase):
|
||||
|
||||
def setUp(self) -> None:
|
||||
print("setup")
|
||||
self.app = QApplication(sys.argv)
|
||||
self.mw = MainWindow(add_examples=True)
|
||||
self.mw.show()
|
||||
|
||||
|
||||
def tearDown(self) -> None:
|
||||
print("teardown")
|
||||
self.mw.rst.wait_for_stop()
|
||||
self.app.quit()
|
||||
print("app quit called")
|
||||
del self.mw
|
||||
del self.app
|
||||
|
||||
|
||||
def test_on_cascade(self):
|
||||
mdi = self.mw.mdi
|
||||
|
||||
mdi.enable_subwindow_view = mock.MagicMock()
|
||||
mdi.cascadeSubWindows = mock.MagicMock()
|
||||
mdi.menu.checkboxes["Multiple windows"].setChecked(False)
|
||||
assert mdi.menu.checkboxes["Multiple windows"].isChecked() == False
|
||||
|
||||
mdi.on_cascade()
|
||||
|
||||
assert mdi.menu.checkboxes["Multiple windows"].isChecked() == True
|
||||
mdi.enable_subwindow_view.assert_called_once()
|
||||
mdi.cascadeSubWindows.assert_called_once()
|
||||
|
||||
|
||||
def test_on_tile(self):
|
||||
mdi = self.mw.mdi
|
||||
|
||||
mdi.enable_subwindow_view = mock.MagicMock()
|
||||
mdi.tileSubWindows = mock.MagicMock()
|
||||
mdi.menu.checkboxes["Multiple windows"].setChecked(False)
|
||||
assert mdi.menu.checkboxes["Multiple windows"].isChecked() == False
|
||||
|
||||
mdi.on_tile()
|
||||
|
||||
assert mdi.menu.checkboxes["Multiple windows"].isChecked() == True
|
||||
mdi.enable_subwindow_view.assert_called_once()
|
||||
mdi.tileSubWindows.assert_called_once()
|
||||
|
||||
|
||||
def test_enable_single_window_mode(self):
|
||||
mdi = self.mw.mdi
|
||||
mdi.enable_subwindow_view = mock.MagicMock()
|
||||
mdi.closeInactiveSubWindows = mock.MagicMock()
|
||||
active = mdi.activeSubWindow()
|
||||
assert mdi.activeSubWindow() == None
|
||||
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mdi.addSubWindow(sub)
|
||||
mdi.setActiveSubWindow(MDISubWindow("sine"))
|
||||
|
||||
# assert mdi.activeSubWindow() != None
|
||||
|
||||
mdi.enable_single_window_mode()
|
||||
|
||||
mdi.enable_subwindow_view.assert_called_once()
|
||||
mdi.closeInactiveSubWindows.assert_called_once()
|
||||
|
||||
# active = mdi.activeSubWindow()
|
||||
# if active:
|
||||
# active.showMaximized()
|
||||
# active.frame_off()
|
||||
|
||||
|
||||
def test_enable_subwindow_view(self):
|
||||
mdi = self.mw.mdi
|
||||
|
||||
mdi.setViewMode = mock.MagicMock()
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mdi.addSubWindow(sub)
|
||||
sub.frame_on = mock.MagicMock()
|
||||
|
||||
mdi.enable_subwindow_view()
|
||||
|
||||
mdi.setViewMode.assert_called_once_with(QMdiArea.SubWindowView)
|
||||
|
||||
# sub.frame_on.assert_called_once() #TODO: check this
|
||||
|
||||
|
||||
def test_enable_tabbed_view(self):
|
||||
mdi = self.mw.mdi
|
||||
mdi.setViewMode = mock.MagicMock()
|
||||
|
||||
mdi.enable_tabbed_view()
|
||||
mdi.setViewMode.assert_called_once_with(QMdiArea.TabbedView)
|
||||
|
||||
|
||||
def test_add(self):
|
||||
mdi =self.mw.mdi
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mdi.add_multiple = mock.MagicMock()
|
||||
mdi.add_single = mock.MagicMock()
|
||||
assert mdi.menu.checkboxes["Single window"].isChecked() == False
|
||||
|
||||
mdi.add(sub)
|
||||
mdi.add_multiple.assert_called_once_with(sub)
|
||||
|
||||
mdi.menu.checkboxes['Single window'].setChecked(True)
|
||||
assert mdi.menu.checkboxes["Single window"].isChecked() == True
|
||||
|
||||
mdi.add(sub)
|
||||
mdi.add_single.assert_called_once_with(sub)
|
||||
|
||||
|
||||
def test_add_multiple(self):
|
||||
mdi = self.mw.mdi
|
||||
mdi.addSubWindow = mock.MagicMock()
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
sub.show = mock.MagicMock()
|
||||
|
||||
mdi.add_multiple(sub)
|
||||
mdi.addSubWindow.assert_called_once()
|
||||
sub.show.assert_called_once()
|
||||
|
||||
|
||||
def test_add_single(self):
|
||||
mdi = self.mw.mdi
|
||||
mdi.addSubWindow = mock.MagicMock()
|
||||
mdi.closeAllSubWindows = mock.MagicMock()
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
sub.showMaximized = mock.MagicMock()
|
||||
sub.frame_off = mock.MagicMock()
|
||||
|
||||
mdi.add_single(sub)
|
||||
|
||||
mdi.closeAllSubWindows.assert_called_once()
|
||||
mdi.addSubWindow.assert_called_once_with(sub)
|
||||
sub.showMaximized.assert_called_once()
|
||||
sub.frame_off.assert_called_once()
|
||||
|
||||
|
||||
def test_paintEvent(self):
|
||||
mdi = self.mw.mdi
|
||||
|
||||
mdi._draw_watermark = mock.MagicMock()
|
||||
mdi.paintEvent('event')
|
||||
mdi._draw_watermark.assert_called_once()
|
||||
|
||||
|
||||
def test_findSubWindow(self):
|
||||
mdi = self.mw.mdi
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mdi.add(sub)
|
||||
|
||||
ret = mdi.findSubWindow('sine')
|
||||
|
||||
assert ret == sub
|
||||
|
||||
ret = mdi.findSubWindow('cosine')
|
||||
|
||||
assert ret == None
|
||||
|
||||
|
||||
def test_closeInactiveSubWindows(self):
|
||||
mdi = self.mw.mdi
|
||||
|
||||
sine_item = self.mw.lst.lst.get("sine")
|
||||
sub = MDISubPlot("sine", sine_item.value)
|
||||
mdi.add(sub)
|
||||
cosine_item = self.mw.lst.lst.get("cosine")
|
||||
cosine_sub = MDISubPlot("cosine", cosine_item.value)
|
||||
mdi.add(cosine_sub)
|
||||
sub.close = mock.MagicMock()
|
||||
|
||||
mdi.closeInactiveSubWindows()
|
||||
|
||||
|
||||
active = mdi.activeSubWindow()
|
||||
assert active == cosine_sub
|
||||
for sub in mdi.subWindowList():
|
||||
if sub != active:
|
||||
sub.close.assert_called_once()
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user