Skip to content

Commit

Permalink
WIP test_multicursor
Browse files Browse the repository at this point in the history
  • Loading branch information
athompson673 authored Dec 20, 2024
1 parent 2d5ba23 commit 3dea758
Showing 1 changed file with 143 additions and 36 deletions.
179 changes: 143 additions & 36 deletions spyder/plugins/editor/widgets/codeeditor/tests/test_multicursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

def click_at(codeeditor, qtbot, position, ctrl=False, alt=False, shift=False):
x, y = codeeditor.get_coordinates(position)
point = codeeditor.calculate_real_position(QPoint(x, y))
point = QPoint(x, y)

modifiers = Qt.KeyboardModifier.NoModifier
Expand All @@ -26,45 +25,47 @@ def click_at(codeeditor, qtbot, position, ctrl=False, alt=False, shift=False):
modifiers |= Qt.KeyboardModifier.AltModifier
if shift:
modifiers |= Qt.KeyboardModifier.ShiftModifier

qtbot.mouseClick(
codeeditor.viewport(),
Qt.MouseButton.LeftButton,
modifiers,
pos=point
)
qtbot.mouseClick(codeeditor.viewport(),
Qt.MouseButton.LeftButton,
modifiers,
pos=point)


def test_add_cursor(codeeditor, qtbot):
# Enabled by default arg on CodeEditor.setup_editor (which is called in the
# pytest fixture creation in conftest.py)
# enabled by default arg on CodeEditor.setup_editor (which is called in the
# pytest fixture creation in conftest.py)
assert codeeditor.multi_cursor_enabled
assert codeeditor.cursorWidth() == 0 # required for multi-cursor rendering
codeeditor.set_text("0123456789")
click_at(codeeditor, qtbot, 6, ctrl=True, alt=True)

# A cursor was added
assert bool(codeeditor.extra_cursors)
qtbot.keyClick(codeeditor, "a")

# Text was inserted correctly from two cursors
assert codeeditor.toPlainText() == "a012345a6789"

# Regular click to set main cursor and clear extra cursors
# regular click to set main cursor and clear extra cursors
click_at(codeeditor, qtbot, 6)
assert not bool(codeeditor.extra_cursors)
qtbot.keyClick(codeeditor, "b")
assert codeeditor.toPlainText() == "a01234b5a6789"
# don't add another cursor on top of main cursor
click_at(codeeditor, qtbot, 7, ctrl=True, alt=True)
assert not bool(codeeditor.extra_cursors)

# test removing cursors
click_at(codeeditor, qtbot, 2, ctrl=True, alt=True)
# remove main cursor
click_at(codeeditor, qtbot, 2, ctrl=True, alt=True)
assert codeeditor.textCursor().position() == 7


def test_column_add_cursor(codeeditor, qtbot):
codeeditor.set_text("0123456789\n0123456789\n0123456789\n0123456789\n")
cursor = codeeditor.textCursor()
cursor.movePosition(
QTextCursor.MoveOperation.Down,
QTextCursor.MoveMode.MoveAnchor,
3
)
cursor.movePosition(QTextCursor.MoveOperation.Down,
QTextCursor.MoveMode.MoveAnchor,
3)
codeeditor.setTextCursor(cursor)
click_at(codeeditor, qtbot, 6, ctrl=True, alt=True, shift=True)

Expand All @@ -79,31 +80,25 @@ def test_settings_toggle(codeeditor, qtbot):
assert codeeditor.cursorWidth() == 0 # required for multi-cursor rendering
codeeditor.set_text("0123456789\n0123456789\n")
click_at(codeeditor, qtbot, 6, ctrl=True, alt=True)

# A cursor was added
assert bool(codeeditor.extra_cursors)
codeeditor.toggle_multi_cursor(False)

# Extra cursors removed on settings toggle
assert not bool(codeeditor.extra_cursors)
click_at(codeeditor, qtbot, 3, ctrl=True, alt=True)

# Extra cursors not added wnen settings "multi-cursor enabled" is False
assert not bool(codeeditor.extra_cursors)
click_at(codeeditor, qtbot, 13, ctrl=True, alt=True, shift=True)

# Column cursors not added wnen settings "multi-cursor enabled" is False
assert not bool(codeeditor.extra_cursors)


def test_extra_selections_decoration(codeeditor, qtbot):
codeeditor.set_text("0123456789\n0123456789\n0123456789\n0123456789\n")
cursor = codeeditor.textCursor()
cursor.movePosition(
QTextCursor.MoveOperation.Down,
QTextCursor.MoveMode.MoveAnchor,
3 # column 0 row 4
)
cursor.movePosition(QTextCursor.MoveOperation.Down,
QTextCursor.MoveMode.MoveAnchor,
3) # column 0 row 4
codeeditor.setTextCursor(cursor)
click_at(codeeditor, qtbot, 6, ctrl=True, alt=True, shift=True)
selections = codeeditor.get_extra_selections("extra_cursor_selections")
Expand Down Expand Up @@ -148,15 +143,128 @@ def test_overwrite_mode(codeeditor, qtbot):
assert codeeditor.toPlainText() == "0123abc6789\n01234bc6789\n"

# TODO test folded code
# extra cursor movement (skip past hidden blocks)
# typing on a folded line (should be read-only)
# delete & backspace (& delete line shortcut) should delete folded section
# move/duplicate line up/down should unfold current and previous/next lines
# TODO test drag & drop cursor rendering
# TODO test backspace & smart backspace
# TODO test smart indent, colon insertion, matching () "" ''
# extra cursor movement (skip past hidden blocks)
# typing on a folded line (should be read-only)
# delete & backspace (& delete line shortcut) should delete folded section
# move/duplicate line up/down should unfold current and previous/next lines


# def test_drag_and_drop(codeeditor, qtbot):
# # test drag & drop cursor rendering
# codeeditor.set_text("0123456789\nabcdefghij\n")
# cursor = codeeditor.textCursor()
# cursor.movePosition(cursor.MoveOperation.NextBlock,
# cursor.MoveMode.KeepAnchor)

# assert codeeditor._drag_cursor is None
# point = QPoint(*codeeditor.get_coordinates(5))
# qtbot.mousePress(codeeditor.viewport(),
# Qt.MouseButton.LeftButton,
# pos=point)

# point = QPoint(*codeeditor.get_coordinates(22))
# # TODO not working: this doesn't generate a DragEnter event or DragMove
# # events. Why?
# qtbot.mouseMove(codeeditor.viewport(),
# pos=point)
# assert codeeditor._drag_cursor is not None
# qtbot.mouseRelease(codeeditor.viewport(),
# Qt.MouseButton.LeftButton,
# pos=point)
# assert codeeditor._drag_cursor is None
# assert codeeditor.toPlainText() == "abcdefghij\n0123456789\n"

def test_smart_text(codeeditor, qtbot):
# test smart backspace, whitespace insertion, colon insertion, and
# parenthesis/quote matching
codeeditor.set_text("def test1\n"
"def test2\n")
click_at(codeeditor, qtbot, 9)
click_at(codeeditor, qtbot, 19, ctrl=True, alt=True)
qtbot.keyClick(codeeditor, Qt.Key.Key_ParenLeft)
# closing paren was inserted?
assert codeeditor.toPlainText() == ("def test1()\n"
"def test2()\n")
qtbot.keyClick(codeeditor, Qt.Key.Key_ParenRight)
# typing close paren advances cursor without adding extra paren?
assert codeeditor.toPlainText() == ("def test1()\n"
"def test2()\n")
qtbot.keyClick(codeeditor, Qt.Key.Key_Return)
# auto colon and indent?
assert codeeditor.toPlainText() == ("def test1():\n"
" \n"
"def test2():\n"
" \n")
# add some extraneous whitespace
qtbot.keyClick(codeeditor, Qt.Key.Key_Tab)
qtbot.keyClick(codeeditor, Qt.Key.Key_Tab)
assert codeeditor.toPlainText() == ("def test1():\n"
" \n"
"def test2():\n"
" \n")
qtbot.keyClick(codeeditor, Qt.Key.Key_Backspace)
# smart backspace to correct indent?
assert codeeditor.toPlainText() == ("def test1():\n"
" \n"
"def test2():\n"
" \n")
for cursor in codeeditor.all_cursors:
cursor.insertText("return")
assert codeeditor.toPlainText() == ("def test1():\n"
" return\n"
"def test2():\n"
" return\n")
codeeditor.set_close_quotes_enabled(True)
qtbot.keyClick(codeeditor, Qt.Key.Key_Space)
qtbot.keyClick(codeeditor, Qt.Key.Key_Apostrophe)
# automatic quote
assert codeeditor.toPlainText() == ("def test1():\n"
" return ''\n"
"def test2():\n"
" return ''\n")
qtbot.keyClick(codeeditor, Qt.Key.Key_Apostrophe)
# automatic close quote
assert codeeditor.toPlainText() == ("def test1():\n"
" return ''\n"
"def test2():\n"
" return ''\n")
qtbot.keyClick(codeeditor, Qt.Key.Key_Return)
# automatic dedent?
assert codeeditor.toPlainText() == ("def test1():\n"
" return ''\n"
"\n"
"def test2():\n"
" return ''\n"
"\n")


# ---- shortcuts
# TODO test code_completion shourcut (ensure disabled)

# def test_disable_code_completion(completions_codeeditor, qtbot):
# code_editor, _ = completions_codeeditor
# code_editor.set_text("def test1():\n"
# " return\n")
# completion = code_editor.completion_widget
# delay = 50
# code_editor.toggle_code_snippets(False)

# code_editor.moveCursor(QTextCursor.MoveOperation.End)
# qtbot.keyClicks(code_editor, "tes", delay=delay)
# qtbot.wait(2000) # keyboard idle + wait for completion time
# assert not completion.isHidden()
# # TODO doesn't hide completions, why?
# qtbot.keyClick(code_editor, Qt.Key.Key_Escape)
# # TODO doesn't hide completions, why?
# click_at(code_editor, qtbot, 0)
# qtbot.wait(1000)
# click_at(code_editor, qtbot, 27, ctrl=True, alt=True)
# qtbot.keyClicks(code_editor, "t", delay=delay)
# qtbot.wait(1000) # keyboard idle + wait for completion time
# # XXX fails because first completions box is never hidden.
# assert completion.isHidden()
# # TODO test ctrl-space shortcut too


# TODO test duplicate/move line up/down
# TODO test delete line
# TODO test goto new line
Expand All @@ -182,6 +290,5 @@ def test_overwrite_mode(codeeditor, qtbot):
# TODO test run Cell (and advance)
# TODO test run selection (and advance)(from line)(in debugger)


if __name__ == '__main__':
pytest.main(['test_multicursor.py'])

0 comments on commit 3dea758

Please sign in to comment.