From b98e455272a17a9830beb2f1511211ea58fea1fd Mon Sep 17 00:00:00 2001 From: Rebecca Breu Date: Tue, 6 Apr 2021 17:34:55 +0200 Subject: [PATCH] More unittests for the view --- README.rst | 1 + beeref/view.py | 1 - tests/base.py | 3 +- tests/test_scene.py | 2 +- tests/test_view.py | 83 +++++++++++++++++++++++++++++++++++++++------ 5 files changed, 77 insertions(+), 13 deletions(-) diff --git a/README.rst b/README.rst index 2154b55..64fc76d 100644 --- a/README.rst +++ b/README.rst @@ -12,6 +12,7 @@ BeeRef lets you quickly arrange your reference images and view them while you cr .. image:: https://github.com/rbreu/beeref/blob/main/images/screenshot.jpg .. |python-version| image:: https://github.com/rbreu/beeref/blob/main/images/python_version_badge.svg + :target: https://www.python.org/ .. |github-ci-flake8| image:: https://github.com/rbreu/beeref/actions/workflows/flake8.yml/badge.svg :target: https://github.com/rbreu/beeref/actions/workflows/flake8.yml diff --git a/beeref/view.py b/beeref/view.py index 4ac485f..7dc874b 100644 --- a/beeref/view.py +++ b/beeref/view.py @@ -353,7 +353,6 @@ class BeeGraphicsView(QtWidgets.QGraphicsView): if img.isNull(): logger.info('No image data in clipboard') else: - self.scene.clearSelection() item = BeePixmapItem(img) pos = self.mapToScene(self.mapFromGlobal(self.cursor().pos())) item.set_pos_center(pos) diff --git a/tests/base.py b/tests/base.py index 25036e8..47762cc 100644 --- a/tests/base.py +++ b/tests/base.py @@ -17,7 +17,8 @@ class BeeTestCase(TestCase): @classmethod def setUpClass(cls): - cls.app = QtWidgets.QApplication([]) + inst = QtWidgets.QApplication.instance() + cls.app = inst if inst else QtWidgets.QApplication([]) @classmethod def tearDownClass(cls): diff --git a/tests/test_scene.py b/tests/test_scene.py index 513b782..31052e7 100644 --- a/tests/test_scene.py +++ b/tests/test_scene.py @@ -166,7 +166,7 @@ class BeeGraphicsSceneTestCase(BeeTestCase): self.scene.addItem = MagicMock() self.scene.event_start = QtCore.QPointF(0, 0) self.scene.rubberband_item.bring_to_front = MagicMock() - self.scene.removeItem(self.scene.rubberband_item) + assert self.scene.rubberband_item.scene() is None event = MagicMock( scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)), ) diff --git a/tests/test_view.py b/tests/test_view.py index 259b263..e8acaf0 100644 --- a/tests/test_view.py +++ b/tests/test_view.py @@ -2,11 +2,10 @@ import os.path import tempfile from unittest.mock import patch -import pytest - from PyQt6 import QtGui from beeref.items import BeePixmapItem +from beeref import fileio from beeref.view import BeeGraphicsView from .base import BeeTestCase @@ -37,7 +36,6 @@ class BeeGraphicsViewTestCase(BeeTestCase): open_file_mock.assert_called_once_with('test.bee') del view - @pytest.mark.skip('Causes segfaults sometimes') @patch('beeref.view.BeeGraphicsView.recalc_scene_rect') @patch('beeref.gui.WelcomeOverlay.hide') def test_on_scene_changed_when_items(self, hide_mock, recalc_mock): @@ -59,21 +57,18 @@ class BeeGraphicsViewTestCase(BeeTestCase): assert '*.png' in formats assert '*.jpg' in formats - @pytest.mark.skip('Causes segfaults sometimes') def test_open_from_file(self): root = os.path.dirname(__file__) filename = os.path.join(root, 'assets', 'test1item.bee') self.view.open_from_file(filename) assert len(self.view.scene.items()) == 1 - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QMessageBox.warning') def test_open_from_file_when_error(self, warn_mock): self.view.open_from_file('uieauiae') assert len(self.view.scene.items()) == 0 warn_mock.assert_called_once() - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QFileDialog.getOpenFileName') def test_on_action_open(self, dialog_mock): root = os.path.dirname(__file__) @@ -83,14 +78,12 @@ class BeeGraphicsViewTestCase(BeeTestCase): self.view.on_action_open() assert len(self.view.scene.items()) == 1 - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QFileDialog.getOpenFileName') def test_on_action_open_when_no_filename(self, dialog_mock): dialog_mock.return_value = (None, None) self.view.on_action_open() assert len(self.view.scene.items()) == 0 - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName') def test_on_action_save_as(self, dialog_mock): item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3)) @@ -102,7 +95,6 @@ class BeeGraphicsViewTestCase(BeeTestCase): self.view.on_action_save_as() assert os.path.exists(filename) is True - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName') @patch('beeref.fileio.save') def test_on_action_save_as_when_no_filename(self, save_mock, dialog_mock): @@ -112,7 +104,6 @@ class BeeGraphicsViewTestCase(BeeTestCase): self.view.on_action_save_as() save_mock.assert_not_called() - @pytest.mark.skip('Causes segfaults sometimes') @patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName') def test_on_action_save_as_filename_doesnt_end_with_bee(self, dialog_mock): item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3)) @@ -123,3 +114,75 @@ class BeeGraphicsViewTestCase(BeeTestCase): dialog_mock.return_value = (filename, None) self.view.on_action_save_as() assert os.path.exists(f'{filename}.bee') is True + + @patch('PyQt6.QtWidgets.QMessageBox.warning') + @patch('PyQt6.QtWidgets.QFileDialog.getSaveFileName') + @patch('beeref.fileio.save') + def test_on_action_save_as_when_error( + self, save_mock, dialog_mock, warn_mock): + item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3)) + self.view.scene.addItem(item) + with tempfile.TemporaryDirectory() as tmpdir: + filename = os.path.join(tmpdir, 'test.bee') + assert os.path.exists(filename) is False + dialog_mock.return_value = (filename, None) + save_mock.side_effect = fileio.BeeFileIOError('foo', 'test.bee') + self.view.on_action_save_as() + warn_mock.assert_called_once() + assert os.path.exists(filename) is False + + def test_on_action_save(self): + item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3)) + self.view.scene.addItem(item) + with tempfile.TemporaryDirectory() as tmpdir: + self.view.filename = os.path.join(tmpdir, 'test.bee') + assert os.path.exists(self.view.filename) is False + self.view.on_action_save() + assert os.path.exists(self.view.filename) is True + + @patch('beeref.view.BeeGraphicsView.on_action_save_as') + def test_on_action_save_when_no_filename(self, save_as_mock): + item = BeePixmapItem(QtGui.QImage(self.imgfilename3x3)) + self.view.scene.addItem(item) + self.view.filename = None + self.view.on_action_save() + save_as_mock.assert_called_once_with() + + @patch('beeref.scene.BeeGraphicsScene.clearSelection') + @patch('PyQt6.QtWidgets.QFileDialog.getOpenFileNames') + def test_on_action_insert_images(self, dialog_mock, clear_mock): + dialog_mock.return_value = ([self.imgfilename3x3], None) + self.view.on_action_insert_images() + assert len(self.view.scene.items()) == 1 + assert self.view.scene.items()[0].isSelected() is True + clear_mock.assert_called_once_with() + + @patch('beeref.scene.BeeGraphicsScene.clearSelection') + @patch('PyQt6.QtWidgets.QMessageBox.warning') + @patch('PyQt6.QtWidgets.QFileDialog.getOpenFileNames') + def test_on_action_insert_images_when_error( + self, dialog_mock, warn_mock, clear_mock): + dialog_mock.return_value = ( + [self.imgfilename3x3, 'iaeiae', 'trntrn'], None) + self.view.on_action_insert_images() + assert len(self.view.scene.items()) == 1 + assert self.view.scene.items()[0].isSelected() is True + warn_mock.assert_called_once() + clear_mock.assert_called_once_with() + + @patch('beeref.scene.BeeGraphicsScene.clearSelection') + @patch('PyQt6.QtGui.QClipboard.image') + def test_on_action_paste(self, clipboard_mock, clear_mock): + clipboard_mock.return_value = QtGui.QImage(self.imgfilename3x3) + self.view.on_action_paste() + assert len(self.view.scene.items()) == 1 + assert self.view.scene.items()[0].isSelected() is True + clear_mock.assert_called_once_with() + + @patch('beeref.scene.BeeGraphicsScene.clearSelection') + @patch('PyQt6.QtGui.QClipboard.image') + def test_on_action_paste_when_empty(self, clipboard_mock, clear_mock): + clipboard_mock.return_value = QtGui.QImage() + self.view.on_action_paste() + assert len(self.view.scene.items()) == 0 + clear_mock.assert_not_called()