diff --git a/IPython/html/tests/test_nbextensions.py b/IPython/html/tests/test_nbextensions.py index 65484a0..4c5a646 100644 --- a/IPython/html/tests/test_nbextensions.py +++ b/IPython/html/tests/test_nbextensions.py @@ -7,13 +7,18 @@ import glob import os import re +import sys import tarfile import zipfile -from io import BytesIO +from io import BytesIO, StringIO from os.path import basename, join as pjoin from unittest import TestCase -import IPython.testing.tools as tt +try: + from unittest import mock +except ImportError: + import mock # py2 + import IPython.testing.decorators as dec from IPython.utils import py3compat from IPython.utils.tempdir import TemporaryDirectory @@ -213,8 +218,13 @@ class TestInstallNBExtension(TestCase): self.assertEqual(new_mtime, old_mtime) def test_quiet(self): - with tt.AssertNotPrints(re.compile(r'.+')): + stdout = StringIO() + stderr = StringIO() + with mock.patch.object(sys, 'stdout', stdout), \ + mock.patch.object(sys, 'stderr', stderr): install_nbextension(self.src, verbose=0) + self.assertEqual(stdout.getvalue(), '') + self.assertEqual(stderr.getvalue(), '') def test_install_zip(self): path = pjoin(self.src, "myjsext.zip") diff --git a/IPython/html/tests/test_notebookapp.py b/IPython/html/tests/test_notebookapp.py index 088a647..8546589 100644 --- a/IPython/html/tests/test_notebookapp.py +++ b/IPython/html/tests/test_notebookapp.py @@ -1,15 +1,5 @@ """Test NotebookApp""" -#----------------------------------------------------------------------------- -# Copyright (C) 2013 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- import logging import os @@ -17,19 +7,17 @@ from tempfile import NamedTemporaryFile import nose.tools as nt +from traitlets.tests.utils import check_help_all_output + from IPython.utils.tempdir import TemporaryDirectory from IPython.utils.traitlets import TraitError -import IPython.testing.tools as tt from IPython.html import notebookapp NotebookApp = notebookapp.NotebookApp -#----------------------------------------------------------------------------- -# Test functions -#----------------------------------------------------------------------------- def test_help_output(): """ipython notebook --help-all works""" - tt.help_all_output_test('notebook') + check_help_all_output('IPython.html') def test_server_info_file(): nbapp = NotebookApp(profile='nbserver_file_test', log=logging.getLogger()) diff --git a/IPython/html/tests/test_utils.py b/IPython/html/tests/test_utils.py index 0eb6166..eba3f75 100644 --- a/IPython/html/tests/test_utils.py +++ b/IPython/html/tests/test_utils.py @@ -1,31 +1,21 @@ """Test HTML utils""" -#----------------------------------------------------------------------------- -# Copyright (C) 2013 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. import os import nose.tools as nt -import IPython.testing.tools as tt +from traitlets.tests.utils import check_help_all_output from IPython.html.utils import url_escape, url_unescape, is_hidden from IPython.utils.tempdir import TemporaryDirectory -#----------------------------------------------------------------------------- -# Test functions -#----------------------------------------------------------------------------- def test_help_output(): - """ipython notebook --help-all works""" - tt.help_all_output_test('notebook') + """jupyter notebook --help-all works""" + # FIXME: will be jupyter_notebook + check_help_all_output('IPython.html') def test_url_escape(): diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index 84f200a..467d707 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -465,23 +465,3 @@ def help_all_output_test(subcommand=''): nt.assert_in("Class parameters", out) return out, err -def assert_big_text_equal(a, b, chunk_size=80): - """assert that large strings are equal - - Zooms in on first chunk that differs, - to give better info than vanilla assertEqual for large text blobs. - """ - for i in range(0, len(a), chunk_size): - chunk_a = a[i:i + chunk_size] - chunk_b = b[i:i + chunk_size] - nt.assert_equal(chunk_a, chunk_b, "[offset: %i]\n%r != \n%r" % ( - i, chunk_a, chunk_b)) - - if len(a) > len(b): - nt.fail("Length doesn't match (%i > %i). Extra text:\n%r" % ( - len(a), len(b), a[len(b):] - )) - elif len(a) < len(b): - nt.fail("Length doesn't match (%i < %i). Extra text:\n%r" % ( - len(a), len(b), b[len(a):] - )) diff --git a/jupyter_console/tests/test_console.py b/jupyter_console/tests/test_console.py index d406039..e7bc884 100644 --- a/jupyter_console/tests/test_console.py +++ b/jupyter_console/tests/test_console.py @@ -1,28 +1,15 @@ -"""Tests for two-process terminal frontend +"""Tests for two-process terminal frontend""" -Currently only has the most simple test possible, starting a console and running -a single command. - -Authors: - -* Min RK -""" - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. import sys from nose import SkipTest -import IPython.testing.tools as tt +from traitlets.tests.utils import check_help_all_output from IPython.testing import decorators as dec -#----------------------------------------------------------------------------- -# Tests -#----------------------------------------------------------------------------- - @dec.skip_win32 def test_console_starts(): """test that `ipython console` starts a terminal""" @@ -34,8 +21,7 @@ def test_console_starts(): def test_help_output(): """ipython console --help-all works""" - tt.help_all_output_test('console') - + check_help_all_output('jupyter_console') def test_display_text(): "Ensure display protocol plain/text key is supported" diff --git a/jupyter_console/tests/test_image_handler.py b/jupyter_console/tests/test_image_handler.py index f91de61..26c92e5 100644 --- a/jupyter_console/tests/test_image_handler.py +++ b/jupyter_console/tests/test_image_handler.py @@ -14,7 +14,6 @@ except ImportError: from IPython.kernel import KernelClient from IPython.terminal.console.interactiveshell import ZMQTerminalInteractiveShell from IPython.utils.tempdir import TemporaryDirectory -from IPython.testing.tools import monkeypatch from IPython.testing.decorators import skip_without from IPython.utils.ipstruct import Struct diff --git a/jupyter_nbconvert/__main__.py b/jupyter_nbconvert/__main__.py new file mode 100644 index 0000000..8f0dd72 --- /dev/null +++ b/jupyter_nbconvert/__main__.py @@ -0,0 +1,2 @@ +from .nbconvertapp import launch_new_instance +launch_new_instance() diff --git a/jupyter_nbconvert/exporters/tests/test_notebook.py b/jupyter_nbconvert/exporters/tests/test_notebook.py index a0b4560..68a966b 100644 --- a/jupyter_nbconvert/exporters/tests/test_notebook.py +++ b/jupyter_nbconvert/exporters/tests/test_notebook.py @@ -9,7 +9,7 @@ from .base import ExportersTestsBase from ..notebook import NotebookExporter from IPython.nbformat import validate -from IPython.testing.tools import assert_big_text_equal +from jupyter_nbconvert.tests.base import assert_big_text_equal class TestNotebookExporter(ExportersTestsBase): """Contains test functions for notebook.py""" diff --git a/jupyter_nbconvert/tests/base.py b/jupyter_nbconvert/tests/base.py index 0e1b5ef..c3a95dc 100644 --- a/jupyter_nbconvert/tests/base.py +++ b/jupyter_nbconvert/tests/base.py @@ -6,17 +6,17 @@ import io import os import glob +import shlex import shutil +import sys import unittest +import nose.tools as nt + from IPython.nbformat import v4, write from IPython.utils.tempdir import TemporaryWorkingDirectory from IPython.utils.process import get_output_error_code -from IPython.testing.tools import get_ipython_cmd - -# a trailing space allows for simpler concatenation with the other arguments -ipy_cmd = get_ipython_cmd(as_string=True) + " " - +from IPython.utils.py3compat import string_types class TestsBase(unittest.TestCase): """Base tests class. Contains useful fuzzy comparison and nbconvert @@ -126,20 +126,43 @@ class TestsBase(unittest.TestCase): return os.path.join(path, *names) - def call(self, parameters, ignore_return_code=False): + def nbconvert(self, parameters, ignore_return_code=False): """ - Execute a, IPython shell command, listening for both Errors and non-zero + Run nbconvert a, IPython shell command, listening for both Errors and non-zero return codes. Parameters ---------- - parameters : str + parameters : str, list(str) List of parameters to pass to IPython. ignore_return_code : optional bool (default False) Throw an OSError if the return code """ - - stdout, stderr, retcode = get_output_error_code(ipy_cmd + parameters) + if isinstance(parameters, string_types): + parameters = shlex.split(parameters) + cmd = [sys.executable, '-m', 'jupyter_nbconvert'] + parameters + stdout, stderr, retcode = get_output_error_code(cmd) if not (retcode == 0 or ignore_return_code): raise OSError(stderr) return stdout, stderr + +def assert_big_text_equal(a, b, chunk_size=80): + """assert that large strings are equal + + Zooms in on first chunk that differs, + to give better info than vanilla assertEqual for large text blobs. + """ + for i in range(0, len(a), chunk_size): + chunk_a = a[i:i + chunk_size] + chunk_b = b[i:i + chunk_size] + nt.assert_equal(chunk_a, chunk_b, "[offset: %i]\n%r != \n%r" % ( + i, chunk_a, chunk_b)) + + if len(a) > len(b): + nt.fail("Length doesn't match (%i > %i). Extra text:\n%r" % ( + len(a), len(b), a[len(b):] + )) + elif len(a) < len(b): + nt.fail("Length doesn't match (%i < %i). Extra text:\n%r" % ( + len(a), len(b), b[len(a):] + )) diff --git a/jupyter_nbconvert/tests/test_nbconvertapp.py b/jupyter_nbconvert/tests/test_nbconvertapp.py index 61b1ad0..e81aef5 100644 --- a/jupyter_nbconvert/tests/test_nbconvertapp.py +++ b/jupyter_nbconvert/tests/test_nbconvertapp.py @@ -11,7 +11,7 @@ import sys from .base import TestsBase from ..postprocessors import PostProcessorBase -import IPython.testing.tools as tt +from traitlets.tests.utils import check_help_all_output from IPython.testing import decorators as dec #----------------------------------------------------------------------------- @@ -29,19 +29,19 @@ class TestNbConvertApp(TestsBase): def test_notebook_help(self): """Will help show if no notebooks are specified?""" with self.create_temp_cwd(): - out, err = self.call('nbconvert --log-level 0', ignore_return_code=True) + out, err = self.nbconvert('--log-level 0', ignore_return_code=True) self.assertIn("see '--help-all'", out) def test_help_output(self): """ipython nbconvert --help-all works""" - tt.help_all_output_test('nbconvert') + check_help_all_output('jupyter_nbconvert') def test_glob(self): """ Do search patterns work for notebook names? """ with self.create_temp_cwd(['notebook*.ipynb']): - self.call('nbconvert --to python *.ipynb --log-level 0') + self.nbconvert('--to python *.ipynb --log-level 0') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -52,7 +52,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(): self.copy_files_to(['notebook*.ipynb'], 'subdir/') - self.call('nbconvert --to python --log-level 0 ' + + self.nbconvert('--to python --log-level 0 ' + os.path.join('subdir', '*.ipynb')) assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -63,7 +63,7 @@ class TestNbConvertApp(TestsBase): Do explicit notebook names work? """ with self.create_temp_cwd(['notebook*.ipynb']): - self.call('nbconvert --log-level 0 --to python notebook2') + self.nbconvert('--log-level 0 --to python notebook2') assert not os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -76,7 +76,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(['notebook2.ipynb']): os.rename('notebook2.ipynb', 'notebook with spaces.ipynb') - self.call('nbconvert --log-level 0 --to pdf' + self.nbconvert('--log-level 0 --to pdf' ' "notebook with spaces"' ' --PDFExporter.latex_count=1' ' --PDFExporter.verbose=True' @@ -86,7 +86,7 @@ class TestNbConvertApp(TestsBase): def test_post_processor(self): """Do post processors work?""" with self.create_temp_cwd(['notebook1.ipynb']): - out, err = self.call('nbconvert --log-level 0 --to python notebook1 ' + out, err = self.nbconvert('--log-level 0 --to python notebook1 ' '--post jupyter_nbconvert.tests.test_nbconvertapp.DummyPost') self.assertIn('Dummy:notebook1.py', out) @@ -94,11 +94,11 @@ class TestNbConvertApp(TestsBase): def test_spurious_cr(self): """Check for extra CR characters""" with self.create_temp_cwd(['notebook2.ipynb']): - self.call('nbconvert --log-level 0 --to latex notebook2') + self.nbconvert('--log-level 0 --to latex notebook2') assert os.path.isfile('notebook2.tex') with open('notebook2.tex') as f: tex = f.read() - self.call('nbconvert --log-level 0 --to html notebook2') + self.nbconvert('--log-level 0 --to html notebook2') assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: html = f.read() @@ -109,7 +109,7 @@ class TestNbConvertApp(TestsBase): def test_png_base64_html_ok(self): """Is embedded png data well formed in HTML?""" with self.create_temp_cwd(['notebook2.ipynb']): - self.call('nbconvert --log-level 0 --to HTML ' + self.nbconvert('--log-level 0 --to HTML ' 'notebook2.ipynb --template full') assert os.path.isfile('notebook2.html') with open('notebook2.html') as f: @@ -121,7 +121,7 @@ class TestNbConvertApp(TestsBase): Do export templates work? """ with self.create_temp_cwd(['notebook2.ipynb']): - self.call('nbconvert --log-level 0 --to slides ' + self.nbconvert('--log-level 0 --to slides ' 'notebook2.ipynb') assert os.path.isfile('notebook2.slides.html') with open('notebook2.slides.html') as f: @@ -130,11 +130,11 @@ class TestNbConvertApp(TestsBase): def test_output_ext(self): """test --output=outputfile[.ext]""" with self.create_temp_cwd(['notebook1.ipynb']): - self.call('nbconvert --log-level 0 --to python ' + self.nbconvert('--log-level 0 --to python ' 'notebook1.ipynb --output nb.py') assert os.path.exists('nb.py') - self.call('nbconvert --log-level 0 --to python ' + self.nbconvert('--log-level 0 --to python ' 'notebook1.ipynb --output nb2') assert os.path.exists('nb2.py') @@ -143,7 +143,7 @@ class TestNbConvertApp(TestsBase): Can a search pattern be used along with matching explicit notebook names? """ with self.create_temp_cwd(['notebook*.ipynb']): - self.call('nbconvert --log-level 0 --to python ' + self.nbconvert('--log-level 0 --to python ' '*.ipynb notebook1.ipynb notebook2.ipynb') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -154,7 +154,7 @@ class TestNbConvertApp(TestsBase): Can explicit notebook names be used and then a matching search pattern? """ with self.create_temp_cwd(['notebook*.ipynb']): - self.call('nbconvert --log-level 0 --to=python ' + self.nbconvert('--log-level 0 --to=python ' 'notebook1.ipynb notebook2.ipynb *.ipynb') assert os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -165,7 +165,7 @@ class TestNbConvertApp(TestsBase): Does the default config work? """ with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']): - self.call('nbconvert --log-level 0') + self.nbconvert('--log-level 0') assert os.path.isfile('notebook1.py') assert not os.path.isfile('notebook2.py') @@ -177,7 +177,7 @@ class TestNbConvertApp(TestsBase): with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py', 'override.py']): - self.call('nbconvert --log-level 0 --config="override.py"') + self.nbconvert('--log-level 0 --config="override.py"') assert not os.path.isfile('notebook1.py') assert os.path.isfile('notebook2.py') @@ -187,7 +187,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(): self.create_empty_notebook(u'nb1_análisis.ipynb') - self.call('nbconvert --log-level 0 --to python nb1_*') + self.nbconvert('--log-level 0 --to python nb1_*') assert os.path.isfile(u'nb1_análisis.py') @dec.onlyif_cmds_exist('pdflatex', 'pandoc') @@ -197,7 +197,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(): self.create_empty_notebook(u'nb1_análisis.ipynb') - self.call('nbconvert --log-level 0 --to pdf "nb1_*"' + self.nbconvert('--log-level 0 --to pdf "nb1_*"' ' --PDFExporter.latex_count=1' ' --PDFExporter.verbose=True') assert os.path.isfile(u'nb1_análisis.pdf') @@ -208,7 +208,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(['hello.py']): self.create_empty_notebook(u'empty.ipynb') - self.call('nbconvert empty --to html --NbConvertApp.writer_class=\'hello.HelloWriter\'') + self.nbconvert('empty --to html --NbConvertApp.writer_class=\'hello.HelloWriter\'') assert os.path.isfile(u'hello.txt') def test_output_suffix(self): @@ -217,7 +217,7 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') - self.call('nbconvert empty.ipynb --to notebook') + self.nbconvert('empty.ipynb --to notebook') assert os.path.isfile('empty.nbconvert.ipynb') def test_different_build_dir(self): @@ -227,8 +227,8 @@ class TestNbConvertApp(TestsBase): with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') os.mkdir('output') - self.call( - 'nbconvert empty.ipynb --to notebook ' + self.nbconvert( + 'empty.ipynb --to notebook ' '--FilesWriter.build_directory=output') assert os.path.isfile('output/empty.ipynb') @@ -238,6 +238,6 @@ class TestNbConvertApp(TestsBase): """ with self.create_temp_cwd(): self.create_empty_notebook('empty.ipynb') - self.call('nbconvert empty.ipynb --to notebook --inplace') + self.nbconvert('empty.ipynb --to notebook --inplace') assert os.path.isfile('empty.ipynb') assert not os.path.isfile('empty.nbconvert.ipynb') diff --git a/jupyter_qtconsole/console/tests/test_app.py b/jupyter_qtconsole/console/tests/test_app.py index 9c7c2b3..2168f6b 100644 --- a/jupyter_qtconsole/console/tests/test_app.py +++ b/jupyter_qtconsole/console/tests/test_app.py @@ -1,27 +1,15 @@ """Test QtConsoleApp""" -#----------------------------------------------------------------------------- -# Copyright (C) 2013 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +# Copyright (c) Jupyter Development Team. +# Distributed under the terms of the Modified BSD License. import nose.tools as nt -import IPython.testing.tools as tt +from traitlets.tests.utils import check_help_all_output from IPython.testing.decorators import skip_if_no_x11 -#----------------------------------------------------------------------------- -# Test functions -#----------------------------------------------------------------------------- - @skip_if_no_x11 def test_help_output(): - """ipython qtconsole --help-all works""" - tt.help_all_output_test('qtconsole') + """jupyter qtconsole --help-all works""" + check_help_all_output('jupyter_qtconsole') diff --git a/traitlets/tests/utils.py b/traitlets/tests/utils.py new file mode 100644 index 0000000..34bc062 --- /dev/null +++ b/traitlets/tests/utils.py @@ -0,0 +1,40 @@ +import sys +import nose.tools as nt + +from subprocess import Popen, PIPE + +def get_output_error_code(cmd): + """Get stdout, stderr, and exit code from running a command""" + p = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = p.communicate() + out = out.decode('utf8', 'replace') + err = err.decode('utf8', 'replace') + return out, err, p.returncode + + +def check_help_output(pkg, subcommand=None): + """test that `python -m PKG [subcommand] -h` works""" + cmd = [sys.executable, '-m', pkg] + if subcommand: + cmd.extend(subcommand) + cmd.append('-h') + out, err, rc = get_output_error_code(cmd) + nt.assert_equal(rc, 0, err) + nt.assert_not_in("Traceback", err) + nt.assert_in("Options", out) + nt.assert_in("--help-all", out) + return out, err + + +def check_help_all_output(pkg, subcommand=None): + """test that `python -m PKG --help-all` works""" + cmd = [sys.executable, '-m', pkg] + if subcommand: + cmd.extend(subcommand) + cmd.append('--help-all') + out, err, rc = get_output_error_code(cmd) + nt.assert_equal(rc, 0, err) + nt.assert_not_in("Traceback", err) + nt.assert_in("Options", out) + nt.assert_in("Class parameters", out) + return out, err