Skip to content

Commit

Permalink
Merge pull request spyder-ide#3324 from jitseniesen/run-line
Browse files Browse the repository at this point in the history
Make 'run line' add a blank line if on last line.
  • Loading branch information
ccordoba12 authored Jul 29, 2016
2 parents 5eab83e + 101abfa commit a3f0644
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 18 deletions.
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ test_script:
- "%CMD_IN_ENV% %APPVEYOR_BUILD_FOLDER%\\continuous_integration\\appveyor\\build_test.bat"
- "%CMD_IN_ENV% %APPVEYOR_BUILD_FOLDER%\\continuous_integration\\appveyor\\run_test.bat"
- "%CMD_IN_ENV% %APPVEYOR_BUILD_FOLDER%\\continuous_integration\\appveyor\\modules_test.bat"
- cd %APPVEYOR_BUILD_FOLDER% & python runtests.py
2 changes: 1 addition & 1 deletion continuous_integration/appveyor/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ function UpdateConda ($python_home) {
function main () {
InstallMiniconda $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON
UpdateConda $env:PYTHON
InstallCondaPackages $env:PYTHON "conda-build==1.21.0 pytest pytest-cov pytest-qt"
InstallCondaPackages $env:PYTHON "conda-build==1.21.0 pytest pytest-cov pytest-qt mock"
}


Expand Down
4 changes: 2 additions & 2 deletions continuous_integration/travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ install_conda()
echo 'conda-build ==1.18.1' > $HOME/miniconda/conda-meta/pinned;
conda install conda-build;
conda create -q -n test-environment python=$PY_VERSION;
conda install -q -y -n test-environment pytest pytest-cov pytest-qt
conda install -q -y -n test-environment pytest pytest-cov pytest-qt mock
fi
}

Expand All @@ -70,7 +70,7 @@ install_pip()
fi

# Install testing packages
pip install pytest pytest-cov pytest-qt
pip install pytest pytest-cov pytest-qt mock

# Install extra packages
EXTRA_PACKAGES="matplotlib pandas sympy pyzmq pillow"
Expand Down
11 changes: 7 additions & 4 deletions runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,21 @@
File for running tests programmatically.
"""

# Standard library imports
import sys

# Third party imports
import qtpy
import qtpy # to ensure that Qt4 uses API v2
import pytest


def main():
"""
Run pytest tests.
"""
pytest.main(['-x', 'spyderlib', '-v', '-rw', '--durations=10',
'--cov=spyderlib', '--cov-report=term-missing'])

errno = pytest.main(['-x', 'spyderlib', '-v', '-rw', '--durations=10',
'--cov=spyderlib', '--cov-report=term-missing'])
sys.exit(errno)

if __name__ == '__main__':
main()
3 changes: 3 additions & 0 deletions spyderlib/utils/tests/test_programs.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

"""Tests for programs.py"""

import os
import time

import pytest

from spyderlib.utils.programs import run_python_script_in_terminal

@pytest.mark.skipif(os.name == 'nt', reason='gets stuck on Windows') # FIXME
def test_run_python_script_in_terminal(tmpdir):
scriptpath = tmpdir.join('write-done.py')
outfilepath = tmpdir.join('out.txt')
Expand All @@ -23,6 +25,7 @@ def test_run_python_script_in_terminal(tmpdir):
res = outfilepath.read()
assert res == 'done'

@pytest.mark.skipif(os.name == 'nt', reason='gets stuck on Windows') # FIXME
def test_run_python_script_in_terminal_with_wdir_empty(tmpdir):
scriptpath = tmpdir.join('write-done.py')
outfilepath = tmpdir.join('out.txt')
Expand Down
30 changes: 19 additions & 11 deletions spyderlib/widgets/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1817,20 +1817,28 @@ def fix_indentation(self, index=None):
#------ Run
def run_selection(self):
"""
Run selected text or current line in console. If no text is selected,
then advance cursor to next line.
Run selected text or current line in console.
If some text is selected, then execute that text in console.
If no text is selected, then execute current line, unless current line
is empty. Then, advance cursor to next line. If cursor is on last line
and that line is not empty, then add a new blank line and move the
cursor there. If cursor is on last line and that line is empty, then do
not move cursor.
"""
text = self.get_current_editor().get_selection_as_executable_code()
if text:
move_next_line = False
else:
editor = self.get_current_editor()
line = editor.get_current_line()
text = line.lstrip()
move_next_line = True
self.exec_in_extconsole.emit(text, self.focus_to_editor)
if move_next_line:
editor.move_cursor_to_next('line', 'down')
self.exec_in_extconsole.emit(text, self.focus_to_editor)
return
editor = self.get_current_editor()
line = editor.get_current_line()
text = line.lstrip()
if text:
self.exec_in_extconsole.emit(text, self.focus_to_editor)
if editor.is_cursor_on_last_line() and text:
editor.append(editor.get_line_separator())
editor.move_cursor_to_next('line', 'down')

def run_cell(self):
"""Run current cell"""
Expand Down
89 changes: 89 additions & 0 deletions spyderlib/widgets/tests/test_editor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
#
# Copyright © 2016- The Spyder Development Team
# Licensed under the terms of the MIT License
#

"""
Tests for editor.py
"""

# Standard library imports
try:
from unittest.mock import Mock
except ImportError:
from mock import Mock # Python 2

# Third party imports
import pytest

# Local imports
from spyderlib.widgets.editor import EditorStack

def setup_editor(qtbot):
"""
Set up EditorStack with CodeEditor containing some Python code.
The cursor is at the empty line below the code.
Returns tuple with EditorStack and CodeEditor.
"""
text = ('a = 1\n'
'print(a)\n'
'\n'
'x = 2') # a newline is added at end
editorStack = EditorStack(None, [])
editorStack.set_introspector(Mock())
editorStack.set_find_widget(Mock())
editorStack.set_io_actions(Mock(), Mock(), Mock(), Mock())
finfo = editorStack.new('foo.py', 'utf-8', text)
qtbot.addWidget(editorStack)
return editorStack, finfo.editor

def test_run_top_line(qtbot):
editorStack, editor = setup_editor(qtbot)
editor.go_to_line(1) # line number is one based
editor.move_cursor(3)
with qtbot.waitSignal(editorStack.exec_in_extconsole) as blocker:
editorStack.run_selection()
assert blocker.signal_triggered
assert blocker.args[0] == 'a = 1'
# check cursor moves to start of next line; note line number is zero based
assert editor.get_cursor_line_column() == (1, 0)

def test_run_last_nonempty_line(qtbot):
editorStack, editor = setup_editor(qtbot)
editor.go_to_line(4)
with qtbot.waitSignal(editorStack.exec_in_extconsole) as blocker:
editorStack.run_selection()
assert blocker.signal_triggered
assert blocker.args[0] == 'x = 2'
assert editor.get_cursor_line_column() == (4, 0) # check cursor moves down

def test_run_empty_line_in_middle(qtbot):
editorStack, editor = setup_editor(qtbot)
editor.go_to_line(3)
with qtbot.assertNotEmitted(editorStack.exec_in_extconsole):
editorStack.run_selection()
assert editor.get_cursor_line_column() == (3, 0) # check cursor moves down


def test_run_last_line_when_empty(qtbot):
editorStack, editor = setup_editor(qtbot)
with qtbot.assertNotEmitted(editorStack.exec_in_extconsole):
editorStack.run_selection()
assert editor.get_cursor_line_column() == (4, 0) # check cursor doesn't move

def test_run_last_line_when_nonempty(qtbot):
editorStack, editor = setup_editor(qtbot)
editor.stdkey_backspace() # delete empty line at end
old_text = editor.toPlainText()
with qtbot.waitSignal(editorStack.exec_in_extconsole) as blocker:
editorStack.run_selection()
assert blocker.signal_triggered
assert blocker.args[0] == 'x = 2'
expected_new_text = old_text + editor.get_line_separator()
assert editor.toPlainText() == expected_new_text # check blank line got added
assert editor.get_cursor_line_column() == (4, 0) # check cursor moves down


if __name__ == "__main__":
pytest.main()

0 comments on commit a3f0644

Please sign in to comment.