mirror of
https://github.com/rbreu/beeref.git
synced 2026-03-11 08:54:28 +00:00
1411 lines
48 KiB
Python
1411 lines
48 KiB
Python
import math
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
import pytest
|
|
from pytest import approx
|
|
|
|
from PyQt6 import QtCore, QtGui, QtWidgets
|
|
from PyQt6.QtCore import Qt
|
|
|
|
from beeref import commands
|
|
from beeref.items import BeePixmapItem, BeeTextItem
|
|
|
|
|
|
def test_add_remove_item(view, item):
|
|
view.scene.addItem(item)
|
|
assert view.scene.items() == [item]
|
|
view.scene.removeItem(item)
|
|
assert view.scene.items() == []
|
|
|
|
|
|
def test_cancel_crop_mode_when_crop(view, item):
|
|
view.scene.crop_item = item
|
|
item.exit_crop_mode = MagicMock()
|
|
view.scene.cancel_crop_mode()
|
|
item.exit_crop_mode.assert_called_once_with(confirm=False)
|
|
|
|
|
|
def test_cancel_crop_mode_when_no_crop(view, item):
|
|
view.scene.cancel_crop_mode()
|
|
|
|
|
|
def test_copy_selection_to_internal_clipboard(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)
|
|
|
|
view.scene.copy_selection_to_internal_clipboard()
|
|
assert set(view.scene.internal_clipboard) == {item1, item2}
|
|
assert set(view.scene.items_for_save()) == {item1, item2, item3}
|
|
|
|
|
|
def test_paste_from_internal_clipboard(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.setScale(3.3)
|
|
view.scene.internal_clipboard = [item2]
|
|
|
|
view.scene.paste_from_internal_clipboard(None)
|
|
assert len(list(view.scene.items_for_save())) == 2
|
|
assert item1.isSelected() is False
|
|
new_item = view.scene.selectedItems(user_only=True)[0]
|
|
assert new_item.scale() == 3.3
|
|
assert new_item is not item2
|
|
|
|
|
|
def test_raise_to_top(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setZValue(0.06)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setZValue(0.02)
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item3)
|
|
item3.setZValue(0.07)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
view.scene.raise_to_top()
|
|
assert item1.zValue() == 0.11 + view.scene.Z_STEP
|
|
assert item2.zValue() == 0.07 + view.scene.Z_STEP
|
|
assert item3.zValue() == 0.07
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_lower_to_bottom(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setZValue(-0.06)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setZValue(-0.02)
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item3)
|
|
item3.setZValue(-0.07)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
view.scene.lower_to_bottom()
|
|
assert item1.zValue() == -0.11 - view.scene.Z_STEP
|
|
assert item2.zValue() == -0.07 - view.scene.Z_STEP
|
|
assert item3.zValue() == -0.07
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_height(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setScale(3)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 80)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 80)):
|
|
view.scene.normalize_height()
|
|
|
|
assert item1.scale() == 2
|
|
assert item1.pos() == QtCore.QPointF(-50, -40)
|
|
assert item2.scale() == 2
|
|
assert item2.pos() == QtCore.QPointF(50, 40)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_height_with_rotation(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setRotation(90)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 200)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 200)):
|
|
view.scene.normalize_height()
|
|
|
|
assert item1.scale() == 0.75
|
|
assert item2.scale() == 1.5
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_height_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.normalize_height()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_width(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setScale(3)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 80, 100)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 80, 100)):
|
|
view.scene.normalize_width()
|
|
|
|
assert item1.scale() == 2
|
|
assert item1.pos() == QtCore.QPointF(-40, -50)
|
|
assert item2.scale() == 2
|
|
assert item2.pos() == QtCore.QPointF(40, 50)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_width_with_rotation(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setRotation(90)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 200, 100)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 200, 100)):
|
|
view.scene.normalize_height()
|
|
|
|
assert item1.scale() == 1.5
|
|
assert item2.scale() == 0.75
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_width_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.normalize_width()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_size(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setScale(2)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
view.scene.normalize_size()
|
|
|
|
assert item1.scale() == approx(math.sqrt(2.5))
|
|
assert item2.scale() == approx(math.sqrt(2.5))
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_size_with_rotation(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setRotation(90)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 200)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 200)):
|
|
view.scene.normalize_size()
|
|
|
|
assert item1.scale() == 1
|
|
assert item2.scale() == 1
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_normalize_size_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.normalize_size()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
@pytest.mark.parametrize('value,expected_func,expected_kwargs',
|
|
[('optimal', 'arrange_optimal', {}),
|
|
('horizontal', 'arrange', {}),
|
|
('vertical', 'arrange', {'vertical': True}),
|
|
('square', 'arrange_square', {})])
|
|
def test_arrange_default(
|
|
value, expected_func, expected_kwargs, settings, view):
|
|
settings.setValue('Items/arrange_default', value)
|
|
setattr(view.scene, expected_func, MagicMock())
|
|
view.scene.arrange_default()
|
|
getattr(view.scene, expected_func).assert_called_once_with(
|
|
**expected_kwargs)
|
|
|
|
|
|
def test_arrange_horizontal(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
item1.filename = 'foo.png'
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(10, -100)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'bar.png'
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-10, 40)
|
|
item2.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange()
|
|
|
|
assert item2.pos() == QtCore.QPointF(-50, -30)
|
|
assert item1.pos() == QtCore.QPointF(50, -30)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_horizontal_with_gap(view, settings):
|
|
settings.setValue('Items/arrange_gap', 6)
|
|
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
item1.filename = 'foo.png'
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(10, -100)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'bar.png'
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-10, 40)
|
|
item2.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange()
|
|
|
|
assert item2.pos() == QtCore.QPointF(-50, -30)
|
|
assert item1.pos() == QtCore.QPointF(56, -30)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_vertical(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
item1.filename = 'foo.png'
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(10, -100)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'bar.png'
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-10, 40)
|
|
item2.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange(vertical=True)
|
|
|
|
assert item1.pos() == QtCore.QPointF(0, -70)
|
|
assert item2.pos() == QtCore.QPointF(0, 10)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_vertical_with_gap(view, settings):
|
|
settings.setValue('Items/arrange_gap', 6)
|
|
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
item1.filename = 'foo.png'
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(10, -100)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'bar.png'
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-10, 40)
|
|
item2.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange(vertical=True)
|
|
|
|
assert item1.pos() == QtCore.QPointF(0, -70)
|
|
assert item2.pos() == QtCore.QPointF(0, 16)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_when_rotated(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(10, -100)
|
|
item1.setRotation(90)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-10, 40)
|
|
item2.setRotation(90)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 80)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 80)):
|
|
view.scene.arrange()
|
|
|
|
assert item2.pos() == QtCore.QPointF(-40, -30)
|
|
assert item1.pos() == QtCore.QPointF(40, -30)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_optimal(view):
|
|
for i in range(4):
|
|
item = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_optimal()
|
|
expected_positions = {(-50, -40), (50, -40), (-50, 40), (50, 40)}
|
|
actual_positions = {
|
|
(i.pos().x(), i.pos().y())
|
|
for i in view.scene.selectedItems(user_only=True)}
|
|
assert expected_positions == actual_positions
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_optimal_with_gap(view, settings):
|
|
settings.setValue('Items/arrange_gap', 6)
|
|
for i in range(4):
|
|
item = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_optimal()
|
|
expected_positions = {(-56, -46), (50, -46), (-56, 40), (50, 40)}
|
|
actual_positions = {
|
|
(i.pos().x(), i.pos().y())
|
|
for i in view.scene.selectedItems(user_only=True)}
|
|
assert expected_positions == actual_positions
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_optimal_when_rotated(view):
|
|
for i in range(4):
|
|
item = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item)
|
|
item.setRotation(90)
|
|
item.setSelected(True)
|
|
item.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_optimal()
|
|
|
|
expected_positions = {(-40, -50), (40, -50), (-40, 50), (40, 50)}
|
|
actual_positions = {
|
|
(i.pos().x(), i.pos().y())
|
|
for i in view.scene.selectedItems(user_only=True)}
|
|
assert expected_positions == actual_positions
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_optimal_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_optimal()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_square(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'foo.png'
|
|
item2.save_id = 66
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.crop = QtCore.QRectF(0, 0, 80, 60)
|
|
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
item3.save_id = 33
|
|
view.scene.addItem(item3)
|
|
item3.setSelected(True)
|
|
item3.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item4 = BeePixmapItem(QtGui.QImage())
|
|
item4.filename = 'bar.png'
|
|
item4.save_id = 77
|
|
view.scene.addItem(item4)
|
|
item4.setSelected(True)
|
|
item4.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_square()
|
|
|
|
assert item4.pos() == QtCore.QPointF(-50, -40)
|
|
assert item2.pos() == QtCore.QPointF(60, -30)
|
|
assert item3.pos() == QtCore.QPointF(-50, 40)
|
|
assert item1.pos() == QtCore.QPointF(50, 40)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_square_with_gap(view, settings):
|
|
settings.setValue('Items/arrange_gap', 6)
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
item2.filename = 'foo.png'
|
|
item2.save_id = 66
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.crop = QtCore.QRectF(0, 0, 80, 60)
|
|
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
item3.save_id = 33
|
|
view.scene.addItem(item3)
|
|
item3.setSelected(True)
|
|
item3.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
item4 = BeePixmapItem(QtGui.QImage())
|
|
item4.filename = 'bar.png'
|
|
item4.save_id = 77
|
|
view.scene.addItem(item4)
|
|
item4.setSelected(True)
|
|
item4.crop = QtCore.QRectF(0, 0, 100, 80)
|
|
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_square()
|
|
|
|
assert item4.pos() == QtCore.QPointF(-53, -43)
|
|
assert item2.pos() == QtCore.QPointF(63, -33)
|
|
assert item3.pos() == QtCore.QPointF(-53, 43)
|
|
assert item1.pos() == QtCore.QPointF(53, 43)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_arrange_square_when_no_items(view):
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.arrange_square()
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_flip_items(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
with patch('beeref.scene.BeeGraphicsScene.itemsBoundingRect',
|
|
return_value=QtCore.QRectF(10, 20, 100, 60)):
|
|
view.scene.flip_items(vertical=True)
|
|
args = view.scene.undo_stack.push.call_args_list[0][0]
|
|
cmd = args[0]
|
|
assert isinstance(cmd, commands.FlipItems)
|
|
assert cmd.items == [item]
|
|
assert cmd.anchor == QtCore.QPointF(60, 50)
|
|
assert cmd.vertical is True
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_crop_items(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.enter_crop_mode = MagicMock()
|
|
|
|
view.scene.crop_items()
|
|
item.enter_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_crop_items_when_in_crop_mode(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.enter_crop_mode = MagicMock()
|
|
view.scene.crop_item = item
|
|
|
|
view.scene.crop_items()
|
|
item.enter_crop_mode.assert_not_called()
|
|
|
|
|
|
def test_crop_item_multi_select(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.enter_crop_mode = MagicMock()
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
|
|
view.scene.crop_items()
|
|
item.enter_crop_mode.assert_not_called()
|
|
|
|
|
|
def test_crop_item_no_selection(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(False)
|
|
item.enter_crop_mode = MagicMock()
|
|
|
|
view.scene.crop_items()
|
|
item.enter_crop_mode.assert_not_called()
|
|
|
|
|
|
def test_crop_item_when_not_image(view):
|
|
item = BeeTextItem('foo')
|
|
item.setSelected(True)
|
|
item.enter_crop_mode = MagicMock()
|
|
|
|
view.scene.crop_items()
|
|
item.enter_crop_mode.assert_not_called()
|
|
|
|
|
|
def test_sample_color_at_when_pixmap_item(view):
|
|
color = QtGui.QColor(255, 0, 0, 3)
|
|
img = QtGui.QImage(10, 10, QtGui.QImage.Format.Format_ARGB32)
|
|
img.fill(color)
|
|
item = BeePixmapItem(img, 'foo.png')
|
|
view.scene.addItem(item)
|
|
assert view.scene.sample_color_at(QtCore.QPointF(2, 2)) == color
|
|
|
|
|
|
def test_sample_color_at_when_text_item(view):
|
|
item = BeeTextItem('foo bar baz')
|
|
view.scene.addItem(item)
|
|
assert view.scene.sample_color_at(QtCore.QPointF(2, 2)) is None
|
|
|
|
|
|
def test_sample_color_at_when_no_item(view):
|
|
assert view.scene.sample_color_at(QtCore.QPointF(2, 2)) is None
|
|
|
|
|
|
def test_select_all_items_when_true(view):
|
|
item1 = BeeTextItem('foo')
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeeTextItem('bar')
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
view.scene.select_all_items()
|
|
assert item1.isSelected() is True
|
|
assert item2.isSelected() is True
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_deselect_all_items_when_false(view):
|
|
item1 = BeeTextItem('foo')
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeeTextItem('bar')
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
|
|
view.scene.deselect_all_items()
|
|
assert item1.isSelected() is False
|
|
assert item2.isSelected() is False
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
|
|
|
|
def test_has_selection_when_no_selection(view, item):
|
|
view.scene.addItem(item)
|
|
assert view.scene.has_selection() is False
|
|
|
|
|
|
def test_has_selection_when_selection(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
assert view.scene.has_selection() is True
|
|
|
|
|
|
def test_has_single_selection_when_no_selection(view, item):
|
|
view.scene.addItem(item)
|
|
assert view.scene.has_single_selection() is False
|
|
|
|
|
|
def test_has_single_selection_when_single_selection(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
assert view.scene.has_single_selection() is True
|
|
|
|
|
|
def test_has_single_selection_when_multi_selection(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
assert view.scene.has_single_selection() is False
|
|
|
|
|
|
def test_has_multi_selection_when_no_selection(view, item):
|
|
view.scene.addItem(item)
|
|
assert view.scene.has_multi_selection() is False
|
|
|
|
|
|
def test_has_multi_selection_when_single_selection(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
assert view.scene.has_multi_selection() is False
|
|
|
|
|
|
def test_has_multi_selection_when_multi_selection(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
assert view.scene.has_multi_selection() is True
|
|
|
|
|
|
def test_has_single_image_selection(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
assert view.scene.has_single_image_selection() is True
|
|
|
|
|
|
def test_has_single_image_selection_when_item_not_image(view):
|
|
item = BeeTextItem('foo')
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
assert view.scene.has_single_image_selection() is False
|
|
|
|
|
|
def test_has_single_image_selection_when_no_selection(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(False)
|
|
assert view.scene.has_single_image_selection() is False
|
|
|
|
|
|
def test_has_single_image_selection_when_multi_selection(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
assert view.scene.has_single_image_selection() is False
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_right_click(mouse_mock, view):
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.RightButton))
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_not_called()
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_item(mouse_mock, view, item):
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode == view.scene.MOVE_MODE
|
|
assert view.scene.event_start == QtCore.QPointF(10, 20)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_item_in_edit_mode(
|
|
mouse_mock, view):
|
|
item = BeeTextItem('foo bar')
|
|
item.exit_edit_mode = MagicMock()
|
|
view.scene.addItem(item)
|
|
view.scene.edit_item = item
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
item.exit_edit_mode.assert_not_called()
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_diff_item_in_edit_mode(
|
|
mouse_mock, view, item):
|
|
txtitem = BeeTextItem('foo bar')
|
|
txtitem.exit_edit_mode = MagicMock()
|
|
view.scene.addItem(txtitem)
|
|
view.scene.edit_item = txtitem
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
txtitem.exit_edit_mode.assert_called_once_with()
|
|
assert view.scene.active_mode == view.scene.MOVE_MODE
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_no_item_in_edit_mode(
|
|
mouse_mock, view):
|
|
item = BeeTextItem('foo bar')
|
|
item.exit_edit_mode = MagicMock()
|
|
view.scene.addItem(item)
|
|
view.scene.edit_item = item
|
|
view.scene.itemAt = MagicMock(return_value=None)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
item.exit_edit_mode.assert_called_once_with()
|
|
assert view.scene.active_mode == view.scene.RUBBERBAND_MODE
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_item_in_crop_mode(
|
|
mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.crop_item = item
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
view.scene.cancel_crop_mode.assert_not_called()
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_diff_item_in_crop_mode(
|
|
mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.crop_item = item
|
|
other_item = BeePixmapItem(QtGui.QImage())
|
|
view.scene.itemAt = MagicMock(return_value=other_item)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
assert view.scene.active_mode is view.scene.MOVE_MODE
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_over_no_item_in_crop_mode(
|
|
mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
view.scene.cancel_crop_mode = MagicMock()
|
|
view.scene.crop_item = item
|
|
view.scene.itemAt = MagicMock(return_value=None)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
view.scene.cancel_crop_mode.assert_called_once_with()
|
|
assert view.scene.active_mode == view.scene.RUBBERBAND_MODE
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_left_click_not_over_item(
|
|
mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
view.scene.itemAt = MagicMock(return_value=None)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode == view.scene.RUBBERBAND_MODE
|
|
assert view.scene.event_start == QtCore.QPointF(10, 20)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
def test_mouse_press_event_when_no_items(mouse_mock, view):
|
|
view.scene.itemAt = MagicMock(return_value=None)
|
|
event = MagicMock(
|
|
button=MagicMock(return_value=Qt.MouseButton.LeftButton),
|
|
scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)),
|
|
)
|
|
view.scene.mousePressEvent(event)
|
|
event.accept.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
mouse_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseDoubleClickEvent')
|
|
def test_mouse_doubleclick_event_when_over_item(mouse_mock, view, item):
|
|
event = MagicMock()
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.addItem(item)
|
|
item.setPos(30, 40)
|
|
item.setSelected(True)
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
view.fit_rect = MagicMock()
|
|
|
|
with patch.object(item, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
view.scene.mouseDoubleClickEvent(event)
|
|
|
|
assert view.scene.active_mode is None
|
|
view.fit_rect.assert_called_once_with(
|
|
QtCore.QRectF(30, 40, 100, 100), toggle_item=item)
|
|
mouse_mock.assert_not_called()
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mousePressEvent')
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseDoubleClickEvent')
|
|
def test_mouse_doubleclick_event_when_over_editable_item(
|
|
double_mock, press_mock, view):
|
|
item = BeeTextItem('foo bar')
|
|
item.enter_edit_mode = MagicMock()
|
|
event = MagicMock()
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.addItem(item)
|
|
item.setPos(30, 40)
|
|
item.setSelected(True)
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
view.fit_rect = MagicMock()
|
|
|
|
with patch.object(item, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
view.scene.mouseDoubleClickEvent(event)
|
|
|
|
assert view.scene.active_mode is None
|
|
item.enter_edit_mode.assert_called_once_with()
|
|
double_mock.assert_not_called()
|
|
press_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseDoubleClickEvent')
|
|
def test_mouse_doubleclick_event_when_item_not_selected(
|
|
mouse_mock, view, item):
|
|
event = MagicMock()
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.addItem(item)
|
|
item.setPos(30, 40)
|
|
item.setSelected(False)
|
|
view.scene.itemAt = MagicMock(return_value=item)
|
|
view.fit_rect = MagicMock()
|
|
|
|
with patch.object(item, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
view.scene.mouseDoubleClickEvent(event)
|
|
|
|
assert view.scene.active_mode is None
|
|
view.fit_rect.assert_called_once_with(
|
|
QtCore.QRectF(30, 40, 100, 100), toggle_item=item)
|
|
mouse_mock.assert_not_called()
|
|
assert item.isSelected() is True
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseDoubleClickEvent')
|
|
def test_mouse_doubleclick_event_when_not_over_item(mouse_mock, view):
|
|
event = MagicMock()
|
|
view.fit_rect = MagicMock()
|
|
view.scene.itemAt = MagicMock(return_value=None)
|
|
view.scene.mouseDoubleClickEvent(event)
|
|
view.fit_rect.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseMoveEvent')
|
|
def test_mouse_move_event_when_rubberband_new(
|
|
mouse_mock, view, imgfilename3x3):
|
|
item = BeePixmapItem(QtGui.QImage(imgfilename3x3))
|
|
view.scene.addItem(item)
|
|
view.scene.active_mode = view.scene.RUBBERBAND_MODE
|
|
view.scene.addItem = MagicMock()
|
|
view.scene.event_start = QtCore.QPointF(0, 0)
|
|
view.scene.rubberband_item.bring_to_front = MagicMock()
|
|
assert view.scene.rubberband_item.scene() is None
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)))
|
|
|
|
view.scene.mouseMoveEvent(event)
|
|
|
|
view.scene.addItem.assert_called_once_with(view.scene.rubberband_item)
|
|
view.scene.rubberband_item.bring_to_front.assert_called_once()
|
|
view.scene.rubberband_item.rect().topLeft().x() == 0
|
|
view.scene.rubberband_item.rect().topLeft().y() == 0
|
|
view.scene.rubberband_item.rect().bottomRight().x() == 10
|
|
view.scene.rubberband_item.rect().bottomRight().y() == 20
|
|
assert item.isSelected() is True
|
|
mouse_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseMoveEvent')
|
|
def test_mouse_move_event_when_rubberband_not_new(
|
|
mouse_mock, view, imgfilename3x3):
|
|
item = BeePixmapItem(QtGui.QImage(imgfilename3x3))
|
|
view.scene.addItem(item)
|
|
view.scene.active_mode = view.scene.RUBBERBAND_MODE
|
|
view.scene.event_start = QtCore.QPointF(0, 0)
|
|
view.scene.rubberband_item.bring_to_front = MagicMock()
|
|
view.scene.addItem(view.scene.rubberband_item)
|
|
view.scene.addItem = MagicMock()
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)))
|
|
|
|
view.scene.mouseMoveEvent(event)
|
|
|
|
view.scene.addItem.assert_not_called()
|
|
view.scene.rubberband_item.bring_to_front.assert_not_called()
|
|
view.scene.rubberband_item.rect().topLeft().x() == 0
|
|
view.scene.rubberband_item.rect().topLeft().y() == 0
|
|
view.scene.rubberband_item.rect().bottomRight().x() == 10
|
|
view.scene.rubberband_item.rect().bottomRight().y() == 20
|
|
assert item.isSelected() is True
|
|
mouse_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseMoveEvent')
|
|
def test_mouse_move_event_when_no_rubberband(mouse_mock, view, imgfilename3x3):
|
|
item = BeePixmapItem(QtGui.QImage(imgfilename3x3))
|
|
view.scene.addItem(item)
|
|
view.scene.active_mode = None
|
|
view.scene.event_start = QtCore.QPointF(0, 0)
|
|
view.scene.rubberband_item.bring_to_front = MagicMock()
|
|
view.scene.addItem = MagicMock()
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPointF(10, 20)))
|
|
|
|
view.scene.mouseMoveEvent(event)
|
|
|
|
view.scene.addItem.assert_not_called()
|
|
view.scene.rubberband_item.bring_to_front.assert_not_called()
|
|
view.scene.rubberband_item.rect().topLeft().x() == 0
|
|
view.scene.rubberband_item.rect().topLeft().y() == 0
|
|
view.scene.rubberband_item.rect().bottomRight().x() == 0
|
|
view.scene.rubberband_item.rect().bottomRight().y() == 0
|
|
assert item.isSelected() is False
|
|
mouse_mock.assert_called_once_with(event)
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_rubberband_active(mouse_mock, view):
|
|
event = MagicMock()
|
|
view.scene.active_mode = view.scene.RUBBERBAND_MODE
|
|
view.scene.addItem(view.scene.rubberband_item)
|
|
view.scene.removeItem = MagicMock()
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.removeItem.assert_called_once_with(view.scene.rubberband_item)
|
|
view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_move_active(mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPoint(10, 20)))
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.event_start = QtCore.QPoint(0, 0)
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.undo_stack.push.assert_called_once()
|
|
args = view.scene.undo_stack.push.call_args_list[0][0]
|
|
cmd = args[0]
|
|
assert isinstance(cmd, commands.MoveItemsBy)
|
|
assert cmd.items == [item]
|
|
assert cmd.ignore_first_redo is True
|
|
assert cmd.delta.x() == 10
|
|
assert cmd.delta.y() == 20
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_move_not_active(mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPoint(10, 20)))
|
|
view.scene.active_mode = None
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.undo_stack.push.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_no_selection(mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(False)
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPoint(10, 20)))
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.undo_stack.push.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_item_action_active(mouse_mock, view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPoint(10, 20)))
|
|
item.active_mode = item.SCALE_MODE
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.undo_stack.push.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
@patch('PyQt6.QtWidgets.QGraphicsScene.mouseReleaseEvent')
|
|
def test_mouse_release_event_when_multiselect_action_active(mouse_mock, view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
event = MagicMock(scenePos=MagicMock(return_value=QtCore.QPoint(10, 20)))
|
|
view.scene.active_mode = view.scene.MOVE_MODE
|
|
view.scene.multi_select_item.active_mode = BeePixmapItem.SCALE_MODE
|
|
view.scene.undo_stack = MagicMock(push=MagicMock())
|
|
|
|
view.scene.mouseReleaseEvent(event)
|
|
view.scene.undo_stack.push.assert_not_called()
|
|
mouse_mock.assert_called_once_with(event)
|
|
assert view.scene.active_mode is None
|
|
|
|
|
|
def test_selected_items(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
selected = view.scene.selectedItems()
|
|
assert len(selected) == 3 # Multi select item!
|
|
assert item1 in selected
|
|
assert item2 in selected
|
|
|
|
|
|
def test_selected_items_user_only(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
selected = view.scene.selectedItems(user_only=True)
|
|
assert len(selected) == 2 # No multi select item!
|
|
assert item1 in selected
|
|
assert item2 in selected
|
|
|
|
|
|
def test_items_by_tpe(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item2 = BeeTextItem('foo')
|
|
view.scene.addItem(item2)
|
|
assert list(view.scene.items_by_type('text')) == [item2]
|
|
|
|
|
|
def test_items_for_save(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item3 = QtWidgets.QGraphicsRectItem()
|
|
view.scene.addItem(item3)
|
|
|
|
items = list(view.scene.items_for_save())
|
|
assert items == [item1, item2]
|
|
|
|
|
|
def test_clear_save_ids(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
item1.save_id = 5
|
|
view.scene.addItem(item1)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item3 = QtWidgets.QGraphicsRectItem()
|
|
view.scene.addItem(item3)
|
|
|
|
view.scene.clear_save_ids()
|
|
assert item1.save_id is None
|
|
assert item2.save_id is None
|
|
assert hasattr(item3, 'save_id') is False
|
|
|
|
|
|
def test_on_view_scale_change(view, item):
|
|
view.scene.addItem(item)
|
|
item.setSelected(True)
|
|
item.on_view_scale_change = MagicMock()
|
|
view.scene.on_view_scale_change()
|
|
item.on_view_scale_change.assert_called_once()
|
|
|
|
|
|
def test_items_bounding_rect_given_items(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(4, -6)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-33, 22)
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item3)
|
|
item3.setSelected(True)
|
|
item3.setPos(1000, 1000)
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
rect = view.scene.itemsBoundingRect(items=[item1, item2])
|
|
|
|
assert rect.topLeft().x() == -33
|
|
assert rect.topLeft().y() == -6
|
|
assert rect.bottomRight().x() == 104
|
|
assert rect.bottomRight().y() == 122
|
|
|
|
|
|
def test_items_bounding_rect_two_items_selection_only(view):
|
|
item1 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item1)
|
|
item1.setSelected(True)
|
|
item1.setPos(4, -6)
|
|
item2 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item2)
|
|
item2.setSelected(True)
|
|
item2.setPos(-33, 22)
|
|
item3 = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item3)
|
|
item3.setSelected(False)
|
|
item3.setPos(1000, 1000)
|
|
|
|
with patch.object(item1, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
with patch.object(item2, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
rect = view.scene.itemsBoundingRect(selection_only=True)
|
|
|
|
assert rect.topLeft().x() == -33
|
|
assert rect.topLeft().y() == -6
|
|
assert rect.bottomRight().x() == 104
|
|
assert rect.bottomRight().y() == 122
|
|
|
|
|
|
def test_items_bounding_rect_rotated_item(view, item):
|
|
view.scene.addItem(item)
|
|
item.setRotation(-45)
|
|
|
|
with patch.object(item, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 100, 100)):
|
|
rect = view.scene.itemsBoundingRect()
|
|
|
|
assert rect.topLeft().x() == 0
|
|
assert rect.topLeft().y() == approx(-math.sqrt(2) * 50)
|
|
assert rect.bottomRight().x() == approx(math.sqrt(2) * 100)
|
|
assert rect.bottomRight().y() == approx(math.sqrt(2) * 50)
|
|
|
|
|
|
def test_items_bounding_rect_flipped_item(view):
|
|
item = BeePixmapItem(QtGui.QImage())
|
|
view.scene.addItem(item)
|
|
item.do_flip()
|
|
with patch.object(item, 'bounding_rect_unselected',
|
|
return_value=QtCore.QRectF(0, 0, 50, 100)):
|
|
rect = view.scene.itemsBoundingRect()
|
|
|
|
assert rect.topLeft().x() == -50
|
|
assert rect.topLeft().y() == 0
|
|
assert rect.bottomRight().x() == 0
|
|
assert rect.bottomRight().y() == 100
|
|
|
|
|
|
def test_items_bounding_rect_when_no_items(view):
|
|
rect = view.scene.itemsBoundingRect()
|
|
assert rect == QtCore.QRectF(0, 0, 0, 0)
|
|
|
|
|
|
def test_get_selection_center(view):
|
|
with patch('beeref.scene.BeeGraphicsScene.itemsBoundingRect',
|
|
return_value=QtCore.QRectF(10, 20, 100, 60)):
|
|
center = view.scene.get_selection_center()
|
|
assert center == QtCore.QPointF(60, 50)
|
|
|
|
|
|
def test_on_selection_change_when_multi_selection_new(view):
|
|
view.scene.has_multi_selection = MagicMock(return_value=True)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.bring_to_front = MagicMock()
|
|
view.scene.itemsBoundingRect = MagicMock(
|
|
return_value=QtCore.QRectF(0, 0, 100, 80))
|
|
view.scene.addItem = MagicMock()
|
|
|
|
view.scene.on_selection_change()
|
|
|
|
m_item = view.scene.multi_select_item
|
|
m_item.fit_selection_area.assert_called_once_with(
|
|
QtCore.QRectF(0, 0, 100, 80))
|
|
m_item.bring_to_front.assert_called_once()
|
|
view.scene.addItem.assert_called_once_with(m_item)
|
|
|
|
|
|
def test_on_selection_change_when_multi_selection_existing(view):
|
|
view.scene.addItem(view.scene.multi_select_item)
|
|
view.scene.has_multi_selection = MagicMock(return_value=True)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.bring_to_front = MagicMock()
|
|
view.scene.itemsBoundingRect = MagicMock(
|
|
return_value=QtCore.QRectF(0, 0, 100, 80))
|
|
view.scene.addItem = MagicMock()
|
|
|
|
view.scene.on_selection_change()
|
|
|
|
m_item = view.scene.multi_select_item
|
|
m_item.fit_selection_area.assert_called_once_with(
|
|
QtCore.QRectF(0, 0, 100, 80))
|
|
m_item.bring_to_front.assert_not_called()
|
|
view.scene.addItem.assert_not_called()
|
|
|
|
|
|
def test_on_selection_change_when_multi_selection_ended(view):
|
|
view.scene.addItem(view.scene.multi_select_item)
|
|
view.scene.has_multi_selection = MagicMock(return_value=False)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.bring_to_front = MagicMock()
|
|
view.scene.itemsBoundingRect = MagicMock(
|
|
return_value=QtCore.QRectF(0, 0, 100, 80))
|
|
view.scene.removeItem = MagicMock()
|
|
|
|
view.scene.on_selection_change()
|
|
|
|
m_item = view.scene.multi_select_item
|
|
m_item.fit_selection_area.assert_not_called()
|
|
view.scene.removeItem.assert_called_once_with(m_item)
|
|
|
|
|
|
def test_on_change_when_multi_select_when_no_scale_no_rotate(view):
|
|
view.scene.addItem(view.scene.multi_select_item)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.active_mode = None
|
|
view.scene.on_change(None)
|
|
view.scene.multi_select_item.fit_selection_area.assert_called_once()
|
|
|
|
|
|
def test_on_change_when_multi_select_when_scale_active(view):
|
|
view.scene.addItem(view.scene.multi_select_item)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.active_mode = BeePixmapItem.SCALE_MODE
|
|
view.scene.on_change(None)
|
|
view.scene.multi_select_item.fit_selection_area.assert_not_called()
|
|
|
|
|
|
def test_on_change_when_multi_select_when_rotate_active(view):
|
|
view.scene.addItem(view.scene.multi_select_item)
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.active_mode = BeePixmapItem.ROTATE_MODE
|
|
view.scene.on_change(None)
|
|
view.scene.multi_select_item.fit_selection_area.assert_not_called()
|
|
|
|
|
|
def test_on_change_when_no_multi_select(view):
|
|
view.scene.multi_select_item.fit_selection_area = MagicMock()
|
|
view.scene.multi_select_item.active_mode = BeePixmapItem.SCALE_MODE
|
|
view.scene.on_change(None)
|
|
view.scene.multi_select_item.fit_selection_area.assert_not_called()
|
|
|
|
|
|
def test_add_queued_items_unselected(view):
|
|
data = {'type': 'text', 'z': 0.33, 'data': {'text': 'foo'}}
|
|
view.scene.add_item_later(data, selected=False)
|
|
view.scene.add_queued_items()
|
|
assert len(view.scene.items()) == 1
|
|
item = view.scene.items()[0]
|
|
assert item.isSelected() is False
|
|
assert view.scene.max_z == 0.33
|
|
assert item.toPlainText() == 'foo'
|
|
|
|
|
|
def test_add_queued_items_selected(view):
|
|
view.scene.max_z = 0.6
|
|
data = {'type': 'text', 'z': 0.33, 'data': {'text': 'foo'}}
|
|
view.scene.add_item_later(data, selected=True)
|
|
view.scene.add_queued_items()
|
|
assert len(view.scene.items()) == 1
|
|
item = view.scene.items()[0]
|
|
assert item.isSelected() is True
|
|
assert item.zValue() > 0.6
|
|
|
|
|
|
def test_add_queued_items_when_no_items(view):
|
|
view.scene.add_queued_items()
|
|
assert view.scene.items() == []
|
|
|
|
|
|
def test_add_queued_items_ignores_unknown_type(view):
|
|
data = {'type': 'foo', 'z': 0.33, 'data': {'bar': 'baz'}}
|
|
view.scene.add_item_later(data, selected=False)
|
|
view.scene.add_queued_items()
|
|
assert len(view.scene.items()) == 1
|
|
item = view.scene.items()[0]
|
|
assert item.toPlainText() == 'Item of unknown type: foo'
|