Skip to content

Commit

Permalink
Merge from 3.x: PR #4110
Browse files Browse the repository at this point in the history
  • Loading branch information
ccordoba12 committed Feb 10, 2017
2 parents 65bc403 + a8d5695 commit e546092
Show file tree
Hide file tree
Showing 6 changed files with 195 additions and 17 deletions.
2 changes: 1 addition & 1 deletion continuous_integration/appveyor/install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function DownloadMiniconda ($python_version, $platform_suffix) {
if ($python_version -match "3.5") {
$filename = "Miniconda3-latest-Windows-" + $platform_suffix + ".exe"
} else {
$filename = "Miniconda-latest-Windows-" + $platform_suffix + ".exe"
$filename = "Miniconda2-latest-Windows-" + $platform_suffix + ".exe"
}
$url = $MINICONDA_URL + $filename

Expand Down
4 changes: 2 additions & 2 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
#==============================================================================
# Create splash screen out of MainWindow to reduce perceived startup time.
#==============================================================================
from spyder.config.base import _, get_image_path, DEV
from spyder.config.base import _, get_image_path, DEV, PYTEST
SPLASH = QSplashScreen(QPixmap(get_image_path('splash.svg'), 'svg'))
SPLASH_FONT = SPLASH.font()
SPLASH_FONT.setPixelSize(10)
Expand Down Expand Up @@ -2925,7 +2925,7 @@ def run_spyder(app, options, args):
# the window
app.focusChanged.connect(main.change_last_focused_widget)

if not os.environ.get('SPYDER_PYTEST', None):
if not PYTEST:
app.exec_()
return main

Expand Down
10 changes: 10 additions & 0 deletions spyder/app/tests/script.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#%%
a = 10


#%%
li = [1, 2, 3]

#%%
import numpy as np
arr = np.array(li)
169 changes: 162 additions & 7 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,52 @@
Tests for the main window
"""

import os
import os.path as osp

import numpy as np
from numpy.testing import assert_array_equal
import pytest
from qtpy.QtCore import Qt
from qtpy.QtCore import Qt, QTimer
from qtpy.QtTest import QTest
from qtpy.QtWidgets import QApplication, QFileDialog, QLineEdit

from spyder.app.cli_options import get_options
from spyder.app.mainwindow import initialize, run_spyder


#==============================================================================
# Constants
#==============================================================================
LOCATION = osp.realpath(osp.join(os.getcwd(), osp.dirname(__file__)))


#==============================================================================
# Utility functions
#==============================================================================
def open_file_in_editor(main_window, fname, directory=None):
"""Open a file using the Editor and its open file dialog"""
top_level_widgets = QApplication.topLevelWidgets()
for w in top_level_widgets:
if isinstance(w, QFileDialog):
if directory is not None:
w.setDirectory(directory)
input_field = w.findChildren(QLineEdit)[0]
input_field.setText(fname)
QTest.keyClick(w, Qt.Key_Enter)


def reset_run_code(qtbot, shell, code_editor, nsb):
"""Reset state after a run code test"""
shell.execute('%reset -f')
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=1500)
code_editor.setFocus()
qtbot.keyClick(code_editor, Qt.Key_Home, modifier=Qt.ControlModifier)


#==============================================================================
# Fixtures
#==============================================================================
@pytest.fixture
def main_window():
app = initialize()
Expand All @@ -23,11 +62,125 @@ def main_window():
return widget


#==============================================================================
# Tests
#==============================================================================
def test_run_code(main_window, qtbot):
"""Test all the different ways we have to run code"""
# ---- Setup ----
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000)

# Load test file
main_window.editor.load(osp.join(LOCATION, 'script.py'))

# Move to the editor's first line
code_editor = main_window.editor.get_focus_widget()
code_editor.setFocus()
qtbot.keyClick(code_editor, Qt.Key_Home, modifier=Qt.ControlModifier)

# Get a reference to the namespace browser widget
nsb = main_window.variableexplorer.get_focus_widget()

# ---- Run file ----
qtbot.keyClick(code_editor, Qt.Key_F5)

# Wait until all objects have appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500)

# Verify result
assert shell.get_value('a') == 10
assert shell.get_value('li') == [1, 2, 3]
assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run lines ----
# Run the whole file line by line
for _ in range(code_editor.blockCount()):
qtbot.keyClick(code_editor, Qt.Key_F9)
qtbot.wait(100)

# Wait until all objects have appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500)

# Verify result
assert shell.get_value('a') == 10
assert shell.get_value('li') == [1, 2, 3]
assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run cell and advance ----
# Run the three cells present in file
for _ in range(3):
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ShiftModifier)
qtbot.wait(100)

# Wait until all objects have appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 3, timeout=1500)

# Verify result
assert shell.get_value('a') == 10
assert shell.get_value('li') == [1, 2, 3]
assert_array_equal(shell.get_value('arr'), np.array([1, 2, 3]))

reset_run_code(qtbot, shell, code_editor, nsb)

# ---- Run cell ----
# Run the first cell in file
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ControlModifier)

# Wait until the object has appeared in the variable explorer
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 1, timeout=1500)

# Verify result
assert shell.get_value('a') == 10

# Press Ctrl+Enter a second time to verify that we're *not* advancing
# to the next cell
qtbot.keyClick(code_editor, Qt.Key_Return, modifier=Qt.ControlModifier)
assert nsb.editor.model.rowCount() == 1

main_window.close()


@pytest.mark.skipif(os.name == 'nt', reason="It's timing out sometimes on Windows")
def test_open_files_in_new_editor_window(main_window, qtbot):
"""
This tests that opening files in a new editor window
is working as expected.
Test for issue 4085
"""
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000)

# Set a timer to manipulate the open dialog while it's running
QTimer.singleShot(2000, lambda: open_file_in_editor(main_window,
'script.py',
directory=LOCATION))

# Create a new editor window
# Note: editor.load() uses the current editorstack by default
main_window.editor.create_new_window()
main_window.editor.load()

# Perform the test
# Note: There's always one file open in the Editor
editorstack = main_window.editor.get_current_editorstack()
assert editorstack.get_stack_count() == 2

main_window.close()


def test_maximize_minimize_plugins(main_window, qtbot):
"""Test that the maximize button is working correctly."""
# Wait until the window is fully up
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=6000)
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000)

# Set focus to the Editor
main_window.editor.get_focus_widget().setFocus()
Expand All @@ -44,6 +197,8 @@ def test_maximize_minimize_plugins(main_window, qtbot):
qtbot.mouseClick(max_button, Qt.LeftButton)
assert not main_window.editor.ismaximized

main_window.close()


def test_issue_4066(main_window, qtbot):
"""
Expand All @@ -56,12 +211,12 @@ def test_issue_4066(main_window, qtbot):
"""
# Create the object
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=6000)
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000)
shell.execute('myobj = [1, 2, 3]')

# Open editor associated with that object and get a reference to it
nsb = main_window.variableexplorer.get_focus_widget()
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=500)
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=1500)
nsb.editor.setFocus()
nsb.editor.edit_item()
obj_editor_id = list(nsb.editor.delegate._editors.keys())[0]
Expand All @@ -70,7 +225,7 @@ def test_issue_4066(main_window, qtbot):
# Move to the IPython console and delete that object
main_window.ipyconsole.get_focus_widget().setFocus()
shell.execute('del myobj')
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=500)
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() == 0, timeout=1500)

# Close editor
ok_widget = obj_editor.bbox.button(obj_editor.bbox.Ok)
Expand All @@ -88,13 +243,13 @@ def test_varexp_edit_inline(main_window, qtbot):
"""
# Create object
shell = main_window.ipyconsole.get_current_shellwidget()
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=6000)
qtbot.waitUntil(lambda: shell._prompt_html is not None, timeout=15000)
shell.execute('a = 10')

# Edit object
main_window.variableexplorer.visibility_changed(True)
nsb = main_window.variableexplorer.get_focus_widget()
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=500)
qtbot.waitUntil(lambda: nsb.editor.model.rowCount() > 0, timeout=1500)
nsb.editor.setFocus()
nsb.editor.edit_item()

Expand Down
5 changes: 5 additions & 0 deletions spyder/config/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
TEST = os.environ.get('SPYDER_TEST')


# To do some adjustments for pytest
# This env var is defined in runtests.py
PYTEST = os.environ.get('SPYDER_PYTEST')


#==============================================================================
# Debug helpers
#==============================================================================
Expand Down
22 changes: 15 additions & 7 deletions spyder/plugins/editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
QToolBar, QVBoxLayout, QWidget)

# Local imports
from spyder.config.base import _, get_conf_path
from spyder.config.base import _, get_conf_path, PYTEST
from spyder.config.main import (CONF, RUN_CELL_SHORTCUT,
RUN_CELL_AND_ADVANCE_SHORTCUT)
from spyder.config.utils import (get_edit_filetypes, get_edit_filters,
Expand Down Expand Up @@ -1815,11 +1815,19 @@ def load(self, filenames=None, goto=None, word='', editorwindow=None,
osp.splitext(filename0)[1])
else:
selectedfilter = ''
filenames, _sf = getopenfilenames(parent_widget,
_("Open file"), basedir,
self.edit_filters,
selectedfilter=selectedfilter,
options=QFileDialog.HideNameFilterDetails)
if not PYTEST:
filenames, _sf = getopenfilenames(
parent_widget,
_("Open file"), basedir,
self.edit_filters,
selectedfilter=selectedfilter,
options=QFileDialog.HideNameFilterDetails)
else:
# Use a Qt (i.e. scriptable) dialog for pytest
dialog = QFileDialog(parent_widget, _("Open file"),
options=QFileDialog.DontUseNativeDialog)
if dialog.exec_():
filenames = dialog.selectedFiles()
self.redirect_stdio.emit(True)
if filenames:
filenames = [osp.normpath(fname) for fname in filenames]
Expand Down Expand Up @@ -2318,7 +2326,7 @@ def run_file(self, debug=False):
if self.dialog_size is not None:
dialog.resize(self.dialog_size)
dialog.setup(fname)
if CONF.get('run', 'open_at_least_once', True):
if CONF.get('run', 'open_at_least_once', not PYTEST):
# Open Run Config dialog at least once: the first time
# a script is ever run in Spyder, so that the user may
# see it at least once and be conscious that it exists
Expand Down

0 comments on commit e546092

Please sign in to comment.