Skip to content

Commit

Permalink
Merge pull request #43 from dalthviz/fixes_issue_41
Browse files Browse the repository at this point in the history
PR: Add a minimal test
  • Loading branch information
ccordoba12 authored Mar 26, 2017
2 parents 08bad92 + 98aa583 commit c7bc357
Show file tree
Hide file tree
Showing 11 changed files with 216 additions and 121 deletions.
42 changes: 8 additions & 34 deletions .ciocheck
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
branch = origin/master
diff_mode = commited
file_mode = all
check = pep8
check = pep8,pydocstyle
enforce = pep8,pydocstyle

# Python (pyformat)
add_copyright = true
Expand All @@ -18,25 +19,25 @@ add_init = true
# http://pep8.readthedocs.io/en/latest/intro.html#configuration
# -----------------------------------------------------------------------------
[pep8]
exclude = */tests/*,*/external/*
ignore = E126,
exclude = */tests/*
ignore = E126, E402,
max-line-length = 79

# -----------------------------------------------------------------------------
# pydocstyle
# http://www.pydocstyle.org/en/latest/usage.html#example
# -----------------------------------------------------------------------------
[pydocstyle]
add-ignore = D203
add-ignore = D203, D400
inherit = false

# -----------------------------------------------------------------------------
# Flake 8
# http://flake8.readthedocs.io/en/latest/config.html
# -----------------------------------------------------------------------------
[flake8]
exclude = */tests/*,
ignore = E126,
exclude = */tests/*
ignore = E126, E402,
max-line-length = 79
max-complexity = 64

Expand Down Expand Up @@ -76,33 +77,6 @@ spaces_before_comment = 2
# http://pep8.readthedocs.io/en/latest/intro.html#configuration
# -----------------------------------------------------------------------------
[autopep8]
exclude =
*/tests/*
exclude = */tests/*
ignore = E126,
max-line-length = 79

# -----------------------------------------------------------------------------
# Coverage
# http://coverage.readthedocs.io/en/latest/config.html
# -----------------------------------------------------------------------------
[coverage:run]
omit =
*/tests/*
*/build/*

[coverage:report]
fail_under = 0
show_missing = true
skip_covered = true
exclude_lines =
pragma: no cover
def test():
if __name__ == .__main__.:

# -----------------------------------------------------------------------------
# pytest
# http://doc.pytest.org/en/latest/usage.html
# -----------------------------------------------------------------------------
[pytest]
addopts = -rfew --durations=10
python_functions = test_*
5 changes: 5 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[run]
omit = */tests/*

[report]
fail_under=0
64 changes: 33 additions & 31 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,45 @@
machine:
environment:
# Python versions to tests (Maximum of 4 different versions)
PY_VERSIONS: "3.5 3.4 2.7"

# Conda variables and aliases for commands
CMD_TEST_CIOCHECK: /home/ubuntu/miniconda/envs/test/bin/ciocheck
CMD_TEST_COVERALLS: /home/ubuntu/miniconda/envs/test/bin/coveralls
CMD_TEST_PIP: /home/ubuntu/miniconda/envs/test/bin/pip
CMD_TEST_PYTHON: /home/ubuntu/miniconda/envs/test/bin/python
MINICONDA: /home/ubuntu/miniconda
PATH: /home/ubuntu/miniconda/bin:$PATH
# The last container is used to test with pyqt5 wheels
PY_VERSIONS: "2.7 3.6 3.5"
# For Coveralls
COVERALLS_REPO_TOKEN: Kr503QwklmJYKXYRXLywrtw8zbX7K8SKx
# Environment variables used by astropy helpers
TRAVIS_OS_NAME: "linux"
CONDA_DEPENDENCIES_FLAGS: "--quiet"
CONDA_DEPENDENCIES: "pytest pytest-cov"
PIP_DEPENDENCIES: "coveralls pytest-qt pytest-xvfb"

dependencies:
pre:
# We need to run a window manager to avoid focus problems when running our tests.
# See https://github.com/TestFX/TestFX/issues/158#issuecomment-62421691
- sudo apt-get install matchbox-window-manager
override:
# Conda install
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
- bash Miniconda3-latest-Linux-x86_64.sh -b -p $MINICONDA
- conda config --set always_yes True

# Environment for tests
# First convert PY_VERSIONS to an array and then select the python version based on the CIRCLE_NODE_INDEX
- export PY_VERSIONS=($PY_VERSIONS) &&
export PYTHON_VERSION=${PY_VERSIONS[$CIRCLE_NODE_INDEX]} &&
echo -e "PYTHON = $PYTHON_VERSION \n============" &&
conda create -n test python=$PYTHON_VERSION -q;
#- conda install -n test --file requirements.txt -q
- "$CMD_TEST_PIP install coveralls"

# Install python module
#- $CMD_TEST_PYTHON setup.py develop > /dev/null;

# Environment for lint checks
- conda install -n test ciocheck -c spyder-ide -q --no-update-deps
export TRAVIS_PYTHON_VERSION=${PY_VERSIONS[$CIRCLE_NODE_INDEX]} &&
echo -e "PYTHON = $TRAVIS_PYTHON_VERSION \n============" &&
git clone git://github.com/astropy/ci-helpers.git > /dev/null &&
source ci-helpers/travis/setup_conda_$TRAVIS_OS_NAME.sh &&
export PATH="$HOME/miniconda/bin:$PATH" &&
source activate test &&
conda install -q ciocheck -c spyder-ide --no-update-deps &&
if [ "$CIRCLE_NODE_INDEX" = "2" ]; then pip install -q pyqt5 spyder notebook; else conda install -q spyder notebook; fi &&
python setup.py install > /dev/null;
- DISPLAY=:99 /usr/bin/matchbox-window-manager:
background: true
- sleep 5

test:
override:
# Check Python style
- $CMD_TEST_CIOCHECK spyder_notebook -dt: # note the colon
# Style checks
- export PATH="$HOME/miniconda/bin:$PATH" && source activate test && ciocheck spyder_notebook: # note the colon
parallel: true

# Run Python tests
- $CMD_TEST_CIOCHECK spyder_notebook -dl -df: # note the colon
# Tests
- export PATH="$HOME/miniconda/bin:$PATH" && source activate test && python runtests.py: # note the colon
parallel: true
# Coveralls
- export PATH="$HOME/miniconda/bin:$PATH" && source activate test && coveralls: # note the colon
parallel: true
30 changes: 30 additions & 0 deletions runtests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
#
# Copyright © Spyder Project Contributors
# Licensed under the terms of the MIT License
#

"""
File for running tests programmatically.
"""

# Third party imports
import pytest


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

# sys.exit doesn't work here because some things could be running
# in the background (e.g. closing the main window) when this point
# is reached. And if that's the case, sys.exit does't stop the
# script (as you would expected).
if errno != 0:
raise SystemExit(errno)

if __name__ == '__main__':
main()
2 changes: 1 addition & 1 deletion spyder_notebook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"""Spyder Notebook plugin."""

# Local imports
from .notebookplugin import NotebookPlugin as PLUGIN_CLASS
from spyder_notebook.notebookplugin import NotebookPlugin as PLUGIN_CLASS

VERSION_INFO = (0, 1, 0, 'dev0')
__version__ = '.'.join(map(str, VERSION_INFO))
Expand Down
61 changes: 31 additions & 30 deletions spyder_notebook/notebookplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
# Copyright (c) Spyder Project Contributors
# Licensed under the terms of the MIT License

"""
Jupyter Notebook plugin
"""
"""Jupyter Notebook plugin."""

# Stdlib imports
import os.path as osp
Expand Down Expand Up @@ -46,6 +44,7 @@ class NotebookPlugin(SpyderPluginWidget):
focus_changed = Signal()

def __init__(self, parent):
"""Constructor."""
SpyderPluginWidget.__init__(self, parent)

self.tabwidget = None
Expand Down Expand Up @@ -89,44 +88,41 @@ def __init__(self, parent):
layout.addWidget(self.tabwidget)
self.setLayout(layout)

#------ SpyderPluginMixin API ---------------------------------------------
# ------ SpyderPluginMixin API --------------------------------------------
def on_first_registration(self):
"""Action to be performed on first plugin registration"""
"""Action to be performed on first plugin registration."""
self.main.tabify_plugins(self.main.editor, self)

def update_font(self):
"""Update font from Preferences"""
"""Update font from Preferences."""
# For now we're passing. We need to create an nbextension for
# this.
pass

#------ SpyderPluginWidget API --------------------------------------------
# ------ SpyderPluginWidget API -------------------------------------------
def get_plugin_title(self):
"""Return widget title"""
"""Return widget title."""
title = _('Jupyter Notebook')
return title

def get_plugin_icon(self):
"""Return widget icon"""
"""Return widget icon."""
return ima.icon('ipython_console')

def get_focus_widget(self):
"""
Return the widget to give focus to when
this plugin's dockwidget is raised on top-level
"""
"""Return the widget to give focus to."""
client = self.tabwidget.currentWidget()
if client is not None:
return client.notebookwidget

def closing_plugin(self, cancelable=False):
"""Perform actions before parent main window is closed"""
"""Perform actions before parent main window is closed."""
for cl in self.clients:
cl.close()
return True

def refresh_plugin(self):
"""Refresh tabwidget"""
"""Refresh tabwidget."""
nb = None
if self.tabwidget.count():
client = self.tabwidget.currentWidget()
Expand All @@ -136,7 +132,7 @@ def refresh_plugin(self):
nb = None

def get_plugin_actions(self):
"""Return a list of actions related to plugin"""
"""Return a list of actions related to plugin."""
create_nb_action = create_action(self,
_("New notebook"),
icon=ima.icon('filenew'),
Expand All @@ -154,33 +150,40 @@ def get_plugin_actions(self):
return self.menu_actions

def register_plugin(self):
"""Register plugin in Spyder's main window"""
"""Register plugin in Spyder's main window."""
self.focus_changed.connect(self.main.plugin_focus_changed)
self.main.add_dockwidget(self)
self.create_new_client(give_focus=False)

#------ Public API (for clients) ------------------------------------------
# ------ Public API (for clients) -----------------------------------------
def get_clients(self):
"""Return notebooks list"""
"""Return notebooks list."""
return [cl for cl in self.clients if isinstance(cl, NotebookClient)]

def get_focus_client(self):
"""Return current notebook with focus, if any"""
"""Return current notebook with focus, if any."""
widget = QApplication.focusWidget()
for client in self.get_clients():
if widget is client or widget is client.notebookwidget:
return client

def get_current_client(self):
"""Return the currently selected notebook"""
"""Return the currently selected notebook."""
try:
client = self.tabwidget.currentWidget()
except AttributeError:
client = None
if client is not None:
return client

def get_current_nbwidget(self):
"""Return the notebookwidget of the current client."""
client = self.get_current_client()
if client is not None:
return client.notebookwidget

def get_current_client_name(self, short=False):
"""Get the current client name."""
client = self.get_current_client()
if client:
if short:
Expand All @@ -189,7 +192,7 @@ def get_current_client_name(self, short=False):
return client.get_name()

def create_new_client(self, name=None, give_focus=True):
"""Create a new notebook or load a pre-existing one"""
"""Create a new notebook or load a pre-existing one."""
# Generate the notebook name (in case of a new one)
if not name:
nb_name = 'untitled' + str(self.untitled_num) + '.ipynb'
Expand Down Expand Up @@ -218,7 +221,7 @@ def create_new_client(self, name=None, give_focus=True):
client.load_notebook()

def close_client(self, index=None, client=None):
"""Close client tab from index or widget (or close current tab)"""
"""Close client tab from index or widget (or close current tab)."""
if not self.tabwidget.count():
return
if client is not None:
Expand All @@ -237,13 +240,13 @@ def close_client(self, index=None, client=None):
self.clients.remove(client)

def save_as(self):
"""Save notebook as..."""
"""Save notebook as."""
current_client = self.get_current_client()
current_client.save()
original_path = current_client.get_name()
original_name = osp.basename(original_path)
filename, _selfilter = getsavefilename(self, _("Save notebook"),
original_name, FILES_FILTER)
original_name, FILES_FILTER)
if filename:
nb_contents = nbformat.read(original_path, as_version=4)
nbformat.write(nb_contents, filename)
Expand All @@ -258,9 +261,9 @@ def open_notebook(self):
for filename in filenames:
self.create_new_client(name=filename)

#------ Public API (for tabs) ---------------------------------------------
# ------ Public API (for tabs) --------------------------------------------
def add_tab(self, widget):
"""Add tab"""
"""Add tab."""
self.clients.append(widget)
index = self.tabwidget.addTab(widget, widget.get_short_name())
self.tabwidget.setCurrentIndex(index)
Expand All @@ -272,8 +275,6 @@ def add_tab(self, widget):
widget.notebookwidget.setFocus()

def move_tab(self, index_from, index_to):
"""
Move tab (tabs themselves have already been moved by the tabwidget)
"""
"""Move tab."""
client = self.clients.pop(index_from)
self.clients.insert(index_to, client)
9 changes: 9 additions & 0 deletions spyder_notebook/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# -----------------------------------------------------------------------------
# Copyright (c) Spyder Project Contributors
#
# Licensed under the terms of the MIT License
# (see LICENSE.txt for details)
# -----------------------------------------------------------------------------

"""Tests."""
Loading

0 comments on commit c7bc357

Please sign in to comment.