mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
Port unittests to pytest-qt (fixes #1)
This commit is contained in:
parent
e2dd0339d7
commit
bc7ce7e09c
28 changed files with 4111 additions and 3726 deletions
3
.github/workflows/pytest.yml
vendored
3
.github/workflows/pytest.yml
vendored
|
|
@ -18,11 +18,12 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install libgl1-mesa-glx libegl1 libglib2.0-0 libxcb-image0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1-dev xserver-xephyr libfontconfig1 libxkbcommon-dev libdbus-1-3
|
||||
sudo apt install libgl1-mesa-glx libegl1 libglib2.0-0 libxcb-image0 libxkbcommon-x11-0 libxcb-icccm4 libxcb-keysyms1 xserver-xephyr libfontconfig1 libxkbcommon-dev libdbus-1-3 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xfixes0
|
||||
sudo apt install xvfb
|
||||
python -m pip install --upgrade pip
|
||||
pip install .
|
||||
pip install -r requirements/dev.txt
|
||||
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -screen 0 1920x1200x24 -ac +extension GLX
|
||||
- name: Run Unittests with pytest
|
||||
run: |
|
||||
xvfb-run coverage run --source=beeref -m pytest -v -s
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ def main():
|
|||
logger.info(f'Starting {constants.APPNAME} version {constants.VERSION}')
|
||||
settings = BeeSettings()
|
||||
logger.info(f'Using settings: {settings.fileName()}')
|
||||
logger.info(f'Logging to: {logfile_name}')
|
||||
logger.info(f'Logging to: {logfile_name()}')
|
||||
CommandlineArgs(with_check=True) # Force checking
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
|
||||
|
|
|
|||
|
|
@ -137,8 +137,10 @@ class BeeSettings(QtCore.QSettings):
|
|||
return values
|
||||
|
||||
|
||||
logfile_name = os.path.join(
|
||||
os.path.dirname(BeeSettings().fileName()), f'{constants.APPNAME}.log')
|
||||
def logfile_name():
|
||||
return os.path.join(
|
||||
os.path.dirname(BeeSettings().fileName()), f'{constants.APPNAME}.log')
|
||||
|
||||
|
||||
logging_conf = {
|
||||
'version': 1,
|
||||
|
|
@ -161,7 +163,7 @@ logging_conf = {
|
|||
'file': {
|
||||
'class': 'beeref.utils.BeeRotatingFileHandler',
|
||||
'formatter': 'verbose',
|
||||
'filename': logfile_name,
|
||||
'filename': logfile_name(),
|
||||
'maxBytes': 1024 * 1000 * 50,
|
||||
'backupCount': 1,
|
||||
'level': 'DEBUG',
|
||||
|
|
|
|||
|
|
@ -43,8 +43,9 @@ def handle_sqlite_errors(func):
|
|||
func(self, *args, **kwargs)
|
||||
except sqlite3.Error as e:
|
||||
logger.exception(f'Error while reading/writing {self.filename}')
|
||||
self._close_connection()
|
||||
if self.worker:
|
||||
self.worker.finished.emit('', [str(e)])
|
||||
self.worker.finished.emit(self.filename, [str(e)])
|
||||
else:
|
||||
raise BeeFileIOError(msg=str(e), filename=self.filename) from e
|
||||
|
||||
|
|
|
|||
|
|
@ -105,23 +105,23 @@ class DebugLogDialog(QtWidgets.QDialog):
|
|||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.setWindowTitle(f'{constants.APPNAME} Debug Log')
|
||||
with open(logfile_name) as f:
|
||||
with open(logfile_name()) as f:
|
||||
self.log_txt = f.read()
|
||||
|
||||
log = QtWidgets.QLabel(self.log_txt)
|
||||
log.setTextInteractionFlags(
|
||||
self.log = QtWidgets.QLabel(self.log_txt)
|
||||
self.log.setTextInteractionFlags(
|
||||
Qt.TextInteractionFlag.TextSelectableByMouse)
|
||||
scroll = QtWidgets.QScrollArea(self)
|
||||
scroll.setWidgetResizable(True)
|
||||
scroll.setWidget(log)
|
||||
scroll.setWidget(self.log)
|
||||
|
||||
buttons = QtWidgets.QDialogButtonBox(
|
||||
QtWidgets.QDialogButtonBox.StandardButton.Close)
|
||||
buttons.rejected.connect(self.reject)
|
||||
copy_button = QtWidgets.QPushButton('Co&py To Clipboard')
|
||||
copy_button.released.connect(self.copy_to_clipboard)
|
||||
self.copy_button = QtWidgets.QPushButton('Co&py To Clipboard')
|
||||
self.copy_button.released.connect(self.copy_to_clipboard)
|
||||
buttons.addButton(
|
||||
copy_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
|
||||
self.copy_button, QtWidgets.QDialogButtonBox.ButtonRole.ActionRole)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout()
|
||||
self.setLayout(layout)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
def __init__(self, app, parent=None):
|
||||
super().__init__(parent)
|
||||
self.app = app
|
||||
self.parent = parent
|
||||
self.settings = BeeSettings()
|
||||
self.setBackgroundBrush(QtGui.QBrush(QtGui.QColor(60, 60, 60)))
|
||||
|
||||
|
|
@ -94,7 +95,7 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
name = os.path.basename(self.filename or '[Untitled]')
|
||||
clean = '' if clean else '*'
|
||||
title = f'{name}{clean} - {constants.APPNAME}'
|
||||
self.parent().setWindowTitle(title)
|
||||
self.parent.setWindowTitle(title)
|
||||
|
||||
def on_scene_changed(self, region):
|
||||
if not self.scene.items():
|
||||
|
|
@ -169,16 +170,16 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
|
||||
def on_action_fullscreen(self, checked):
|
||||
if checked:
|
||||
self.parent().showFullScreen()
|
||||
self.parent.showFullScreen()
|
||||
else:
|
||||
self.parent().showNormal()
|
||||
self.parent.showNormal()
|
||||
|
||||
def on_action_always_on_top(self, checked):
|
||||
self.parent().setWindowFlag(
|
||||
self.parent.setWindowFlag(
|
||||
Qt.WindowType.WindowStaysOnTopHint, on=checked)
|
||||
self.parent().destroy()
|
||||
self.parent().create()
|
||||
self.parent().show()
|
||||
self.parent.destroy()
|
||||
self.parent.create()
|
||||
self.parent.show()
|
||||
|
||||
def on_action_show_scrollbars(self, checked):
|
||||
if checked:
|
||||
|
|
@ -194,9 +195,9 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
|
||||
def on_action_show_menubar(self, checked):
|
||||
if checked:
|
||||
self.parent().setMenuBar(self.create_menubar())
|
||||
self.parent.setMenuBar(self.create_menubar())
|
||||
else:
|
||||
self.parent().setMenuBar(None)
|
||||
self.parent.setMenuBar(None)
|
||||
|
||||
def on_action_undo(self):
|
||||
logger.debug('Undo: %s' % self.undo_stack.undoText())
|
||||
|
|
@ -270,8 +271,6 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
self.scene.add_queued_items()
|
||||
|
||||
def on_loading_finished(self, filename, errors):
|
||||
if filename:
|
||||
self.filename = filename
|
||||
if errors:
|
||||
QtWidgets.QMessageBox.warning(
|
||||
self,
|
||||
|
|
@ -279,6 +278,7 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
('<p>Problem loading file %s</p>'
|
||||
'<p>Not accessible or not a proper bee file</p>') % filename)
|
||||
else:
|
||||
self.filename = filename
|
||||
self.scene.add_queued_items()
|
||||
self.on_action_fit_scene()
|
||||
|
||||
|
|
@ -305,15 +305,15 @@ class BeeGraphicsView(QtWidgets.QGraphicsView, ActionsMixin):
|
|||
self.filename = filename
|
||||
|
||||
def on_saving_finished(self, filename, errors):
|
||||
if filename:
|
||||
self.filename = filename
|
||||
self.undo_stack.setClean()
|
||||
else:
|
||||
if errors:
|
||||
QtWidgets.QMessageBox.warning(
|
||||
self,
|
||||
'Problem saving file',
|
||||
('<p>Problem saving file %s</p>'
|
||||
'<p>File/directory not accessible</p>') % filename)
|
||||
else:
|
||||
self.filename = filename
|
||||
self.undo_stack.setClean()
|
||||
|
||||
def do_save(self, filename, create_new):
|
||||
if not filename.endswith('.bee'):
|
||||
|
|
|
|||
|
|
@ -2,3 +2,4 @@ coverage
|
|||
flake8
|
||||
httpretty
|
||||
pytest
|
||||
git+https://github.com/pytest-dev/pytest-qt.git
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ from PyQt6 import QtWidgets
|
|||
|
||||
from beeref.actions import ActionsMixin
|
||||
from beeref.actions.menu_structure import MENU_SEPARATOR
|
||||
from ..base import BeeTestCase
|
||||
|
||||
|
||||
class FooWidget(QtWidgets.QWidget, ActionsMixin):
|
||||
|
|
@ -23,226 +22,265 @@ class FooWidget(QtWidgets.QWidget, ActionsMixin):
|
|||
pass
|
||||
|
||||
|
||||
class ActionsMixinTestCase(BeeTestCase):
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_actions(
|
||||
actions_mock, menu_mock, toggle_mock, trigger_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'shortcuts': ['Ctrl+F'],
|
||||
'callback': 'on_foo',
|
||||
}]
|
||||
|
||||
def setUp(self):
|
||||
menu_patcher = patch('beeref.actions.mixin.menu_structure')
|
||||
self.menu_mock = menu_patcher.start()
|
||||
self.addCleanup(menu_patcher.stop)
|
||||
actions_patcher = patch('beeref.actions.mixin.actions')
|
||||
self.actions_mock = actions_patcher.start()
|
||||
self.addCleanup(actions_patcher.stop)
|
||||
self.widget = FooWidget()
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
widget.build_menu_and_actions()
|
||||
trigger_mock.connect.assert_called_once_with(widget.on_foo)
|
||||
toggle_mock.connect.assert_not_called()
|
||||
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
def test_create_actions(self, toggle_mock, trigger_mock):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'shortcuts': ['Ctrl+F'],
|
||||
'callback': 'on_foo',
|
||||
}]
|
||||
assert len(widget.actions()) == 1
|
||||
qaction = widget.actions()[0]
|
||||
assert qaction.text() == '&Foo'
|
||||
assert qaction.shortcut() == 'Ctrl+F'
|
||||
assert qaction.isEnabled() is True
|
||||
assert widget.bee_actions['foo'] == qaction
|
||||
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
self.widget.build_menu_and_actions()
|
||||
trigger_mock.connect.assert_called_once_with(self.widget.on_foo)
|
||||
toggle_mock.connect.assert_not_called()
|
||||
|
||||
assert len(self.widget.actions()) == 1
|
||||
qaction = self.widget.actions()[0]
|
||||
assert qaction.text() == '&Foo'
|
||||
assert qaction.shortcut() == 'Ctrl+F'
|
||||
assert qaction.isEnabled() is True
|
||||
assert self.widget.bee_actions['foo'] == qaction
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_actions_checkable(
|
||||
actions_mock, menu_mock, toggle_mock, trigger_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'checkable': True,
|
||||
'callback': 'on_foo',
|
||||
}]
|
||||
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
def test_create_actions_checkable(self, toggle_mock, trigger_mock):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'checkable': True,
|
||||
'callback': 'on_foo',
|
||||
}]
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
widget.build_menu_and_actions()
|
||||
trigger_mock.connect.assert_not_called()
|
||||
toggle_mock.connect.assert_called_once_with(widget.on_foo)
|
||||
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
self.widget.build_menu_and_actions()
|
||||
trigger_mock.connect.assert_not_called()
|
||||
toggle_mock.connect.assert_called_once_with(self.widget.on_foo)
|
||||
assert len(widget.actions()) == 1
|
||||
qaction = widget.actions()[0]
|
||||
assert qaction.text() == '&Foo'
|
||||
assert qaction.isEnabled() is True
|
||||
assert qaction.isChecked() is False
|
||||
assert widget.bee_actions['foo'] == qaction
|
||||
|
||||
assert len(self.widget.actions()) == 1
|
||||
qaction = self.widget.actions()[0]
|
||||
assert qaction.text() == '&Foo'
|
||||
assert qaction.isEnabled() is True
|
||||
assert qaction.isChecked() is False
|
||||
assert self.widget.bee_actions['foo'] == qaction
|
||||
|
||||
@patch.object(FooWidget, 'on_foo')
|
||||
@patch.object(FooWidget, 'settings')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
def test_create_actions_checkable_with_settings(
|
||||
self, toggle_mock, settings_mock, callback_mock):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'checkable': True,
|
||||
'callback': 'on_foo',
|
||||
'settings': 'foo/bar',
|
||||
}]
|
||||
@patch.object(FooWidget, 'on_foo')
|
||||
@patch.object(FooWidget, 'settings')
|
||||
@patch('PyQt6.QtGui.QAction.toggled')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_actions_checkable_with_settings(
|
||||
actions_mock, menu_mock, toggle_mock, settings_mock, callback_mock,
|
||||
qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'checkable': True,
|
||||
'callback': 'on_foo',
|
||||
'settings': 'foo/bar',
|
||||
}]
|
||||
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
settings_mock.value.return_value = True
|
||||
self.widget.build_menu_and_actions()
|
||||
settings_mock.value.assert_called_once_with(
|
||||
'foo/bar', False, type=bool)
|
||||
qaction = self.widget.actions()[0]
|
||||
assert qaction.isChecked() is True
|
||||
assert toggle_mock.connect.call_count == 2
|
||||
callback_mock.assert_called_once_with(True)
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
settings_mock.value.return_value = True
|
||||
widget.build_menu_and_actions()
|
||||
settings_mock.value.assert_called_once_with(
|
||||
'foo/bar', False, type=bool)
|
||||
qaction = widget.actions()[0]
|
||||
assert qaction.isChecked() is True
|
||||
assert toggle_mock.connect.call_count == 2
|
||||
callback_mock.assert_called_once_with(True)
|
||||
|
||||
def test_create_actions_with_group(self):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_actions_with_group(actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
widget.build_menu_and_actions()
|
||||
assert len(widget.actions()) == 1
|
||||
qaction = widget.actions()[0]
|
||||
assert widget.bee_actiongroups['bar'] == [qaction]
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_build_menu_and_actions_with_actions(actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
with patch('PyQt6.QtWidgets.QMenu.addAction') as add_mock:
|
||||
widget.build_menu_and_actions()
|
||||
assert isinstance(widget.context_menu, QtWidgets.QMenu)
|
||||
add_mock.assert_called_once_with(widget.bee_actions['foo'])
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_build_menu_and_actions_with_separator(actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
menu_mock.__iter__.return_value = [MENU_SEPARATOR]
|
||||
with patch('PyQt6.QtWidgets.QMenu.addSeparator') as sep_mock:
|
||||
widget.build_menu_and_actions()
|
||||
assert isinstance(widget.context_menu, QtWidgets.QMenu)
|
||||
sep_mock.assert_called_once_with()
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_build_menu_and_actions_with_submenu(actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
menu_mock.__iter__.return_value = [
|
||||
{'menu': '&Bar', 'items': ['foo']}]
|
||||
with patch('PyQt6.QtWidgets.QMenu.addAction') as add_mock:
|
||||
with patch('PyQt6.QtWidgets.QMenu.addMenu') as addmenu_mock:
|
||||
addmenu_mock.return_value = QtWidgets.QMenu()
|
||||
widget.build_menu_and_actions()
|
||||
assert isinstance(widget.context_menu, QtWidgets.QMenu)
|
||||
addmenu_mock.assert_called_once_with('&Bar')
|
||||
add_mock.assert_called_once_with(widget.bee_actions['foo'])
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_actiongroup_set_enabled(actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
actions_mock.__iter__.return_value = [
|
||||
{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
self.widget.build_menu_and_actions()
|
||||
assert len(self.widget.actions()) == 1
|
||||
qaction = self.widget.actions()[0]
|
||||
assert self.widget.bee_actiongroups['bar'] == [qaction]
|
||||
'group': 'g1',
|
||||
},
|
||||
{
|
||||
'id': 'bar',
|
||||
'text': '&Bar',
|
||||
'callback': 'on_foo',
|
||||
'group': 'g2',
|
||||
},
|
||||
]
|
||||
|
||||
def test_build_menu_and_actions_with_actions(self):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
widget.build_menu_and_actions()
|
||||
widget.actiongroup_set_enabled('g1', True)
|
||||
assert widget.bee_actions['foo'].isEnabled() is True
|
||||
assert widget.bee_actions['bar'].isEnabled() is False
|
||||
|
||||
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_build_menu_and_actions_disables_actiongroups(
|
||||
actions_mock, menu_mock, qapp):
|
||||
widget = FooWidget()
|
||||
widget.scene.has_selection.return_value = False
|
||||
actions_mock.__iter__.return_value = [
|
||||
{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
with patch('PyQt6.QtWidgets.QMenu.addAction') as add_mock:
|
||||
self.widget.build_menu_and_actions()
|
||||
assert isinstance(self.widget.context_menu, QtWidgets.QMenu)
|
||||
add_mock.assert_called_once_with(self.widget.bee_actions['foo'])
|
||||
'group': 'active_when_selection',
|
||||
},
|
||||
]
|
||||
|
||||
def test_build_menu_and_actions_with_separator(self):
|
||||
self.menu_mock.__iter__.return_value = [MENU_SEPARATOR]
|
||||
with patch('PyQt6.QtWidgets.QMenu.addSeparator') as sep_mock:
|
||||
self.widget.build_menu_and_actions()
|
||||
assert isinstance(self.widget.context_menu, QtWidgets.QMenu)
|
||||
sep_mock.assert_called_once_with()
|
||||
menu_mock.__iter__.return_value = ['foo']
|
||||
widget.build_menu_and_actions()
|
||||
qaction = widget.actions()[0]
|
||||
assert qaction.isEnabled() is False
|
||||
|
||||
def test_build_menu_and_actions_with_submenu(self):
|
||||
self.actions_mock.__iter__.return_value = [{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'bar',
|
||||
}]
|
||||
self.menu_mock.__iter__.return_value = [
|
||||
{'menu': '&Bar', 'items': ['foo']}]
|
||||
with patch('PyQt6.QtWidgets.QMenu.addAction') as add_mock:
|
||||
with patch('PyQt6.QtWidgets.QMenu.addMenu') as addmenu_mock:
|
||||
addmenu_mock.return_value = QtWidgets.QMenu()
|
||||
self.widget.build_menu_and_actions()
|
||||
assert isinstance(self.widget.context_menu, QtWidgets.QMenu)
|
||||
addmenu_mock.assert_called_once_with('&Bar')
|
||||
add_mock.assert_called_once_with(
|
||||
self.widget.bee_actions['foo'])
|
||||
|
||||
def test_actiongroup_set_enabled(self):
|
||||
self.actions_mock.__iter__.return_value = [
|
||||
{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'g1',
|
||||
},
|
||||
{
|
||||
'id': 'bar',
|
||||
'text': '&Bar',
|
||||
'callback': 'on_foo',
|
||||
'group': 'g2',
|
||||
},
|
||||
]
|
||||
@patch('beeref.config.BeeSettings.get_recent_files')
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_create_recent_files(
|
||||
actions_mock, menu_mock, triggered_mock, files_mock, qapp):
|
||||
widget = FooWidget()
|
||||
files_mock.return_value = [
|
||||
os.path.abspath(f'{i}.bee') for i in range(15)]
|
||||
menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
self.widget.build_menu_and_actions()
|
||||
self.widget.actiongroup_set_enabled('g1', True)
|
||||
assert self.widget.bee_actions['foo'].isEnabled() is True
|
||||
assert self.widget.bee_actions['bar'].isEnabled() is False
|
||||
widget.build_menu_and_actions()
|
||||
triggered_mock.connect.assert_called()
|
||||
assert len(widget.actions()) == 15
|
||||
qaction1 = widget.actions()[0]
|
||||
assert qaction1.text() == '0.bee'
|
||||
assert qaction1.shortcut() == 'Ctrl+1'
|
||||
assert qaction1.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_0'] == qaction1
|
||||
qaction10 = widget.actions()[9]
|
||||
assert qaction10.text() == '9.bee'
|
||||
assert qaction10.shortcut() == 'Ctrl+0'
|
||||
assert qaction10.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_9'] == qaction10
|
||||
qaction15 = widget.actions()[-1]
|
||||
assert qaction15.text() == '14.bee'
|
||||
assert qaction15.shortcut() == ''
|
||||
assert qaction15.isEnabled() is True
|
||||
assert widget.bee_actions['recent_files_14'] == qaction15
|
||||
|
||||
def test_build_menu_and_actions_disables_actiongroups(self):
|
||||
self.widget.scene.has_selection.return_value = False
|
||||
self.actions_mock.__iter__.return_value = [
|
||||
{
|
||||
'id': 'foo',
|
||||
'text': '&Foo',
|
||||
'callback': 'on_foo',
|
||||
'group': 'active_when_selection',
|
||||
},
|
||||
]
|
||||
|
||||
self.menu_mock.__iter__.return_value = ['foo']
|
||||
self.widget.build_menu_and_actions()
|
||||
qaction = self.widget.actions()[0]
|
||||
assert qaction.isEnabled() is False
|
||||
@patch('beeref.config.BeeSettings.get_recent_files')
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
@patch('beeref.actions.mixin.menu_structure')
|
||||
@patch('beeref.actions.mixin.actions')
|
||||
def test_update_recent_files(
|
||||
actions_mock, menu_mock, triggered_mock, files_mock, qapp):
|
||||
widget = FooWidget()
|
||||
files_mock.return_value = [os.path.abspath('foo.bee')]
|
||||
menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
|
||||
@patch('beeref.config.BeeSettings.get_recent_files')
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
def test_create_recent_files(self, triggered_mock, files_mock):
|
||||
files_mock.return_value = [
|
||||
os.path.abspath(f'{i}.bee') for i in range(15)]
|
||||
self.menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
widget.build_menu_and_actions()
|
||||
triggered_mock.connect.reset_mock()
|
||||
assert len(widget.actions()) == 1
|
||||
qaction1 = widget.actions()[0]
|
||||
assert qaction1.text() == 'foo.bee'
|
||||
|
||||
self.widget.build_menu_and_actions()
|
||||
triggered_mock.connect.assert_called()
|
||||
assert len(self.widget.actions()) == 15
|
||||
qaction1 = self.widget.actions()[0]
|
||||
assert qaction1.text() == '0.bee'
|
||||
assert qaction1.shortcut() == 'Ctrl+1'
|
||||
assert qaction1.isEnabled() is True
|
||||
assert self.widget.bee_actions['recent_files_0'] == qaction1
|
||||
qaction10 = self.widget.actions()[9]
|
||||
assert qaction10.text() == '9.bee'
|
||||
assert qaction10.shortcut() == 'Ctrl+0'
|
||||
assert qaction10.isEnabled() is True
|
||||
assert self.widget.bee_actions['recent_files_9'] == qaction10
|
||||
qaction15 = self.widget.actions()[-1]
|
||||
assert qaction15.text() == '14.bee'
|
||||
assert qaction15.shortcut() == ''
|
||||
assert qaction15.isEnabled() is True
|
||||
assert self.widget.bee_actions['recent_files_14'] == qaction15
|
||||
files_mock.return_value = [os.path.abspath('bar.bee')]
|
||||
widget.update_menu_and_actions()
|
||||
triggered_mock.connect.assert_called()
|
||||
assert len(widget.actions()) == 1
|
||||
qaction1 = widget.actions()[0]
|
||||
assert qaction1.text() == 'bar.bee'
|
||||
|
||||
@patch('beeref.config.BeeSettings.get_recent_files')
|
||||
@patch('PyQt6.QtGui.QAction.triggered')
|
||||
def test_update_recent_files(self, triggered_mock, files_mock):
|
||||
files_mock.return_value = [os.path.abspath('foo.bee')]
|
||||
self.menu_mock.__iter__.return_value = [{
|
||||
'menu': 'Open &Recent',
|
||||
'items': '_build_recent_files',
|
||||
}]
|
||||
|
||||
self.widget.build_menu_and_actions()
|
||||
triggered_mock.connect.reset_mock()
|
||||
assert len(self.widget.actions()) == 1
|
||||
qaction1 = self.widget.actions()[0]
|
||||
assert qaction1.text() == 'foo.bee'
|
||||
|
||||
files_mock.return_value = [os.path.abspath('bar.bee')]
|
||||
self.widget.update_menu_and_actions()
|
||||
triggered_mock.connect.assert_called()
|
||||
assert len(self.widget.actions()) == 1
|
||||
qaction1 = self.widget.actions()[0]
|
||||
assert qaction1.text() == 'bar.bee'
|
||||
|
||||
def test_create_menubar(self):
|
||||
self.widget.toplevel_menus = [QtWidgets.QMenu('Foo')]
|
||||
menubar = self.widget.create_menubar()
|
||||
assert isinstance(menubar, QtWidgets.QMenuBar)
|
||||
assert len(menubar.actions()) == 1
|
||||
def test_create_menubar(qapp):
|
||||
widget = FooWidget()
|
||||
widget.toplevel_menus = [QtWidgets.QMenu('Foo')]
|
||||
menubar = widget.create_menubar()
|
||||
assert isinstance(menubar, QtWidgets.QMenuBar)
|
||||
assert len(menubar.actions()) == 1
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
import os.path
|
||||
import tempfile
|
||||
from unittest import mock, TestCase
|
||||
|
||||
from PyQt6 import QtWidgets
|
||||
|
||||
from beeref.config import BeeSettings
|
||||
|
||||
|
||||
root = os.path.dirname(__file__)
|
||||
imgfilename3x3 = os.path.join(root, 'assets', 'test3x3.png')
|
||||
with open(imgfilename3x3, 'rb') as f:
|
||||
imgdata3x3 = f.read()
|
||||
|
||||
|
||||
class BeeTestCase(TestCase):
|
||||
|
||||
imgfilename3x3 = imgfilename3x3
|
||||
imgdata3x3 = imgdata3x3
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls._settings_dir = tempfile.TemporaryDirectory()
|
||||
settings_dir_patcher = mock.patch(
|
||||
'beeref.config.BeeSettings.get_settings_dir',
|
||||
return_value=cls._settings_dir.name)
|
||||
cls._settings_dir_mock = settings_dir_patcher.start()
|
||||
inst = QtWidgets.QApplication.instance()
|
||||
cls.app = inst if inst else QtWidgets.QApplication([])
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
cls._settings_dir_mock.stop()
|
||||
cls._settings_dir.cleanup()
|
||||
|
||||
def tearDown(self):
|
||||
BeeSettings().clear()
|
||||
|
||||
def queue2list(self, queue):
|
||||
qlist = []
|
||||
while not queue.empty():
|
||||
qlist.append(queue.get())
|
||||
return qlist
|
||||
|
|
@ -1,4 +1,8 @@
|
|||
from unittest.mock import MagicMock
|
||||
import os.path
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from PyQt6 import QtGui, QtWidgets
|
||||
|
||||
|
||||
def pytest_configure(config):
|
||||
|
|
@ -10,3 +14,57 @@ def pytest_configure(config):
|
|||
# logging configuration happens on module level
|
||||
import logging.config
|
||||
logging.config.dictConfig = MagicMock
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def commandline_args():
|
||||
config_patcher = patch('beeref.view.commandline_args')
|
||||
config_mock = config_patcher.start()
|
||||
config_mock.filename = None
|
||||
yield config_mock
|
||||
config_patcher.stop()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def settings(tmpdir):
|
||||
from beeref.config import BeeSettings
|
||||
dir_patcher = patch('beeref.config.BeeSettings.get_settings_dir',
|
||||
return_value=tmpdir.dirname)
|
||||
dir_patcher.start()
|
||||
settings = BeeSettings()
|
||||
yield settings
|
||||
settings.clear()
|
||||
dir_patcher.stop()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def main_window(qtbot):
|
||||
from beeref.__main__ import BeeRefMainWindow
|
||||
app = QtWidgets.QApplication.instance()
|
||||
main = BeeRefMainWindow(app)
|
||||
qtbot.addWidget(main)
|
||||
yield main
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def view(main_window):
|
||||
yield main_window.view
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def imgfilename3x3():
|
||||
root = os.path.dirname(__file__)
|
||||
yield os.path.join(root, 'assets', 'test3x3.png')
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def imgdata3x3(imgfilename3x3):
|
||||
with open(imgfilename3x3, 'rb') as f:
|
||||
imgdata3x3 = f.read()
|
||||
yield imgdata3x3
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def item():
|
||||
from beeref.items import BeePixmapItem
|
||||
yield BeePixmapItem(QtGui.QImage())
|
||||
|
|
|
|||
|
|
@ -3,47 +3,48 @@ import httpretty
|
|||
from PyQt6 import QtCore
|
||||
|
||||
from beeref.fileio.image import load_image
|
||||
from ..base import BeeTestCase
|
||||
|
||||
|
||||
class LoadImageTestCase(BeeTestCase):
|
||||
def test_load_image_loads_from_filename(view, imgfilename3x3):
|
||||
img, filename = load_image(imgfilename3x3)
|
||||
assert img.isNull() is False
|
||||
assert filename == imgfilename3x3
|
||||
|
||||
def test_loads_from_filename(self):
|
||||
img, filename = load_image(self.imgfilename3x3)
|
||||
assert img.isNull() is False
|
||||
assert filename == self.imgfilename3x3
|
||||
|
||||
def test_loads_from_nonexisting_filename(self):
|
||||
img, filename = load_image('foo.png')
|
||||
assert img.isNull() is True
|
||||
assert filename == 'foo.png'
|
||||
def test_load_image_loads_from_nonexisting_filename(view, imgfilename3x3):
|
||||
img, filename = load_image('foo.png')
|
||||
assert img.isNull() is True
|
||||
assert filename == 'foo.png'
|
||||
|
||||
def test_loads_from_existing_local_url(self):
|
||||
url = QtCore.QUrl.fromLocalFile(self.imgfilename3x3)
|
||||
img, filename = load_image(url)
|
||||
assert img.isNull() is False
|
||||
assert filename == self.imgfilename3x3
|
||||
|
||||
@httpretty.activate
|
||||
def test_loads_from_existing_web_url(self):
|
||||
url = 'http://example.com/foo.png'
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
url,
|
||||
body=self.imgdata3x3,
|
||||
)
|
||||
img, filename = load_image(QtCore.QUrl(url))
|
||||
assert img.isNull() is False
|
||||
assert filename == url
|
||||
def test_load_image_loads_from_existing_local_url(view, imgfilename3x3):
|
||||
url = QtCore.QUrl.fromLocalFile(imgfilename3x3)
|
||||
img, filename = load_image(url)
|
||||
assert img.isNull() is False
|
||||
assert filename == imgfilename3x3
|
||||
|
||||
@httpretty.activate
|
||||
def test_loads_from_web_url_errors(self):
|
||||
url = 'http://example.com/foo.png'
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
url,
|
||||
status=500,
|
||||
)
|
||||
img, filename = load_image(QtCore.QUrl(url))
|
||||
assert img.isNull() is True
|
||||
assert filename == url
|
||||
|
||||
@httpretty.activate
|
||||
def test_load_image_loads_from_existing_web_url(view, imgdata3x3):
|
||||
url = 'http://example.com/foo.png'
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
url,
|
||||
body=imgdata3x3,
|
||||
)
|
||||
img, filename = load_image(QtCore.QUrl(url))
|
||||
assert img.isNull() is False
|
||||
assert filename == url
|
||||
|
||||
|
||||
@httpretty.activate
|
||||
def test_load_image_loads_from_web_url_errors(view, imgfilename3x3):
|
||||
url = 'http://example.com/foo.png'
|
||||
httpretty.register_uri(
|
||||
httpretty.GET,
|
||||
url,
|
||||
status=500,
|
||||
)
|
||||
img, filename = load_image(QtCore.QUrl(url))
|
||||
assert img.isNull() is True
|
||||
assert filename == url
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ from PyQt6 import QtCore
|
|||
|
||||
from beeref import fileio
|
||||
from beeref import commands
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from ..base import BeeTestCase
|
||||
from ..utils import queue2list
|
||||
|
||||
|
||||
@patch('beeref.fileio.sql.SQLiteIO.write')
|
||||
|
|
@ -26,62 +25,62 @@ def test_read_bee(read_mock):
|
|||
read_mock.assert_called_once()
|
||||
|
||||
|
||||
class LoadImagesTestCase(BeeTestCase):
|
||||
def test_load_images_loads(view, imgfilename3x3):
|
||||
view.scene.undo_stack = MagicMock()
|
||||
worker = MagicMock(canceled=False)
|
||||
fileio.load_images([imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), view.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
items = queue2list(view.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = view.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == view.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
|
||||
def setUp(self):
|
||||
self.scene = BeeGraphicsScene(MagicMock())
|
||||
|
||||
def test_loads(self):
|
||||
worker = MagicMock(canceled=False)
|
||||
fileio.load_images([self.imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), self.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
items = self.queue2list(self.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == self.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
def test_load_images_canceled(view, imgfilename3x3):
|
||||
view.scene.undo_stack = MagicMock()
|
||||
worker = MagicMock(canceled=True)
|
||||
fileio.load_images([imgfilename3x3, imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), view.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
items = queue2list(view.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = view.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == view.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
|
||||
def test_canceled(self):
|
||||
worker = MagicMock(canceled=True)
|
||||
fileio.load_images([self.imgfilename3x3, self.imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), self.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
items = self.queue2list(self.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == self.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
|
||||
def test_error(self):
|
||||
worker = MagicMock(canceled=False)
|
||||
fileio.load_images(['foo.jpg', self.imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), self.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_any_call(0)
|
||||
worker.progress.emit.assert_any_call(1)
|
||||
worker.finished.emit.assert_called_once_with('', ['foo.jpg'])
|
||||
items = self.queue2list(self.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = self.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == self.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
def test_load_images_error(view, imgfilename3x3):
|
||||
view.scene.undo_stack = MagicMock()
|
||||
worker = MagicMock(canceled=False)
|
||||
fileio.load_images(['foo.jpg', imgfilename3x3],
|
||||
QtCore.QPointF(5, 6), view.scene, worker)
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_any_call(0)
|
||||
worker.progress.emit.assert_any_call(1)
|
||||
worker.finished.emit.assert_called_once_with('', ['foo.jpg'])
|
||||
items = queue2list(view.scene.items_to_add)
|
||||
assert len(items) == 1
|
||||
item = items[0][0]
|
||||
args = view.scene.undo_stack.push.call_args_list[0][0]
|
||||
cmd = args[0]
|
||||
assert isinstance(cmd, commands.InsertItems)
|
||||
assert cmd.items == [item]
|
||||
assert cmd.scene == view.scene
|
||||
assert cmd.ignore_first_redo is True
|
||||
assert item.pos() == QtCore.QPointF(3.5, 4.5)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import os.path
|
||||
import tempfile
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from PyQt6 import QtGui
|
||||
|
|
@ -8,314 +7,314 @@ import pytest
|
|||
from beeref.fileio.errors import BeeFileIOError
|
||||
from beeref.fileio.sql import SQLiteIO
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from ..base import BeeTestCase
|
||||
|
||||
|
||||
class SQLiteIOTestCase(BeeTestCase):
|
||||
def test_sqliteio_ẁrite_meta_application_id():
|
||||
io = SQLiteIO(':memory:', MagicMock(), create_new=True)
|
||||
io.write_meta()
|
||||
result = io.fetchone('PRAGMA application_id')
|
||||
assert result[0] == SQLiteIO.APPLICATION_ID
|
||||
|
||||
def setUp(self):
|
||||
self.scene_mock = MagicMock()
|
||||
self.io = SQLiteIO(':memory:', self.scene_mock, create_new=True)
|
||||
|
||||
def test_ẁrite_meta_application_id(self):
|
||||
self.io.write_meta()
|
||||
result = self.io.fetchone('PRAGMA application_id')
|
||||
assert result[0] == SQLiteIO.APPLICATION_ID
|
||||
def test_sqliteio_ẁrite_meta_user_version():
|
||||
io = SQLiteIO(':memory:', MagicMock(), create_new=True)
|
||||
io.write_meta()
|
||||
result = io.fetchone('PRAGMA user_version')
|
||||
assert result[0] == SQLiteIO.USER_VERSION
|
||||
|
||||
def test_ẁrite_meta_user_version(self):
|
||||
self.io.write_meta()
|
||||
result = self.io.fetchone('PRAGMA user_version')
|
||||
assert result[0] == SQLiteIO.USER_VERSION
|
||||
|
||||
def test_ẁrite_meta_foreign_keys(self):
|
||||
self.io.write_meta()
|
||||
result = self.io.fetchone('PRAGMA foreign_keys')
|
||||
assert result[0] == 1
|
||||
def test_sqliteio_ẁrite_meta_foreign_keys():
|
||||
io = SQLiteIO(':memory:', MagicMock(), create_new=True)
|
||||
io.write_meta()
|
||||
result = io.fetchone('PRAGMA foreign_keys')
|
||||
assert result[0] == 1
|
||||
|
||||
def test_create_schema_on_new_when_create_new(self):
|
||||
self.io.create_schema_on_new()
|
||||
result = self.io.fetchone(
|
||||
'SELECT COUNT(*) FROM sqlite_master '
|
||||
'WHERE type="table" AND name NOT LIKE "sqlite_%"')
|
||||
assert result[0] == 2
|
||||
self.scene_mock.clear_save_ids.assert_called_once()
|
||||
|
||||
def test_create_schema_on_new_when_not_create_new(self):
|
||||
self.io.create_new = False
|
||||
self.io.create_schema_on_new()
|
||||
result = self.io.fetchone(
|
||||
'SELECT COUNT(*) FROM sqlite_master '
|
||||
'WHERE type="table" AND name NOT LIKE "sqlite_%"')
|
||||
assert result[0] == 0
|
||||
self.scene_mock.clear_save_ids.assert_not_called()
|
||||
def test_sqliteio_create_schema_on_new_when_create_new():
|
||||
scene_mock = MagicMock()
|
||||
io = SQLiteIO(':memory:', scene_mock, create_new=True)
|
||||
io.create_schema_on_new()
|
||||
result = io.fetchone(
|
||||
'SELECT COUNT(*) FROM sqlite_master '
|
||||
'WHERE type="table" AND name NOT LIKE "sqlite_%"')
|
||||
assert result[0] == 2
|
||||
scene_mock.clear_save_ids.assert_called_once()
|
||||
|
||||
def test_readonly_doesnt_allow_write(self):
|
||||
scene = BeeGraphicsScene(None)
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
io = SQLiteIO(fname, scene, readonly=True)
|
||||
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
def test_sqliteio_create_schema_on_new_when_not_create_new():
|
||||
scene_mock = MagicMock()
|
||||
io = SQLiteIO(':memory:', scene_mock, create_new=False)
|
||||
io.create_schema_on_new()
|
||||
result = io.fetchone(
|
||||
'SELECT COUNT(*) FROM sqlite_master '
|
||||
'WHERE type="table" AND name NOT LIKE "sqlite_%"')
|
||||
assert result[0] == 0
|
||||
scene_mock.clear_save_ids.assert_not_called()
|
||||
|
||||
|
||||
def test_sqliteio_readonly_doesnt_allow_write(view, tmpdir):
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
io = SQLiteIO(fname, view.scene, readonly=True)
|
||||
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
io.write()
|
||||
|
||||
assert exinfo.value.filename == fname
|
||||
with open(fname, 'r') as f:
|
||||
f.read() == 'foobar'
|
||||
|
||||
|
||||
def test_sqliteio_write_calls_create_schema_on_new(view):
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
with patch.object(io, 'create_schema_on_new') as crmock:
|
||||
with patch.object(io, 'fetchall'):
|
||||
with patch.object(io, 'exmany'):
|
||||
io.write()
|
||||
|
||||
assert exinfo.value.filename == fname
|
||||
with open(fname, 'r') as f:
|
||||
f.read() == 'foobar'
|
||||
crmock.assert_called_once()
|
||||
|
||||
|
||||
class SQLiteIOWriteTestCase(BeeTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.scene = BeeGraphicsScene(None)
|
||||
self.io = SQLiteIO(':memory:', self.scene, create_new=True)
|
||||
|
||||
def test_calls_create_schema_on_new(self):
|
||||
with patch.object(self.io, 'create_schema_on_new') as crmock:
|
||||
with patch.object(self.io, 'fetchall'):
|
||||
with patch.object(self.io, 'exmany'):
|
||||
self.io.write()
|
||||
crmock.assert_called_once()
|
||||
|
||||
def test_calls_write_meta(self):
|
||||
with patch.object(self.io, 'write_meta') as metamock:
|
||||
with patch.object(self.io, 'fetchall'):
|
||||
with patch.object(self.io, 'exmany'):
|
||||
self.io.write()
|
||||
metamock.assert_called_once()
|
||||
|
||||
def test_inserts_new_item(self):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.jpg')
|
||||
self.scene.addItem(item)
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
item.setZValue(0.22)
|
||||
item.setRotation(33)
|
||||
item.do_flip()
|
||||
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
|
||||
self.io.write()
|
||||
|
||||
assert item.save_id == 1
|
||||
result = self.io.fetchone(
|
||||
'SELECT x, y, z, scale, rotation, flip, filename, type, '
|
||||
'sqlar.data, sqlar.name '
|
||||
'FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 44.0
|
||||
assert result[1] == 55.0
|
||||
assert result[2] == 0.22
|
||||
assert result[3] == 1.3
|
||||
assert result[4] == 33
|
||||
assert result[5] == -1
|
||||
assert result[6] == 'bee.jpg'
|
||||
assert result[7] == 'pixmap'
|
||||
assert result[8] == b'abc'
|
||||
assert result[9] == '0001-bee.png'
|
||||
|
||||
def test_inserts_new_item_without_filename(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
self.io.write()
|
||||
|
||||
assert item.save_id == 1
|
||||
result = self.io.fetchone(
|
||||
'SELECT filename, sqlar.name FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] is None
|
||||
assert result[1] == '0001.png'
|
||||
|
||||
def test_updates_existing_item(self):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
self.scene.addItem(item)
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
item.setZValue(0.22)
|
||||
item.setRotation(33)
|
||||
item.save_id = 1
|
||||
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
|
||||
self.io.write()
|
||||
item.setScale(0.7)
|
||||
item.setPos(20, 30)
|
||||
item.setZValue(0.33)
|
||||
item.setRotation(100)
|
||||
item.do_flip()
|
||||
item.filename = 'new.png'
|
||||
item.pixmap_to_bytes.return_value = b'updated'
|
||||
self.io.create_new = False
|
||||
self.io.write()
|
||||
|
||||
assert self.io.fetchone('SELECT COUNT(*) from items') == (1,)
|
||||
result = self.io.fetchone(
|
||||
'SELECT x, y, z, scale, rotation, flip, filename, sqlar.data '
|
||||
'FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 20
|
||||
assert result[1] == 30
|
||||
assert result[2] == 0.33
|
||||
assert result[3] == 0.7
|
||||
assert result[4] == 100
|
||||
assert result[5] == -1
|
||||
assert result[6] == 'new.png'
|
||||
assert result[7] == b'abc'
|
||||
|
||||
def test_removes_nonexisting_item(self):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
self.scene.addItem(item)
|
||||
self.io.write()
|
||||
|
||||
self.scene.removeItem(item)
|
||||
self.io.create_new = False
|
||||
self.io.write()
|
||||
|
||||
assert self.io.fetchone('SELECT COUNT(*) from items') == (0,)
|
||||
assert self.io.fetchone('SELECT COUNT(*) from sqlar') == (0,)
|
||||
|
||||
def test_update_recovers_from_borked_file(self):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
self.scene.addItem(item)
|
||||
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
io = SQLiteIO(fname, self.scene, create_new=False)
|
||||
io.write()
|
||||
result = io.fetchone('SELECT COUNT(*) FROM items')
|
||||
assert result[0] == 1
|
||||
|
||||
def test_updates_progress(self):
|
||||
worker = MagicMock(canceled=False)
|
||||
io = SQLiteIO(':memory:', self.scene, create_new=True,
|
||||
worker=worker)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
io.write()
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
|
||||
def test_canceled(self):
|
||||
worker = MagicMock(canceled=True)
|
||||
io = SQLiteIO(':memory:', self.scene, create_new=True,
|
||||
worker=worker)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
io.write()
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
def test_sqliteio_write_calls_write_meta(view):
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
with patch.object(io, 'write_meta') as metamock:
|
||||
with patch.object(io, 'fetchall'):
|
||||
with patch.object(io, 'exmany'):
|
||||
io.write()
|
||||
metamock.assert_called_once()
|
||||
|
||||
|
||||
class SQLiteIOReadTestCase(BeeTestCase):
|
||||
def test_sqliteio_write_inserts_new_item(view):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.jpg')
|
||||
view.scene.addItem(item)
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
item.setZValue(0.22)
|
||||
item.setRotation(33)
|
||||
item.do_flip()
|
||||
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
io.write()
|
||||
|
||||
def setUp(self):
|
||||
self.scene = BeeGraphicsScene(None)
|
||||
assert item.save_id == 1
|
||||
result = io.fetchone(
|
||||
'SELECT x, y, z, scale, rotation, flip, filename, type, '
|
||||
'sqlar.data, sqlar.name '
|
||||
'FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 44.0
|
||||
assert result[1] == 55.0
|
||||
assert result[2] == 0.22
|
||||
assert result[3] == 1.3
|
||||
assert result[4] == 33
|
||||
assert result[5] == -1
|
||||
assert result[6] == 'bee.jpg'
|
||||
assert result[7] == 'pixmap'
|
||||
assert result[8] == b'abc'
|
||||
assert result[9] == '0001-bee.png'
|
||||
|
||||
def test_reads_readonly(self):
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
io = SQLiteIO(fname, self.scene, create_new=True)
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items '
|
||||
'(type, x, y, z, scale, rotation, flip, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 22.2, 33.3, 0.22, 3.4, 45, -1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)',
|
||||
(1, self.imgdata3x3))
|
||||
io.connection.commit()
|
||||
del(io)
|
||||
|
||||
io = SQLiteIO(fname, self.scene, readonly=True)
|
||||
io.read()
|
||||
item, selected = self.scene.items_to_add.get()
|
||||
assert selected is False
|
||||
assert item.save_id == 1
|
||||
assert item.pos().x() == 22.2
|
||||
assert item.pos().y() == 33.3
|
||||
assert item.zValue() == 0.22
|
||||
assert item.scale() == 3.4
|
||||
assert item.rotation() == 45
|
||||
assert item.flip() == -1
|
||||
assert item.filename == 'bee.png'
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
assert self.scene.items_to_add.empty() is True
|
||||
def test_sqliteio_write_inserts_new_item_without_filename(view, item):
|
||||
view.scene.addItem(item)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
io.write()
|
||||
|
||||
def test_updates_progress(self):
|
||||
worker = MagicMock(canceled=False)
|
||||
io = SQLiteIO(':memory:', self.scene, create_new=True,
|
||||
worker=worker)
|
||||
assert item.save_id == 1
|
||||
result = io.fetchone(
|
||||
'SELECT filename, sqlar.name FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] is None
|
||||
assert result[1] == '0001.png'
|
||||
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 0, 0, 0, 1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.connection.commit()
|
||||
|
||||
def test_sqliteio_write_updates_existing_item(view):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
view.scene.addItem(item)
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
item.setZValue(0.22)
|
||||
item.setRotation(33)
|
||||
item.save_id = 1
|
||||
item.pixmap_to_bytes = MagicMock(return_value=b'abc')
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
io.write()
|
||||
item.setScale(0.7)
|
||||
item.setPos(20, 30)
|
||||
item.setZValue(0.33)
|
||||
item.setRotation(100)
|
||||
item.do_flip()
|
||||
item.filename = 'new.png'
|
||||
item.pixmap_to_bytes.return_value = b'updated'
|
||||
io.create_new = False
|
||||
io.write()
|
||||
|
||||
assert io.fetchone('SELECT COUNT(*) from items') == (1,)
|
||||
result = io.fetchone(
|
||||
'SELECT x, y, z, scale, rotation, flip, filename, sqlar.data '
|
||||
'FROM items '
|
||||
'INNER JOIN sqlar on sqlar.item_id = items.id')
|
||||
assert result[0] == 20
|
||||
assert result[1] == 30
|
||||
assert result[2] == 0.33
|
||||
assert result[3] == 0.7
|
||||
assert result[4] == 100
|
||||
assert result[5] == -1
|
||||
assert result[6] == 'new.png'
|
||||
assert result[7] == b'abc'
|
||||
|
||||
|
||||
def test_sqliteio_write_removes_nonexisting_item(view):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
item.setScale(1.3)
|
||||
item.setPos(44, 55)
|
||||
view.scene.addItem(item)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True)
|
||||
io.write()
|
||||
|
||||
view.scene.removeItem(item)
|
||||
io.create_new = False
|
||||
io.write()
|
||||
|
||||
assert io.fetchone('SELECT COUNT(*) from items') == (0,)
|
||||
assert io.fetchone('SELECT COUNT(*) from sqlar') == (0,)
|
||||
|
||||
|
||||
def test_sqliteio_write_update_recovers_from_borked_file(view, tmpdir):
|
||||
item = BeePixmapItem(QtGui.QImage(), filename='bee.png')
|
||||
view.scene.addItem(item)
|
||||
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
io = SQLiteIO(fname, view.scene, create_new=False)
|
||||
io.write()
|
||||
result = io.fetchone('SELECT COUNT(*) FROM items')
|
||||
assert result[0] == 1
|
||||
|
||||
|
||||
def test_sqliteio_write_updates_progress(view):
|
||||
worker = MagicMock(canceled=False)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True, worker=worker)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item)
|
||||
io.write()
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
|
||||
|
||||
def test_sqliteio_write_canceled(view):
|
||||
worker = MagicMock(canceled=True)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True, worker=worker)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item)
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item)
|
||||
io.write()
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
|
||||
|
||||
def test_sqliteio_read_reads_readonly(view, tmpdir, imgdata3x3):
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
io = SQLiteIO(fname, view.scene, create_new=True)
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items '
|
||||
'(type, x, y, z, scale, rotation, flip, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 22.2, 33.3, 0.22, 3.4, 45, -1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)',
|
||||
(1, imgdata3x3))
|
||||
io.connection.commit()
|
||||
del(io)
|
||||
|
||||
io = SQLiteIO(fname, view.scene, readonly=True)
|
||||
io.read()
|
||||
item, selected = view.scene.items_to_add.get()
|
||||
assert selected is False
|
||||
assert item.save_id == 1
|
||||
assert item.pos().x() == 22.2
|
||||
assert item.pos().y() == 33.3
|
||||
assert item.zValue() == 0.22
|
||||
assert item.scale() == 3.4
|
||||
assert item.rotation() == 45
|
||||
assert item.flip() == -1
|
||||
assert item.filename == 'bee.png'
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
assert view.scene.items_to_add.empty() is True
|
||||
|
||||
|
||||
def test_sqliteio_read_updates_progress(view):
|
||||
worker = MagicMock(canceled=False)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True,
|
||||
worker=worker)
|
||||
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 0, 0, 0, 1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.connection.commit()
|
||||
io.read()
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
|
||||
|
||||
def test_sqliteio_read_canceled(view):
|
||||
worker = MagicMock(canceled=True)
|
||||
io = SQLiteIO(':memory:', view.scene, create_new=True, worker=worker)
|
||||
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 0, 0, 0, 1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 50, 50, 0, 1, 'bee2.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.connection.commit()
|
||||
io.read()
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
|
||||
|
||||
def test_sqliteio_read_raises_error_when_file_borked(view, tmpdir):
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
io = SQLiteIO(fname, view.scene, readonly=True)
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
io.read()
|
||||
worker.begin_processing.emit.assert_called_once_with(1)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with(':memory:', [])
|
||||
assert exinfo.value.filename == fname
|
||||
|
||||
def test_canceled(self):
|
||||
worker = MagicMock(canceled=True)
|
||||
io = SQLiteIO(':memory:', self.scene, create_new=True,
|
||||
worker=worker)
|
||||
|
||||
io.create_schema_on_new()
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 0, 0, 0, 1, 'bee.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.ex('INSERT INTO items (type, x, y, z, scale, filename) '
|
||||
'VALUES (?, ?, ?, ?, ?, ?) ',
|
||||
('pixmap', 50, 50, 0, 1, 'bee2.png'))
|
||||
io.ex('INSERT INTO sqlar (item_id, data) VALUES (?, ?)', (1, b''))
|
||||
io.connection.commit()
|
||||
def test_sqliteio_read_emits_error_message_when_file_borked(view, tmpdir):
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
worker = MagicMock()
|
||||
io = SQLiteIO(fname, view.scene, readonly=True, worker=worker)
|
||||
io.read()
|
||||
worker.finished.emit.assert_called_once()
|
||||
args = worker.finished.emit.call_args_list[0][0]
|
||||
assert args[0] == fname
|
||||
assert len(args[1]) == 1
|
||||
|
||||
|
||||
def test_sqliteio_read_raises_error_when_file_empty(view, tmpdir):
|
||||
fname = os.path.join(tmpdir, 'test.bee')
|
||||
io = SQLiteIO(fname, view.scene, readonly=True)
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
io.read()
|
||||
worker.begin_processing.emit.assert_called_once_with(2)
|
||||
worker.progress.emit.assert_called_once_with(0)
|
||||
worker.finished.emit.assert_called_once_with('', [])
|
||||
assert exinfo.value.filename == fname
|
||||
|
||||
def test_raises_error_when_file_borked(self):
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
io = SQLiteIO(fname, self.scene, readonly=True)
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
io.read()
|
||||
assert exinfo.value.filename == fname
|
||||
|
||||
def test_emits_error_message_when_file_borked(self):
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
with open(fname, 'w') as f:
|
||||
f.write('foobar')
|
||||
|
||||
worker = MagicMock()
|
||||
io = SQLiteIO(fname, self.scene, readonly=True, worker=worker)
|
||||
io.read()
|
||||
worker.finished.emit.assert_called_once()
|
||||
args = worker.finished.emit.call_args_list[0][0]
|
||||
assert args[0] == ''
|
||||
assert len(args[1]) == 1
|
||||
|
||||
def test_reads_raises_error_when_file_empty(self):
|
||||
with tempfile.TemporaryDirectory() as dirname:
|
||||
fname = os.path.join(dirname, 'test.bee')
|
||||
io = SQLiteIO(fname, self.scene, readonly=True)
|
||||
with pytest.raises(BeeFileIOError) as exinfo:
|
||||
io.read()
|
||||
assert exinfo.value.filename == fname
|
||||
|
||||
# should not create a file on reading!
|
||||
assert os.path.isfile(fname) is False
|
||||
# should not create a file on reading!
|
||||
assert os.path.isfile(fname) is False
|
||||
|
|
|
|||
128
tests/selection/test_base_item_mixin.py
Normal file
128
tests/selection/test_base_item_mixin.py
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
from unittest.mock import patch, MagicMock, PropertyMock
|
||||
|
||||
from PyQt6 import QtCore, QtGui
|
||||
|
||||
from beeref.items import BeePixmapItem
|
||||
|
||||
|
||||
def test_set_scale(qapp, imgfilename3x3):
|
||||
item = BeePixmapItem(QtGui.QImage(imgfilename3x3), imgfilename3x3)
|
||||
item.prepareGeometryChange = MagicMock()
|
||||
item.setScale(3)
|
||||
assert item.scale() == 3
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
item.prepareGeometryChange.assert_called_once()
|
||||
|
||||
|
||||
def test_set_scale_ignores_zero(qapp, item):
|
||||
item.setScale(0)
|
||||
assert item.scale() == 1
|
||||
|
||||
|
||||
def test_set_scale_ignores_negative(qapp, item):
|
||||
item.setScale(-0.1)
|
||||
assert item.scale() == 1
|
||||
|
||||
|
||||
def test_set_scale_with_anchor(qapp, item):
|
||||
item.setScale(2, anchor=QtCore.QPointF(100, 100))
|
||||
assert item.scale() == 2
|
||||
assert item.pos() == QtCore.QPointF(-100, -100)
|
||||
|
||||
|
||||
def test_set_zvalue_sets_new_max(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setZValue(1.1)
|
||||
assert item.zValue() == 1.1
|
||||
assert view.scene.max_z == 1.1
|
||||
|
||||
|
||||
def test_set_zvalue_keeps_old_max(view, item):
|
||||
view.scene.addItem(item)
|
||||
view.scene.max_z = 3.3
|
||||
item.setZValue(1.1)
|
||||
assert item.zValue() == 1.1
|
||||
assert view.scene.max_z == 3.3
|
||||
|
||||
|
||||
def test_bring_to_front(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setZValue(3.3)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.bring_to_front()
|
||||
assert item2.zValue() > item.zValue()
|
||||
assert item2.zValue() == view.scene.max_z
|
||||
|
||||
|
||||
def test_set_rotation_no_anchor(qapp, item):
|
||||
item.setRotation(45)
|
||||
assert item.rotation() == 45
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
|
||||
|
||||
def test_set_rotation_anchor_bottomright_cw(qapp, item):
|
||||
item.setRotation(90, QtCore.QPointF(100, 100))
|
||||
assert item.rotation() == 90
|
||||
assert item.pos().x() == 200
|
||||
assert item.pos().y() == 0
|
||||
|
||||
|
||||
def test_set_rotation_anchor_bottomright_ccw(qapp, item):
|
||||
item.setRotation(-90, QtCore.QPointF(100, 100))
|
||||
assert item.rotation() == 270
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 200
|
||||
|
||||
|
||||
def test_set_rotation_caps_above_360(qapp, item):
|
||||
item.setRotation(400)
|
||||
assert item.rotation() == 40
|
||||
|
||||
|
||||
def test_flip(qapp, item):
|
||||
assert item.flip() == 1
|
||||
|
||||
|
||||
def test_flip_when_flipped(qapp, item):
|
||||
item.do_flip()
|
||||
assert item.flip() == -1
|
||||
|
||||
|
||||
def test_do_flip_no_anchor(qapp, item):
|
||||
item.do_flip()
|
||||
assert item.flip() == -1
|
||||
item.do_flip()
|
||||
assert item.flip() == 1
|
||||
|
||||
|
||||
def test_do_flip_vertical(qapp, item):
|
||||
item.do_flip(vertical=True)
|
||||
assert item.flip() == -1
|
||||
assert item.rotation() == 180
|
||||
|
||||
|
||||
def test_do_flip_anchor(qapp, item):
|
||||
item.do_flip(anchor=QtCore.QPointF(100, 100))
|
||||
assert item.flip() == -1
|
||||
assert item.pos() == QtCore.QPointF(200, 0)
|
||||
|
||||
|
||||
def test_do_flip_vertical_anchor(qapp, item):
|
||||
item.do_flip(vertical=True, anchor=QtCore.QPointF(100, 100))
|
||||
assert item.flip() == -1
|
||||
assert item.rotation() == 180
|
||||
assert item.pos() == QtCore.QPointF(0, 200)
|
||||
|
||||
|
||||
def test_base_item_mixin_center_scene_coords(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setPos(5, 5)
|
||||
item.setScale(2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
assert item.center_scene_coords == QtCore.QPointF(105, 85)
|
||||
99
tests/selection/test_multi_select_item.py
Normal file
99
tests/selection/test_multi_select_item.py
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
from unittest.mock import patch, MagicMock
|
||||
|
||||
from PyQt6 import QtCore, QtGui
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.selection import MultiSelectItem
|
||||
|
||||
|
||||
@patch('beeref.selection.SelectableMixin.init_selectable')
|
||||
def test_init(selectable_mock):
|
||||
item = MultiSelectItem()
|
||||
assert hasattr(item, 'save_id') is False
|
||||
selectable_mock.assert_called_once()
|
||||
|
||||
|
||||
def test_width():
|
||||
item = MultiSelectItem()
|
||||
item.setRect(0, 0, 50, 100)
|
||||
assert item.width == 50
|
||||
|
||||
|
||||
def test_height():
|
||||
item = MultiSelectItem()
|
||||
item.setRect(0, 0, 50, 100)
|
||||
assert item.height == 100
|
||||
|
||||
|
||||
def test_paint():
|
||||
item = MultiSelectItem()
|
||||
item.paint_selectable = MagicMock()
|
||||
painter = MagicMock()
|
||||
item.paint(painter, None, None)
|
||||
item.paint_selectable.assert_called_once()
|
||||
painter.drawRect.assert_not_called()
|
||||
|
||||
|
||||
def test_has_selection_outline():
|
||||
item = MultiSelectItem()
|
||||
item.has_selection_outline() is True
|
||||
|
||||
|
||||
def test_has_selection_handles():
|
||||
item = MultiSelectItem()
|
||||
item.has_selection_handles() is True
|
||||
|
||||
|
||||
def test_selection_action_items(view):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item1)
|
||||
item1.setSelected(True)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.setSelected(True)
|
||||
item3 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item3)
|
||||
item3.setSelected(False)
|
||||
action_items = set(view.scene.multi_select_item.selection_action_items())
|
||||
assert action_items == {item1, item2, view.scene.multi_select_item}
|
||||
|
||||
|
||||
def test_fit_selection_area():
|
||||
item = MultiSelectItem()
|
||||
item.setScale(5)
|
||||
item.setRotation(-20)
|
||||
item.do_flip()
|
||||
item.fit_selection_area(QtCore.QRectF(-10, -20, 100, 80))
|
||||
assert item.pos().x() == -10
|
||||
assert item.pos().y() == -20
|
||||
assert item.width == 100
|
||||
assert item.height == 80
|
||||
assert item.scale() == 1
|
||||
assert item.rotation() == 0
|
||||
assert item.flip() == 1
|
||||
assert item.isSelected() is True
|
||||
|
||||
|
||||
@patch('PyQt6.QtWidgets.QGraphicsRectItem.mousePressEvent')
|
||||
def test_mouse_press_event_when_ctrl_leftclick(mouse_mock):
|
||||
item = MultiSelectItem()
|
||||
item.fit_selection_area(QtCore.QRectF(0, 0, 100, 80))
|
||||
event = MagicMock(
|
||||
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
||||
modifiers=MagicMock(
|
||||
return_value=Qt.KeyboardModifier.ControlModifier))
|
||||
item.mousePressEvent(event)
|
||||
event.ignore.assert_called_once()
|
||||
mouse_mock.assert_not_called()
|
||||
|
||||
|
||||
@patch('beeref.selection.SelectableMixin.mousePressEvent')
|
||||
def test_mouse_press_event_when_leftclick(mouse_mock):
|
||||
item = MultiSelectItem()
|
||||
item.fit_selection_area(QtCore.QRectF(0, 0, 100, 80))
|
||||
event = MagicMock(
|
||||
button=MagicMock(return_value=Qt.MouseButton.LeftButton))
|
||||
item.mousePressEvent(event)
|
||||
event.ignore.assert_not_called()
|
||||
mouse_mock.assert_called_once_with(event)
|
||||
33
tests/selection/test_rubberband_item.py
Normal file
33
tests/selection/test_rubberband_item.py
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
from PyQt6 import QtCore
|
||||
|
||||
from beeref.selection import RubberbandItem
|
||||
|
||||
|
||||
def test_width():
|
||||
item = RubberbandItem()
|
||||
item.setRect(5, 5, 100, 80)
|
||||
assert item.width == 100
|
||||
|
||||
|
||||
def test_height():
|
||||
item = RubberbandItem()
|
||||
item.setRect(5, 5, 100, 80)
|
||||
assert item.height == 80
|
||||
|
||||
|
||||
def test_fit_topleft_to_bottomright():
|
||||
item = RubberbandItem()
|
||||
item.fit(QtCore.QPointF(-10, -20), QtCore.QPointF(30, 40))
|
||||
assert item.rect().topLeft().x() == -10
|
||||
assert item.rect().topLeft().y() == -20
|
||||
assert item.rect().bottomRight().x() == 30
|
||||
assert item.rect().bottomRight().y() == 40
|
||||
|
||||
|
||||
def test_fit_topright_to_bottomleft():
|
||||
item = RubberbandItem()
|
||||
item.fit(QtCore.QPointF(50, -20), QtCore.QPointF(-30, 40))
|
||||
assert item.rect().topLeft().x() == -30
|
||||
assert item.rect().topLeft().y() == -20
|
||||
assert item.rect().bottomRight().x() == 50
|
||||
assert item.rect().bottomRight().y() == 40
|
||||
1062
tests/selection/test_selectable_mixin.py
Normal file
1062
tests/selection/test_selectable_mixin.py
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1,14 +1,12 @@
|
|||
from PyQt6 import QtGui
|
||||
|
||||
from beeref.assets import BeeAssets
|
||||
from .base import BeeTestCase
|
||||
|
||||
|
||||
class GetRectFromPointsTestCase(BeeTestCase):
|
||||
def test_singleton(view):
|
||||
assert BeeAssets() is BeeAssets()
|
||||
assert BeeAssets().logo is BeeAssets().logo
|
||||
|
||||
def test_singleton(self):
|
||||
assert BeeAssets() is BeeAssets()
|
||||
assert BeeAssets().logo is BeeAssets().logo
|
||||
|
||||
def test_has_logo(self):
|
||||
assert isinstance(BeeAssets().logo, QtGui.QIcon)
|
||||
def test_has_logo(view):
|
||||
assert isinstance(BeeAssets().logo, QtGui.QIcon)
|
||||
|
|
|
|||
|
|
@ -4,453 +4,417 @@ from PyQt6 import QtCore, QtGui
|
|||
|
||||
from beeref import commands
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from .base import BeeTestCase
|
||||
|
||||
|
||||
class InsertItemsTestCase(BeeTestCase):
|
||||
|
||||
@patch('beeref.scene.BeeGraphicsScene.views')
|
||||
def test_redo_undo(self, views_mock):
|
||||
scene = BeeGraphicsScene(None)
|
||||
view = MagicMock(get_scale=MagicMock(return_value=1))
|
||||
views_mock.return_value = [view]
|
||||
scene.update_selection = MagicMock()
|
||||
scene.max_z = 5
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(50, 40)
|
||||
command = commands.InsertItems(scene, [item2])
|
||||
command.redo()
|
||||
assert list(scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
item2.zValue() > 5
|
||||
command.undo()
|
||||
assert list(scene.items_for_save()) == [item1]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
|
||||
@patch('beeref.scene.BeeGraphicsScene.views')
|
||||
def test_redo_undo_with_position(self, views_mock):
|
||||
scene = BeeGraphicsScene(None)
|
||||
view = MagicMock(get_scale=MagicMock(return_value=1))
|
||||
views_mock.return_value = [view]
|
||||
scene.update_selection = MagicMock()
|
||||
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(10, 20)
|
||||
scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(50, 40)
|
||||
scene.addItem(item2)
|
||||
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.InsertItems(
|
||||
scene, [item1, item2], QtCore.QPointF(100, 200))
|
||||
command.redo()
|
||||
assert set(scene.items_for_save()) == {item1, item2}
|
||||
assert item1.pos() == QtCore.QPointF(30, 150)
|
||||
assert item2.pos() == QtCore.QPointF(70, 170)
|
||||
command.undo()
|
||||
assert list(scene.items_for_save()) == []
|
||||
assert item1.pos() == QtCore.QPointF(10, 20)
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
|
||||
@patch('beeref.scene.BeeGraphicsScene.views')
|
||||
def test_ignore_first_redo(self, views_mock):
|
||||
scene = BeeGraphicsScene(None)
|
||||
view = MagicMock(get_scale=MagicMock(return_value=1))
|
||||
views_mock.return_value = [view]
|
||||
scene.update_selection = MagicMock()
|
||||
scene.max_z = 5
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
command = commands.InsertItems(scene, [item2], ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert list(scene.items_for_save()) == [item1]
|
||||
assert item1.isSelected() is False
|
||||
command.redo()
|
||||
assert list(scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
item2.zValue() > 5
|
||||
def test_insert_items(view):
|
||||
view.scene.update_selection = MagicMock()
|
||||
view.scene.max_z = 5
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(50, 40)
|
||||
command = commands.InsertItems(view.scene, [item2])
|
||||
command.redo()
|
||||
assert list(view.scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
item2.zValue() > 5
|
||||
command.undo()
|
||||
assert list(view.scene.items_for_save()) == [item1]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
|
||||
|
||||
class DeleteItemsTestCase(BeeTestCase):
|
||||
def test_insert_items_with_position(view):
|
||||
view.scene.update_selection = MagicMock()
|
||||
|
||||
def test_redo_undo(self):
|
||||
scene = BeeGraphicsScene(None)
|
||||
scene.update_selection = MagicMock()
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
scene.addItem(item2)
|
||||
item2.setSelected(True)
|
||||
command = commands.DeleteItems(scene, [item2])
|
||||
command.redo()
|
||||
assert list(scene.items_for_save()) == [item1]
|
||||
command.undo()
|
||||
assert list(scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(10, 20)
|
||||
view.scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(50, 40)
|
||||
view.scene.addItem(item2)
|
||||
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.InsertItems(
|
||||
view.scene, [item1, item2], QtCore.QPointF(100, 200))
|
||||
command.redo()
|
||||
assert set(view.scene.items_for_save()) == {item1, item2}
|
||||
assert item1.pos() == QtCore.QPointF(30, 150)
|
||||
assert item2.pos() == QtCore.QPointF(70, 170)
|
||||
command.undo()
|
||||
assert list(view.scene.items_for_save()) == []
|
||||
assert item1.pos() == QtCore.QPointF(10, 20)
|
||||
assert item2.pos() == QtCore.QPointF(50, 40)
|
||||
|
||||
|
||||
class MoveItemsByTestCase(BeeTestCase):
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(0, 0)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(30, 40)
|
||||
command = commands.MoveItemsBy([item1, item2], QtCore.QPointF(50, 100))
|
||||
command.redo()
|
||||
assert item1.pos().x() == 50
|
||||
assert item1.pos().y() == 100
|
||||
assert item2.pos().x() == 80
|
||||
assert item2.pos().y() == 140
|
||||
|
||||
command.undo()
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.pos().x() == 30
|
||||
assert item2.pos().y() == 40
|
||||
|
||||
def test_ignore_first_redo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(0, 0)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(30, 40)
|
||||
command = commands.MoveItemsBy([item1, item2],
|
||||
QtCore.QPointF(50, 100),
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.pos().x() == 30
|
||||
assert item2.pos().y() == 40
|
||||
command.redo()
|
||||
assert item1.pos().x() == 50
|
||||
assert item1.pos().y() == 100
|
||||
assert item2.pos().x() == 80
|
||||
assert item2.pos().y() == 140
|
||||
def test_insert_items_ignore_first_redo(view):
|
||||
view.scene.update_selection = MagicMock()
|
||||
view.scene.max_z = 5
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
command = commands.InsertItems(view.scene, [item2], ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert list(view.scene.items_for_save()) == [item1]
|
||||
assert item1.isSelected() is False
|
||||
command.redo()
|
||||
assert list(view.scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
item2.zValue() > 5
|
||||
|
||||
|
||||
class ScaleItemsByTestCase(BeeTestCase):
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
item2.setPos(100, 100)
|
||||
command = commands.ScaleItemsBy([item1, item2], 2,
|
||||
QtCore.QPointF(100, 100))
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == -100
|
||||
assert item2.scale() == 6
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.undo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
def test_ignore_first_redo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
item2.setPos(100, 100)
|
||||
command = commands.ScaleItemsBy([item1, item2], 2,
|
||||
QtCore.QPointF(100, 100),
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == -100
|
||||
assert item2.scale() == 6
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
def test_delete_items(view):
|
||||
view.scene.update_selection = MagicMock()
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.setSelected(True)
|
||||
command = commands.DeleteItems(view.scene, [item2])
|
||||
command.redo()
|
||||
assert list(view.scene.items_for_save()) == [item1]
|
||||
command.undo()
|
||||
assert list(view.scene.items_for_save()) == [item1, item2]
|
||||
assert item1.isSelected() is False
|
||||
assert item2.isSelected() is True
|
||||
|
||||
|
||||
class RotateItemsByTestCase(BeeTestCase):
|
||||
def test_move_items_by(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(0, 0)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(30, 40)
|
||||
command = commands.MoveItemsBy([item1, item2], QtCore.QPointF(50, 100))
|
||||
command.redo()
|
||||
assert item1.pos().x() == 50
|
||||
assert item1.pos().y() == 100
|
||||
assert item2.pos().x() == 80
|
||||
assert item2.pos().y() == 140
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.RotateItemsBy([item1, item2], -90,
|
||||
QtCore.QPointF(100, 100))
|
||||
command.redo()
|
||||
assert item1.rotation() == 270
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 200
|
||||
assert item2.rotation() == 120
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.undo()
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
def test_ignore_first_redo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.RotateItemsBy([item1, item2], -90,
|
||||
QtCore.QPointF(100, 100),
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.redo()
|
||||
assert item1.rotation() == 270
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 200
|
||||
assert item2.rotation() == 120
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.undo()
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.pos().x() == 30
|
||||
assert item2.pos().y() == 40
|
||||
|
||||
|
||||
class NormalizeItemsTestCase(BeeTestCase):
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.NormalizeItems([item1, item2], [2, 0.5])
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos() == QtCore.QPointF(-50, -40)
|
||||
assert item2.scale() == 1.5
|
||||
assert item2.pos() == QtCore.QPointF(75, 60)
|
||||
command.undo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos() == QtCore.QPointF(0, 0)
|
||||
def test_move_items_by_ignore_first_redo(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setPos(0, 0)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setPos(30, 40)
|
||||
command = commands.MoveItemsBy([item1, item2],
|
||||
QtCore.QPointF(50, 100),
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.pos().x() == 30
|
||||
assert item2.pos().y() == 40
|
||||
command.redo()
|
||||
assert item1.pos().x() == 50
|
||||
assert item1.pos().y() == 100
|
||||
assert item2.pos().x() == 80
|
||||
assert item2.pos().y() == 140
|
||||
|
||||
|
||||
class FlipItemsTestCase(BeeTestCase):
|
||||
def test_scale_items_by(view):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
item2.setPos(100, 100)
|
||||
command = commands.ScaleItemsBy([item1, item2], 2,
|
||||
QtCore.QPointF(100, 100))
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == -100
|
||||
assert item2.scale() == 6
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.undo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
def test_redo_undo_horizontal(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.FlipItems([item1, item2],
|
||||
def test_scale_items_by_ignore_first_redo(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
item2.setPos(100, 100)
|
||||
command = commands.ScaleItemsBy([item1, item2], 2,
|
||||
QtCore.QPointF(100, 100),
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == -100
|
||||
assert item2.scale() == 6
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
|
||||
def test_rotate_items_by(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.RotateItemsBy([item1, item2], -90,
|
||||
QtCore.QPointF(100, 100))
|
||||
command.redo()
|
||||
assert item1.rotation() == 270
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 200
|
||||
assert item2.rotation() == 120
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.undo()
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
|
||||
def test_rotate_items_by_ignore_first_redo(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.RotateItemsBy([item1, item2], -90,
|
||||
QtCore.QPointF(100, 100),
|
||||
vertical=False)
|
||||
command.redo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(200, 0)
|
||||
assert item2.flip() == 1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
command.undo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.flip() == -1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
|
||||
def test_redo_undo_vertical(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.FlipItems([item1, item2],
|
||||
QtCore.QPointF(100, 100),
|
||||
vertical=True)
|
||||
command.redo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.rotation() == 180
|
||||
assert item1.pos() == QtCore.QPointF(0, 200)
|
||||
assert item2.flip() == 1
|
||||
assert item2.rotation() == 210
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
command.undo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.flip() == -1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
ignore_first_redo=True)
|
||||
command.redo()
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
command.redo()
|
||||
assert item1.rotation() == 270
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 200
|
||||
assert item2.rotation() == 120
|
||||
assert item2.pos().x() == 100
|
||||
assert item2.pos().y() == 100
|
||||
|
||||
|
||||
class ResetScaleTestCase(BeeTestCase):
|
||||
|
||||
def test_redo_undo(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
item.setScale(2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetScale([item])
|
||||
command.redo()
|
||||
assert item.scale() == 1
|
||||
assert item.pos().x() == 50
|
||||
assert item.pos().y() == 40
|
||||
command.undo()
|
||||
assert item.scale() == 2
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
def test_normalize_items(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setScale(3)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.NormalizeItems([item1, item2], [2, 0.5])
|
||||
command.redo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.pos() == QtCore.QPointF(-50, -40)
|
||||
assert item2.scale() == 1.5
|
||||
assert item2.pos() == QtCore.QPointF(75, 60)
|
||||
command.undo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.scale() == 3
|
||||
assert item2.pos() == QtCore.QPointF(0, 0)
|
||||
|
||||
|
||||
class ResetRotateTestCase(BeeTestCase):
|
||||
def test_flip_items_horizontal(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
def test_redo_undo(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
item.setRotation(180)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetRotation([item])
|
||||
command.redo()
|
||||
assert item.rotation() == 0
|
||||
assert item.pos().x() == -100
|
||||
assert item.pos().y() == -80
|
||||
command.undo()
|
||||
assert item.rotation() == 180
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.FlipItems([item1, item2],
|
||||
QtCore.QPointF(100, 100),
|
||||
vertical=False)
|
||||
command.redo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(200, 0)
|
||||
assert item2.flip() == 1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
command.undo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.flip() == -1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
|
||||
|
||||
class ResetFlipTestCase(BeeTestCase):
|
||||
def test_flip_items_vertical(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setRotation(0)
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.do_flip()
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetFlip([item1, item2])
|
||||
command.redo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
command.undo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(30)
|
||||
item2.setPos(100, 100)
|
||||
item2.do_flip()
|
||||
command = commands.FlipItems([item1, item2],
|
||||
QtCore.QPointF(100, 100),
|
||||
vertical=True)
|
||||
command.redo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.rotation() == 180
|
||||
assert item1.pos() == QtCore.QPointF(0, 200)
|
||||
assert item2.flip() == 1
|
||||
assert item2.rotation() == 210
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
command.undo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.flip() == -1
|
||||
assert item2.rotation() == 30
|
||||
assert item2.pos() == QtCore.QPointF(100, 100)
|
||||
|
||||
|
||||
class ResetTransformsTestCase(BeeTestCase):
|
||||
|
||||
def test_redo_undo(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(2)
|
||||
item1.do_flip()
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(180)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetTransforms([item1, item2])
|
||||
command.redo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.flip() == 1
|
||||
assert item1.pos().x() == -150
|
||||
assert item1.pos().y() == 40
|
||||
assert item2.scale() == 1
|
||||
assert item2.rotation() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == -100
|
||||
assert item2.pos().y() == -80
|
||||
command.undo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.rotation() == 0
|
||||
assert item1.flip() == -1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 1
|
||||
assert item2.rotation() == 180
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
def test_reset_scale(view, item):
|
||||
item.setScale(2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetScale([item])
|
||||
command.redo()
|
||||
assert item.scale() == 1
|
||||
assert item.pos().x() == 50
|
||||
assert item.pos().y() == 40
|
||||
command.undo()
|
||||
assert item.scale() == 2
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
|
||||
|
||||
class ArrangeItemsTestCase(BeeTestCase):
|
||||
def test_reset_rotate(view, item):
|
||||
item.setRotation(180)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetRotation([item])
|
||||
command.redo()
|
||||
assert item.rotation() == 0
|
||||
assert item.pos().x() == -100
|
||||
assert item.pos().y() == -80
|
||||
command.undo()
|
||||
assert item.rotation() == 180
|
||||
assert item.pos().x() == 0
|
||||
assert item.pos().y() == 0
|
||||
|
||||
def test_redo_undo(self):
|
||||
scene = BeeGraphicsScene(None)
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.do_flip()
|
||||
scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(90)
|
||||
scene.addItem(item2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ArrangeItems(
|
||||
scene,
|
||||
[item1, item2],
|
||||
[QtCore.QPointF(1, 2), QtCore.QPointF(203, 204)])
|
||||
|
||||
command.redo()
|
||||
assert item1.pos() == QtCore.QPointF(101, 2)
|
||||
assert item2.pos() == QtCore.QPointF(283, 204)
|
||||
command.undo()
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.pos() == QtCore.QPointF(0, 0)
|
||||
def test_reset_flip(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.do_flip()
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetFlip([item1, item2])
|
||||
command.redo()
|
||||
assert item1.flip() == 1
|
||||
assert item1.pos().x() == -100
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
command.undo()
|
||||
assert item1.flip() == -1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
|
||||
|
||||
def test_reset_transforms(qapp):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.setScale(2)
|
||||
item1.do_flip()
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(180)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ResetTransforms([item1, item2])
|
||||
command.redo()
|
||||
assert item1.scale() == 1
|
||||
assert item1.rotation() == 0
|
||||
assert item1.flip() == 1
|
||||
assert item1.pos().x() == -150
|
||||
assert item1.pos().y() == 40
|
||||
assert item2.scale() == 1
|
||||
assert item2.rotation() == 0
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == -100
|
||||
assert item2.pos().y() == -80
|
||||
command.undo()
|
||||
assert item1.scale() == 2
|
||||
assert item1.rotation() == 0
|
||||
assert item1.flip() == -1
|
||||
assert item1.pos().x() == 0
|
||||
assert item1.pos().y() == 0
|
||||
assert item2.scale() == 1
|
||||
assert item2.rotation() == 180
|
||||
assert item2.flip() == 1
|
||||
assert item2.pos().x() == 0
|
||||
assert item2.pos().y() == 0
|
||||
|
||||
|
||||
def test_arrange_items(view):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
item1.do_flip()
|
||||
view.scene.addItem(item1)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
item2.setRotation(90)
|
||||
view.scene.addItem(item2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=80):
|
||||
command = commands.ArrangeItems(
|
||||
view.scene,
|
||||
[item1, item2],
|
||||
[QtCore.QPointF(1, 2), QtCore.QPointF(203, 204)])
|
||||
|
||||
command.redo()
|
||||
assert item1.pos() == QtCore.QPointF(101, 2)
|
||||
assert item2.pos() == QtCore.QPointF(283, 204)
|
||||
command.undo()
|
||||
assert item1.pos() == QtCore.QPointF(0, 0)
|
||||
assert item2.pos() == QtCore.QPointF(0, 0)
|
||||
|
|
|
|||
|
|
@ -4,67 +4,70 @@ from unittest.mock import patch
|
|||
|
||||
import pytest
|
||||
|
||||
from beeref.config import CommandlineArgs, BeeSettings
|
||||
from .base import BeeTestCase
|
||||
from beeref.config import CommandlineArgs
|
||||
|
||||
|
||||
class CommandlineArgsTestCase(BeeTestCase):
|
||||
|
||||
def test_singleton(self):
|
||||
assert CommandlineArgs() is CommandlineArgs()
|
||||
assert CommandlineArgs()._args is CommandlineArgs()._args
|
||||
|
||||
@patch('beeref.config.parser.parse_args')
|
||||
def test_with_check_forces_new_parsing(self, parse_mock):
|
||||
args1 = CommandlineArgs()
|
||||
args2 = CommandlineArgs(with_check=True)
|
||||
parse_mock.assert_called_once()
|
||||
assert args1 is not args2
|
||||
|
||||
def test_get(self):
|
||||
args = CommandlineArgs()
|
||||
assert args.loglevel == 'INFO'
|
||||
|
||||
def test_get_unknown(self):
|
||||
args = CommandlineArgs()
|
||||
with pytest.raises(AttributeError):
|
||||
args.foo
|
||||
def test_command_line_args_singleton():
|
||||
assert CommandlineArgs() is CommandlineArgs()
|
||||
assert CommandlineArgs()._args is CommandlineArgs()._args
|
||||
CommandlineArgs._instance = None
|
||||
|
||||
|
||||
class BeeSettingsRecentFilesTestCase(BeeTestCase):
|
||||
@patch('beeref.config.parser.parse_args')
|
||||
def test_command_line_args_with_check_forces_new_parsing(parse_mock):
|
||||
args1 = CommandlineArgs()
|
||||
args2 = CommandlineArgs(with_check=True)
|
||||
parse_mock.assert_called_once()
|
||||
assert args1 is not args2
|
||||
CommandlineArgs._instance = None
|
||||
|
||||
def setUp(self):
|
||||
self.settings = BeeSettings()
|
||||
|
||||
def test_get_empty(self):
|
||||
self.settings.get_recent_files() == []
|
||||
def test_command_line_args_get():
|
||||
args = CommandlineArgs()
|
||||
assert args.loglevel == 'INFO'
|
||||
CommandlineArgs._instance = None
|
||||
|
||||
def test_get_existing_only(self):
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
self.settings.update_recent_files('foo.bee')
|
||||
self.settings.update_recent_files(f.name)
|
||||
self.settings.get_recent_files(existing_only=True) == [f.name]
|
||||
|
||||
def test_update(self):
|
||||
self.settings.update_recent_files('foo.bee')
|
||||
self.settings.update_recent_files('bar.bee')
|
||||
assert self.settings.get_recent_files() == [
|
||||
os.path.abspath('bar.bee'),
|
||||
os.path.abspath('foo.bee')]
|
||||
def test_command_line_args_get_unknown():
|
||||
args = CommandlineArgs()
|
||||
with pytest.raises(AttributeError):
|
||||
args.foo
|
||||
CommandlineArgs._instance = None
|
||||
|
||||
def test_update_existing(self):
|
||||
self.settings.update_recent_files('foo.bee')
|
||||
self.settings.update_recent_files('bar.bee')
|
||||
self.settings.update_recent_files('foo.bee')
|
||||
assert self.settings.get_recent_files() == [
|
||||
os.path.abspath('foo.bee'),
|
||||
os.path.abspath('bar.bee')]
|
||||
|
||||
def test_update_respects_max_num(self):
|
||||
for i in range(15):
|
||||
self.settings.update_recent_files(f'{i}.bee')
|
||||
def test_settings_recent_files_get_empty(settings):
|
||||
settings.get_recent_files() == []
|
||||
|
||||
recent = self.settings.get_recent_files()
|
||||
assert len(recent) == 10
|
||||
assert recent[0] == os.path.abspath('14.bee')
|
||||
assert recent[-1] == os.path.abspath('5.bee')
|
||||
|
||||
def test_settings_recent_files_get_existing_only(settings):
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
settings.update_recent_files('foo.bee')
|
||||
settings.update_recent_files(f.name)
|
||||
settings.get_recent_files(existing_only=True) == [f.name]
|
||||
|
||||
|
||||
def test_settings_recent_files_update(settings):
|
||||
settings.update_recent_files('foo.bee')
|
||||
settings.update_recent_files('bar.bee')
|
||||
assert settings.get_recent_files() == [
|
||||
os.path.abspath('bar.bee'),
|
||||
os.path.abspath('foo.bee')]
|
||||
|
||||
|
||||
def test_settings_recent_files_update_existing(settings):
|
||||
settings.update_recent_files('foo.bee')
|
||||
settings.update_recent_files('bar.bee')
|
||||
settings.update_recent_files('foo.bee')
|
||||
assert settings.get_recent_files() == [
|
||||
os.path.abspath('foo.bee'),
|
||||
os.path.abspath('bar.bee')]
|
||||
|
||||
|
||||
def test_settings_recent_files_update_respects_max_num(settings):
|
||||
for i in range(15):
|
||||
settings.update_recent_files(f'{i}.bee')
|
||||
|
||||
recent = settings.get_recent_files()
|
||||
assert len(recent) == 10
|
||||
assert recent[0] == os.path.abspath('14.bee')
|
||||
assert recent[-1] == os.path.abspath('5.bee')
|
||||
|
|
|
|||
18
tests/test_gui.py
Normal file
18
tests/test_gui.py
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
from PyQt6 import QtWidgets
|
||||
from PyQt6.QtCore import Qt
|
||||
|
||||
from beeref.config import logfile_name
|
||||
from beeref.gui import DebugLogDialog
|
||||
|
||||
|
||||
def test_debug_log_dialog(qtbot, settings, view):
|
||||
with open(logfile_name(), 'w') as f:
|
||||
f.write('my log output')
|
||||
|
||||
dialog = DebugLogDialog(view)
|
||||
dialog.show()
|
||||
qtbot.addWidget(dialog)
|
||||
assert dialog.log.text() == 'my log output'
|
||||
qtbot.mouseClick(dialog.copy_button, Qt.MouseButton.LeftButton)
|
||||
clipboard = QtWidgets.QApplication.clipboard()
|
||||
assert clipboard.text() == 'my log output'
|
||||
|
|
@ -3,138 +3,130 @@ from unittest.mock import patch, MagicMock, PropertyMock
|
|||
from PyQt6 import QtCore, QtGui
|
||||
|
||||
from beeref.items import BeePixmapItem
|
||||
from beeref.scene import BeeGraphicsScene
|
||||
from .base import BeeTestCase
|
||||
|
||||
|
||||
class BeePixmapItemTestCase(BeeTestCase):
|
||||
@patch('beeref.selection.SelectableMixin.init_selectable')
|
||||
def test_init(selectable_mock, qapp, imgfilename3x3):
|
||||
item = BeePixmapItem(QtGui.QImage(imgfilename3x3), imgfilename3x3)
|
||||
assert item.save_id is None
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
assert item.scale() == 1
|
||||
assert item.filename == imgfilename3x3
|
||||
selectable_mock.assert_called_once()
|
||||
|
||||
def setUp(self):
|
||||
self.scene = BeeGraphicsScene(None)
|
||||
|
||||
@patch('beeref.selection.SelectableMixin.init_selectable')
|
||||
def test_init(self, selectable_mock):
|
||||
item = BeePixmapItem(
|
||||
QtGui.QImage(self.imgfilename3x3), self.imgfilename3x3)
|
||||
assert item.save_id is None
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
assert item.scale() == 1
|
||||
assert item.filename == self.imgfilename3x3
|
||||
selectable_mock.assert_called_once()
|
||||
def test_set_pos_center(qapp, item):
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == -100
|
||||
assert item.pos().y() == -50
|
||||
|
||||
def test_set_pos_center(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == -100
|
||||
assert item.pos().y() == -50
|
||||
|
||||
def test_set_pos_center_when_scaled(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
item.setScale(2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == -200
|
||||
assert item.pos().y() == -100
|
||||
def test_set_pos_center_when_scaled(qapp, item):
|
||||
item.setScale(2)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == -200
|
||||
assert item.pos().y() == -100
|
||||
|
||||
def test_set_pos_center_when_rotated(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
item.setRotation(90)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == 50
|
||||
assert item.pos().y() == -100
|
||||
|
||||
def test_pixmap_to_bytes(self):
|
||||
item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3))
|
||||
assert item.pixmap_to_bytes().startswith(b'\x89PNG')
|
||||
def test_set_pos_center_when_rotated(qapp, item):
|
||||
item.setRotation(90)
|
||||
with patch('beeref.items.BeePixmapItem.width',
|
||||
new_callable=PropertyMock, return_value=200):
|
||||
with patch('beeref.items.BeePixmapItem.height',
|
||||
new_callable=PropertyMock, return_value=100):
|
||||
item.set_pos_center(QtCore.QPointF(0, 0))
|
||||
assert item.pos().x() == 50
|
||||
assert item.pos().y() == -100
|
||||
|
||||
def test_pixmap_from_bytes(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
with open(self.imgfilename3x3, 'rb') as f:
|
||||
imgdata = f.read()
|
||||
item.pixmap_from_bytes(imgdata)
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
|
||||
def test_paint(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
item.pixmap = MagicMock(return_value='bee')
|
||||
item.paint_selectable = MagicMock()
|
||||
painter = MagicMock()
|
||||
item.paint(painter, None, None)
|
||||
item.paint_selectable.assert_called_once()
|
||||
painter.drawPixmap.assert_called_with(0, 0, 'bee')
|
||||
def test_pixmap_to_bytes(qapp, imgfilename3x3):
|
||||
item = BeePixmapItem(QtGui.QImage(imgfilename3x3))
|
||||
assert item.pixmap_to_bytes().startswith(b'\x89PNG')
|
||||
|
||||
def test_has_selection_outline_when_not_selected(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
item.setSelected(False)
|
||||
item.has_selection_outline() is False
|
||||
|
||||
def test_has_selection_outline_when_selected(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item)
|
||||
item.setSelected(True)
|
||||
item.has_selection_outline() is True
|
||||
def test_pixmap_from_bytes(qapp, item, imgfilename3x3):
|
||||
with open(imgfilename3x3, 'rb') as f:
|
||||
imgdata = f.read()
|
||||
item.pixmap_from_bytes(imgdata)
|
||||
assert item.width == 3
|
||||
assert item.height == 3
|
||||
|
||||
def test_has_selection_handles_when_not_selected(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item1)
|
||||
item1.setSelected(False)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item2)
|
||||
item2.setSelected(False)
|
||||
item1.has_selection_handles() is False
|
||||
|
||||
def test_has_selection_handles_when_selected_single(self):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item1)
|
||||
item1.setSelected(True)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item2)
|
||||
item2.setSelected(False)
|
||||
item1.has_selection_handles() is True
|
||||
def test_paint(qapp, item):
|
||||
item.pixmap = MagicMock(return_value='bee')
|
||||
item.paint_selectable = MagicMock()
|
||||
painter = MagicMock()
|
||||
item.paint(painter, None, None)
|
||||
item.paint_selectable.assert_called_once()
|
||||
painter.drawPixmap.assert_called_with(0, 0, 'bee')
|
||||
|
||||
def test_has_selection_handles_when_selected_multi(self):
|
||||
view = MagicMock(get_scale=MagicMock(return_value=1))
|
||||
with patch('beeref.scene.BeeGraphicsScene.views',
|
||||
return_value=[view]):
|
||||
item1 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item1)
|
||||
item1.setSelected(True)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
self.scene.addItem(item2)
|
||||
item2.setSelected(True)
|
||||
item1.has_selection_handles() is False
|
||||
|
||||
def test_selection_action_items(self):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
assert item.selection_action_items() == [item]
|
||||
def test_has_selection_outline_when_not_selected(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setSelected(False)
|
||||
item.has_selection_outline() is False
|
||||
|
||||
def test_create_copy(self):
|
||||
item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3), 'foo.png')
|
||||
item.setPos(20, 30)
|
||||
item.setRotation(33)
|
||||
item.do_flip()
|
||||
item.setZValue(0.5)
|
||||
item.setScale(2.2)
|
||||
|
||||
copy = item.create_copy()
|
||||
assert copy.pixmap_to_bytes() == item.pixmap_to_bytes()
|
||||
assert copy.filename == 'foo.png'
|
||||
assert copy.pos() == QtCore.QPointF(20, 30)
|
||||
assert copy.rotation() == 33
|
||||
assert item.flip() == -1
|
||||
assert item.zValue() == 0.5
|
||||
assert item.scale() == 2.2
|
||||
def test_has_selection_outline_when_selected(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setSelected(True)
|
||||
item.has_selection_outline() is True
|
||||
|
||||
|
||||
def test_has_selection_handles_when_not_selected(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setSelected(False)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.setSelected(False)
|
||||
item.has_selection_handles() is False
|
||||
|
||||
|
||||
def test_has_selection_handles_when_selected_single(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setSelected(True)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.setSelected(False)
|
||||
item.has_selection_handles() is True
|
||||
|
||||
|
||||
def test_has_selection_handles_when_selected_multi(view, item):
|
||||
view.scene.addItem(item)
|
||||
item.setSelected(True)
|
||||
item2 = BeePixmapItem(QtGui.QImage())
|
||||
view.scene.addItem(item2)
|
||||
item2.setSelected(True)
|
||||
item.has_selection_handles() is False
|
||||
|
||||
|
||||
def test_selection_action_items(qapp):
|
||||
item = BeePixmapItem(QtGui.QImage())
|
||||
assert item.selection_action_items() == [item]
|
||||
|
||||
|
||||
def test_create_copy(qapp, imgfilename3x3):
|
||||
item = BeePixmapItem(QtGui.QImage(imgfilename3x3), 'foo.png')
|
||||
item.setPos(20, 30)
|
||||
item.setRotation(33)
|
||||
item.do_flip()
|
||||
item.setZValue(0.5)
|
||||
item.setScale(2.2)
|
||||
|
||||
copy = item.create_copy()
|
||||
assert copy.pixmap_to_bytes() == item.pixmap_to_bytes()
|
||||
assert copy.filename == 'foo.png'
|
||||
assert copy.pos() == QtCore.QPointF(20, 30)
|
||||
assert copy.rotation() == 33
|
||||
assert item.flip() == -1
|
||||
assert item.zValue() == 0.5
|
||||
assert item.scale() == 2.2
|
||||
|
|
|
|||
|
|
@ -6,31 +6,25 @@ from beeref.__main__ import BeeRefMainWindow, main
|
|||
from beeref.assets import BeeAssets
|
||||
from beeref.view import BeeGraphicsView
|
||||
|
||||
from .base import BeeTestCase
|
||||
|
||||
@patch('PyQt6.QtWidgets.QWidget.show')
|
||||
def test_beeref_mainwindow_init(show_mock, qapp):
|
||||
window = BeeRefMainWindow(qapp)
|
||||
assert window.windowTitle() == 'BeeRef'
|
||||
assert BeeAssets().logo == BeeAssets().logo
|
||||
assert window.windowIcon()
|
||||
assert window.contentsMargins() == QtCore.QMargins(0, 0, 0, 0)
|
||||
assert isinstance(window.view, BeeGraphicsView)
|
||||
show_mock.assert_called_once()
|
||||
|
||||
|
||||
class BeeRefMainWindowTestCase(BeeTestCase):
|
||||
|
||||
@patch('PyQt6.QtWidgets.QWidget.show')
|
||||
def test_init(self, show_mock):
|
||||
window = BeeRefMainWindow(self.app)
|
||||
assert window.windowTitle() == 'BeeRef'
|
||||
assert BeeAssets().logo == BeeAssets().logo
|
||||
assert window.windowIcon()
|
||||
assert window.contentsMargins() == QtCore.QMargins(0, 0, 0, 0)
|
||||
assert isinstance(window.view, BeeGraphicsView)
|
||||
show_mock.assert_called_once()
|
||||
|
||||
|
||||
class BeeRefMainTestCase(BeeTestCase):
|
||||
|
||||
@patch('PyQt6.QtWidgets.QApplication')
|
||||
@patch('beeref.__main__.CommandlineArgs')
|
||||
def test_run(self, args_mock, app_mock):
|
||||
app_mock.return_value = self.app
|
||||
args_mock.return_value.filename = None
|
||||
args_mock.return_value.loglevel = 'WARN'
|
||||
with patch.object(self.app, 'exec') as exec_mock:
|
||||
main()
|
||||
args_mock.assert_called_once_with(with_check=True)
|
||||
exec_mock.assert_called_once_with()
|
||||
@patch('PyQt6.QtWidgets.QApplication')
|
||||
@patch('beeref.__main__.CommandlineArgs')
|
||||
def test_main(args_mock, app_mock, qapp):
|
||||
app_mock.return_value = qapp
|
||||
args_mock.return_value.filename = None
|
||||
args_mock.return_value.loglevel = 'WARN'
|
||||
with patch.object(qapp, 'exec') as exec_mock:
|
||||
main()
|
||||
args_mock.assert_called_once_with(with_check=True)
|
||||
exec_mock.assert_called_once_with()
|
||||
|
|
|
|||
1606
tests/test_scene.py
1606
tests/test_scene.py
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,31 +1,28 @@
|
|||
import logging
|
||||
import os.path
|
||||
import pytest
|
||||
import tempfile
|
||||
|
||||
from PyQt6 import QtCore
|
||||
|
||||
from beeref import utils
|
||||
from .base import BeeTestCase
|
||||
|
||||
|
||||
class GetRectFromPointsTestCase(BeeTestCase):
|
||||
def test_get_rect_from_points_given_topleft_bottomright():
|
||||
rect = utils.get_rect_from_points(QtCore.QPointF(-10, -20),
|
||||
QtCore.QPointF(30, 40))
|
||||
assert rect.topLeft().x() == -10
|
||||
assert rect.topLeft().y() == -20
|
||||
assert rect.bottomRight().x() == 30
|
||||
assert rect.bottomRight().y() == 40
|
||||
|
||||
def test_given_topleft_bottomright(self):
|
||||
rect = utils.get_rect_from_points(QtCore.QPointF(-10, -20),
|
||||
QtCore.QPointF(30, 40))
|
||||
assert rect.topLeft().x() == -10
|
||||
assert rect.topLeft().y() == -20
|
||||
assert rect.bottomRight().x() == 30
|
||||
assert rect.bottomRight().y() == 40
|
||||
|
||||
def test_given_topright_bottomleft(self):
|
||||
rect = utils.get_rect_from_points(QtCore.QPointF(50, -20),
|
||||
QtCore.QPointF(-30, 40))
|
||||
assert rect.topLeft().x() == -30
|
||||
assert rect.topLeft().y() == -20
|
||||
assert rect.bottomRight().x() == 50
|
||||
assert rect.bottomRight().y() == 40
|
||||
def test_get_rect_from_points_given_topright_bottomleft():
|
||||
rect = utils.get_rect_from_points(QtCore.QPointF(50, -20),
|
||||
QtCore.QPointF(-30, 40))
|
||||
assert rect.topLeft().x() == -30
|
||||
assert rect.topLeft().y() == -20
|
||||
assert rect.bottomRight().x() == 50
|
||||
assert rect.bottomRight().y() == 40
|
||||
|
||||
|
||||
@pytest.mark.parametrize('number,base,expected',
|
||||
|
|
@ -37,22 +34,19 @@ def test_round_to(number, base, expected):
|
|||
assert utils.round_to(number, base) == expected
|
||||
|
||||
|
||||
class BeeRotatingFileHandlerTestCase(BeeTestCase):
|
||||
def test_rotating_file_handler_creates_new_dir(tmpdir):
|
||||
logfile = os.path.join(tmpdir, 'foo', 'bar.log')
|
||||
handler = utils.BeeRotatingFileHandler(logfile)
|
||||
handler.emit(logging.LogRecord(
|
||||
'foo', logging.INFO, 'bar', 66, 'baz', [], None))
|
||||
handler.close()
|
||||
assert os.path.exists(logfile)
|
||||
|
||||
def test_creates_new_dir(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
logfile = os.path.join(tmpdir, 'foo', 'bar.log')
|
||||
handler = utils.BeeRotatingFileHandler(logfile)
|
||||
handler.emit(logging.LogRecord(
|
||||
'foo', logging.INFO, 'bar', 66, 'baz', [], None))
|
||||
handler.close()
|
||||
assert os.path.exists(logfile)
|
||||
|
||||
def test_uses_existing_dir(self):
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
logfile = os.path.join(tmpdir, 'bar.log')
|
||||
handler = utils.BeeRotatingFileHandler(logfile)
|
||||
handler.emit(logging.LogRecord(
|
||||
'foo', logging.INFO, 'bar', 66, 'baz', [], None))
|
||||
handler.close()
|
||||
assert os.path.exists(logfile)
|
||||
def testrotating_file_handler_uses_existing_dir(tmpdir):
|
||||
logfile = os.path.join(tmpdir, 'bar.log')
|
||||
handler = utils.BeeRotatingFileHandler(logfile)
|
||||
handler.emit(logging.LogRecord(
|
||||
'foo', logging.INFO, 'bar', 66, 'baz', [], None))
|
||||
handler.close()
|
||||
assert os.path.exists(logfile)
|
||||
|
|
|
|||
1252
tests/test_view.py
1252
tests/test_view.py
File diff suppressed because it is too large
Load diff
5
tests/utils.py
Normal file
5
tests/utils.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
def queue2list(queue):
|
||||
qlist = []
|
||||
while not queue.empty():
|
||||
qlist.append(queue.get())
|
||||
return qlist
|
||||
Loading…
Reference in a new issue