beeref/tests/test_items.py

443 lines
17 KiB
Python
Raw Normal View History

2021-03-30 17:04:44 +00:00
from unittest.mock import patch, MagicMock, PropertyMock
2021-03-25 17:45:55 +00:00
2021-03-30 17:04:44 +00:00
from PyQt6 import QtCore, QtGui, QtWidgets
2021-04-01 14:31:43 +00:00
from PyQt6.QtCore import Qt
2021-03-22 20:48:05 +00:00
from beeref.items import BeePixmapItem
2021-03-30 17:04:44 +00:00
from beeref.scene import BeeGraphicsScene
from .base import BeeTestCase
2021-03-22 20:48:05 +00:00
class BeePixmapItemTestCase(BeeTestCase):
def setUp(self):
self.scene = BeeGraphicsScene(None)
2021-03-22 20:48:05 +00:00
def test_init(self):
2021-03-28 09:06:04 +00:00
item = BeePixmapItem(
QtGui.QImage(self.imgfilename3x3), self.imgfilename3x3)
assert item.save_id is None
2021-03-22 20:48:05 +00:00
assert item.width == 3
assert item.height == 3
2021-03-28 20:45:16 +00:00
assert item.scale() == 1
2021-03-22 20:48:05 +00:00
assert item.flags() == (
QtWidgets.QGraphicsItem.GraphicsItemFlags.ItemIsMovable
| QtWidgets.QGraphicsItem.GraphicsItemFlags.ItemIsSelectable)
2021-03-28 09:06:04 +00:00
assert item.filename == self.imgfilename3x3
2021-03-22 20:48:05 +00:00
2021-03-25 17:45:55 +00:00
def test_set_scale(self):
2021-04-01 14:31:43 +00:00
item = BeePixmapItem(
QtGui.QImage(self.imgfilename3x3), self.imgfilename3x3)
2021-03-30 17:04:44 +00:00
item.prepareGeometryChange = MagicMock()
2021-03-25 17:45:55 +00:00
item.setScale(3)
2021-03-28 20:45:16 +00:00
assert item.scale() == 3
2021-04-01 14:31:43 +00:00
assert item.pos().x() == 0
assert item.pos().y() == 0
2021-03-30 17:04:44 +00:00
item.prepareGeometryChange.assert_called_once()
2021-03-25 17:45:55 +00:00
def test_set_scale_ignores_zero(self):
item = BeePixmapItem(QtGui.QImage())
item.setScale(0)
2021-03-28 20:45:16 +00:00
assert item.scale() == 1
2021-03-25 17:45:55 +00:00
def test_set_scale_ignores_negative(self):
item = BeePixmapItem(QtGui.QImage())
item.setScale(-0.1)
2021-03-28 20:45:16 +00:00
assert item.scale() == 1
2021-03-25 17:45:55 +00:00
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(0, 0)
assert item.pos().x() == -100
assert item.pos().y() == -50
2021-03-30 17:04:44 +00:00
def test_set_zvalue_sets_new_max(self):
item = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item)
item.setZValue(1.1)
assert item.zValue() == 1.1
assert self.scene.max_z == 1.1
def test_set_zvalue_keeps_old_max(self):
item = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item)
self.scene.max_z = 3.3
item.setZValue(1.1)
assert item.zValue() == 1.1
assert self.scene.max_z == 3.3
def test_bring_to_front(self):
item1 = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item1)
item1.setZValue(3.3)
item2 = BeePixmapItem(QtGui.QImage())
self.scene.addItem(item2)
item2.bring_to_front()
assert item2.zValue() > item1.zValue()
assert item2.zValue() == self.scene.max_z
2021-04-01 14:31:43 +00:00
def test_on_view_scale_change(self):
item = BeePixmapItem(QtGui.QImage())
with patch('beeref.items.BeePixmapItem.prepareGeometryChange') as m:
item.on_view_scale_change()
m.assert_called_once()
2021-03-30 17:04:44 +00:00
2021-04-01 14:31:43 +00:00
class BeePixmapItemWithViewBaseTestCase(BeeTestCase):
2021-03-30 17:04:44 +00:00
def setUp(self):
self.scene = BeeGraphicsScene(None)
self.item = BeePixmapItem(QtGui.QImage())
self.scene.addItem(self.item)
self.view = MagicMock(get_scale=MagicMock(return_value=1))
2021-04-01 14:31:43 +00:00
views_patcher = patch('beeref.scene.BeeGraphicsScene.views',
return_value=[self.view])
views_patcher.start()
2021-03-30 17:04:44 +00:00
self.addCleanup(views_patcher.stop)
2021-04-01 14:31:43 +00:00
width_patcher = patch('beeref.items.BeePixmapItem.width',
new_callable=PropertyMock,
return_value=100)
width_patcher.start()
self.addCleanup(width_patcher.stop)
height_patcher = patch('beeref.items.BeePixmapItem.height',
new_callable=PropertyMock,
return_value=80)
height_patcher.start()
self.addCleanup(height_patcher.stop)
class BeePixmapItemPaintstuffTestCase(BeePixmapItemWithViewBaseTestCase):
2021-03-30 17:04:44 +00:00
def test_fixed_length_for_viewport_when_default_scales(self):
self.view.get_scale = MagicMock(return_value=1)
assert self.item.fixed_length_for_viewport(100) == 100
assert self.item._view_scale == 1
2021-03-30 17:04:44 +00:00
def test_fixed_length_for_viewport_when_viewport_scaled(self):
self.view.get_scale = MagicMock(return_value=2)
assert self.item.fixed_length_for_viewport(100) == 50
assert self.item._view_scale == 2
2021-03-30 17:04:44 +00:00
def test_fixed_length_for_viewport_when_item_scaled(self):
self.view.get_scale = MagicMock(return_value=1)
self.item.setScale(5)
assert self.item.fixed_length_for_viewport(100) == 20
assert self.item._view_scale == 1
2021-03-30 17:04:44 +00:00
2021-03-31 07:47:24 +00:00
def test_fixed_length_for_viewport_when_no_scene(self):
item = BeePixmapItem(QtGui.QImage())
item._view_scale = 0.5
assert item.fixed_length_for_viewport(100) == 200
2021-03-31 07:47:24 +00:00
2021-03-30 17:04:44 +00:00
def test_resize_size_when_scaled(self):
self.view.get_scale = MagicMock(return_value=2)
self.item.setScale(2)
self.item.SELECT_RESIZE_SIZE = 100
assert self.item.select_resize_size == 25
def test_rotate_size_when_scaled(self):
self.view.get_scale = MagicMock(return_value=2)
self.item.setScale(2)
self.item.SELECT_ROTATE_SIZE = 100
assert self.item.select_rotate_size == 25
@patch('beeref.items.BeePixmapItem.draw_debug_shape')
def test_paint_when_not_selected(self, debug_mock):
2021-03-30 17:04:44 +00:00
painter = MagicMock()
self.item.setSelected(False)
self.item.pixmap = MagicMock(return_value='pixmap')
self.item.paint(painter, None, None)
painter.drawPixmap.assert_called_once_with(0, 0, 'pixmap')
painter.drawRect.assert_not_called()
painter.drawPoint.assert_not_called()
debug_mock.assert_not_called()
2021-03-30 17:04:44 +00:00
def test_paint_when_selected_single_selection(self):
painter = MagicMock()
self.item.setSelected(True)
self.item.paint(painter, None, None)
painter.drawPixmap.assert_called_once()
painter.drawRect.assert_called_once()
assert painter.drawPoint.call_count == 4
2021-03-30 17:04:44 +00:00
def test_paint_when_selected_multi_selection(self):
item2 = BeePixmapItem(QtGui.QImage())
item2.setSelected(True)
self.scene.addItem(item2)
painter = MagicMock()
self.item.setSelected(True)
self.item.paint(painter, None, None)
painter.drawPixmap.assert_called_once()
painter.drawRect.assert_called_once()
painter.drawPoint.assert_not_called()
def test_paint_when_draw_debug_shapes(self):
with patch('beeref.items.commandline_args') as args_mock:
with patch('beeref.items.BeePixmapItem.draw_debug_shape') as m:
args_mock.draw_debug_shapes = True
item = BeePixmapItem(QtGui.QImage())
item.paint(MagicMock(), None, None)
m.assert_called()
2021-04-01 14:31:43 +00:00
def test_corners(self):
assert set(self.item.corners) == set((
(0, 0),
(100, 0),
(0, 80),
(100, 80)))
def test_get_scale_bounds(self):
2021-03-30 17:04:44 +00:00
self.view.get_scale = MagicMock(return_value=1)
self.item.SELECT_RESIZE_SIZE = 10
2021-04-01 14:31:43 +00:00
rect = self.item.get_scale_bounds((100, 100))
assert rect.topLeft().x() == 95
assert rect.topLeft().y() == 95
assert rect.bottomRight().x() == 105
assert rect.bottomRight().y() == 105
2021-03-30 17:04:44 +00:00
def test_bottom_right_rotate_bounds(self):
self.view.get_scale = MagicMock(return_value=1)
self.item.SELECT_RESIZE_SIZE = 10
self.item.SELECT_ROTATE_SIZE = 10
2021-04-01 14:31:43 +00:00
rect = self.item.bottom_right_rotate_bounds
assert rect.topLeft().x() == 105
assert rect.topLeft().y() == 85
assert rect.bottomRight().x() == 115
assert rect.bottomRight().y() == 95
2021-03-30 17:04:44 +00:00
def test_bounding_rect_when_not_selected(self):
self.view.get_scale = MagicMock(return_value=1)
self.item.setSelected(False)
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.boundingRect',
return_value=QtCore.QRectF(0, 0, 100, 80)):
rect = self.item.boundingRect()
assert rect.topLeft().x() == 0
assert rect.topLeft().y() == 0
assert rect.bottomRight().x() == 100
assert rect.bottomRight().y() == 80
def test_bounding_rect_when_selected(self):
self.item.SELECT_RESIZE_SIZE = 10
self.item.SELECT_ROTATE_SIZE = 10
self.view.get_scale = MagicMock(return_value=1)
self.item.setSelected(True)
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.boundingRect',
return_value=QtCore.QRectF(0, 0, 100, 80)):
rect = self.item.boundingRect()
assert rect.topLeft().x() == -15
assert rect.topLeft().y() == -15
assert rect.bottomRight().x() == 115
assert rect.bottomRight().y() == 95
def test_shape_when_not_selected(self):
self.view.get_scale = MagicMock(return_value=1)
self.item.setSelected(False)
path = QtGui.QPainterPath()
path.addRect(QtCore.QRectF(0, 0, 100, 80))
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.shape',
return_value=path):
2021-04-01 14:31:43 +00:00
shape = self.item.shape().boundingRect()
assert shape.topLeft().x() == 0
assert shape.topLeft().y() == 0
assert shape.bottomRight().x() == 100
assert shape.bottomRight().y() == 80
2021-03-30 17:04:44 +00:00
def test_shape_when_selected(self):
self.item.SELECT_RESIZE_SIZE = 10
self.item.SELECT_ROTATE_SIZE = 10
self.view.get_scale = MagicMock(return_value=1)
self.item.setSelected(True)
path = QtGui.QPainterPath()
path.addRect(QtCore.QRectF(0, 0, 100, 80))
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.shape',
return_value=path):
2021-04-01 14:31:43 +00:00
shape = self.item.shape().boundingRect()
assert shape.topLeft().x() == -5
assert shape.topLeft().y() == -5
assert shape.bottomRight().x() == 115
assert shape.bottomRight().y() == 95
class BeePixmapItemScalingTestCase(BeePixmapItemWithViewBaseTestCase):
def test_get_scale_delta_bottomright(self):
self.item.scale_start = QtCore.QPoint(10, 10)
event = MagicMock()
event.scenePos = MagicMock(return_value=QtCore.QPoint(20, 90))
assert self.item.get_scale_delta(event, (100, 80)) == 0.5
def test_get_scale_delta_topleft(self):
self.item.scale_start = QtCore.QPoint(10, 10)
event = MagicMock()
event.scenePos = MagicMock(return_value=QtCore.QPoint(-10, -60))
assert self.item.get_scale_delta(event, (0, 0)) == 0.5
def test_get_scale_anchor_topleft(self):
assert self.item.get_scale_anchor((0, 0)) == (100, 80)
def test_get_scale_anchor_bottomright(self):
assert self.item.get_scale_anchor((100, 80)) == (0, 0)
def test_get_scale_anchor_topright(self):
assert self.item.get_scale_anchor((100, 0)) == (0, 80)
def test_get_scale_anchor_bottomleft(self):
assert self.item.get_scale_anchor((0, 80)) == (100, 0)
def test_get_scale_direction_topleft(self):
assert self.item.get_scale_direction((0, 0)) == (-1, -1)
def test_get_scale_direction_bottomright(self):
assert self.item.get_scale_direction((100, 80)) == (1, 1)
def test_get_scale_direction_topright(self):
assert self.item.get_scale_direction((100, 0)) == (1, -1)
def test_get_scale_direction_bottomleft(self):
assert self.item.get_scale_direction((0, 80)) == (-1, 1)
def test_translate_for_scale_anchor(self):
pos = QtCore.QPoint(50, 70)
self.item.translate_for_scale_anchor(pos, 2, (100, 80))
assert self.item.pos().x() == -150
assert self.item.pos().y() == -90
class BeePixmapItemEventsstuffTestCase(BeePixmapItemWithViewBaseTestCase):
def setUp(self):
super().setUp()
self.event = MagicMock()
self.item.setCursor = MagicMock()
def test_hover_move_event_no_selection(self):
self.event.pos = MagicMock(return_value=QtCore.QPointF(0, 0))
self.item.hoverMoveEvent(self.event)
self.item.setCursor.assert_not_called()
def test_hover_move_event_topleft_scale(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(0, 0))
self.item.hoverMoveEvent(self.event)
self.item.setCursor.assert_called_once_with(
Qt.CursorShape.SizeFDiagCursor)
def test_hover_move_event_bottomright_scale(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(100, 80))
self.item.hoverMoveEvent(self.event)
self.item.setCursor.assert_called_once_with(
Qt.CursorShape.SizeFDiagCursor)
def test_hover_move_event_topright_scale(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(100, 0))
self.item.hoverMoveEvent(self.event)
self.item.setCursor.assert_called_once_with(
Qt.CursorShape.SizeBDiagCursor)
def test_hover_move_event_not_in_handles(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(50, 50))
self.item.hoverMoveEvent(self.event)
self.item.setCursor.assert_called_once_with(
Qt.CursorShape.ArrowCursor)
def test_hover_enter_event_when_selected(self):
self.item.setSelected(True)
self.item.hoverEnterEvent(self.event)
self.item.setCursor.assert_not_called()
def test_hover_enter_event_when_not_selected(self):
self.item.setSelected(False)
self.item.hoverEnterEvent(self.event)
self.item.setCursor.assert_called_once_with(
Qt.CursorShape.ArrowCursor)
def test_mouse_press_event_topleft_scale(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(2, 2))
self.event.scenePos = MagicMock(return_value=QtCore.QPointF(66, 99))
self.event.button = MagicMock(
return_value=Qt.MouseButtons.LeftButton)
self.item.mousePressEvent(self.event)
assert self.item.scale_active_corner == (0, 0)
assert self.item.scale_start == QtCore.QPointF(66, 99)
assert self.item.scale_orig_factor == 1
assert self.item.scale_orig_pos == QtCore.QPointF(0, 0)
def test_mouse_press_event_bottomright_scale(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(99, 79))
self.event.scenePos = MagicMock(return_value=QtCore.QPointF(66, 99))
self.event.button = MagicMock(
return_value=Qt.MouseButtons.LeftButton)
self.item.mousePressEvent(self.event)
assert self.item.scale_active_corner == (100, 80)
assert self.item.scale_start == QtCore.QPointF(66, 99)
assert self.item.scale_orig_factor == 1
assert self.item.scale_orig_pos == QtCore.QPointF(0, 0)
def test_mouse_press_event_not_selected(self):
self.item.setSelected(False)
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.mousePressEvent') as m:
self.item.mousePressEvent(self.event)
m.assert_called_once_with(self.event)
assert self.item.scale_active_corner is None
def test_mouse_press_not_in_handles(self):
self.item.setSelected(True)
self.event.pos = MagicMock(return_value=QtCore.QPointF(50, 40))
self.event.button = MagicMock(
return_value=Qt.MouseButtons.LeftButton)
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.mousePressEvent') as m:
self.item.mousePressEvent(self.event)
m.assert_called_once_with(self.event)
assert self.item.scale_active_corner is None
def test_mouse_move_event_when_no_action(self):
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem.mouseMoveEvent') as m:
self.item.mouseMoveEvent(self.event)
m.assert_called_once_with(self.event)
def test_move_event_when_scale_action(self):
self.event.scenePos = MagicMock(return_value=QtCore.QPointF(20, 90))
self.item.scale_active_corner = (100, 80)
self.item.scale_start = QtCore.QPointF(10, 10)
self.item.scale_orig_factor = 1
self.item.scale_orig_pos = QtCore.QPointF(0, 0)
self.item.mouseMoveEvent(self.event)
assert self.item.scale() == 1.5
def test_mouse_release_event_when_no_action(self):
with patch('PyQt6.QtWidgets.QGraphicsPixmapItem'
'.mouseReleaseEvent') as m:
self.item.mouseReleaseEvent(self.event)
m.assert_called_once_with(self.event)
def test_mouse_release_event_when_scale_action(self):
self.event.scenePos = MagicMock(return_value=QtCore.QPointF(20, 90))
self.item.scale_active_corner = (100, 80)
self.item.scale_start = QtCore.QPointF(10, 10)
self.item.scale_orig_factor = 1
self.item.scale_orig_pos = QtCore.QPointF(0, 0)
self.scene.undo_stack = MagicMock()
self.scene.undo_stack.push = MagicMock()
self.item.mouseReleaseEvent(self.event)
self.scene.undo_stack.push.assert_called_once()
args = self.scene.undo_stack.push.call_args_list[0][0]
cmd = args[0]
assert cmd.items == [self.item]
assert cmd.delta == 0.5
assert cmd.anchor == (0, 0)
assert cmd.ignore_first_redo is True
assert self.item.scale_active_corner is None