From bd98ca07dabe9b16851cecb9efbf4b2183fdbcce 2012-07-15 10:46:30 From: Takafumi Arakaki Date: 2012-07-15 10:46:30 Subject: [PATCH] Add tests for IPython.lib.latextools --- diff --git a/IPython/lib/tests/test_latextools.py b/IPython/lib/tests/test_latextools.py new file mode 100644 index 0000000..a06105c --- /dev/null +++ b/IPython/lib/tests/test_latextools.py @@ -0,0 +1,119 @@ +# encoding: utf-8 +"""Tests for IPython.utils.path.py""" + +#----------------------------------------------------------------------------- +# Copyright (C) 2008-2011 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. +#----------------------------------------------------------------------------- + +import nose.tools as nt + +from IPython.lib import latextools +from IPython.testing.decorators import onlyif_cmds_exist +from IPython.testing.tools import monkeypatch +from IPython.utils.process import FindCmdError + + +def test_latex_to_png_dvipng_fails_when_no_cmd(): + """ + `latex_to_png_dvipng` should return None when there is no required command + """ + for command in ['latex', 'dvipng']: + yield (check_latex_to_png_dvipng_fails_when_no_cmd, command) + + +def check_latex_to_png_dvipng_fails_when_no_cmd(command): + def mock_find_cmd(arg): + if arg == command: + raise FindCmdError + + with monkeypatch(latextools, "find_cmd", mock_find_cmd): + nt.assert_equals(latextools.latex_to_png_dvipng("whatever", True), + None) + + +@onlyif_cmds_exist('latex', 'dvipng') +def test_latex_to_png_dvipng_runs(): + """ + Test that latex_to_png_dvipng just runs without error. + """ + def mock_kpsewhich(filename): + nt.assert_equals(filename, "breqn.sty") + return None + + for (s, wrap) in [("$$x^2$$", False), ("x^2", True)]: + yield (latextools.latex_to_png_dvipng, s, wrap) + + with monkeypatch(latextools, "kpsewhich", mock_kpsewhich): + yield (latextools.latex_to_png_dvipng, s, wrap) + + +def test_genelatex_no_wrap(): + """ + Test genelatex with wrap=False. + """ + def mock_kpsewhich(filename): + assert False, ("kpsewhich should not be called " + "(called with {0})".format(filename)) + + with monkeypatch(latextools, "kpsewhich", mock_kpsewhich): + nt.assert_equals( + '\n'.join(latextools.genelatex("body text", False)), + r'''\documentclass{article} +\usepackage{amsmath} +\usepackage{amsthm} +\usepackage{amssymb} +\usepackage{bm} +\pagestyle{empty} +\begin{document} +body text +\end{document}''') + + +def test_genelatex_wrap_with_breqn(): + """ + Test genelatex with wrap=True for the case breqn.sty is installed. + """ + def mock_kpsewhich(filename): + nt.assert_equals(filename, "breqn.sty") + return "path/to/breqn.sty" + + with monkeypatch(latextools, "kpsewhich", mock_kpsewhich): + nt.assert_equals( + '\n'.join(latextools.genelatex("x^2", True)), + r'''\documentclass{article} +\usepackage{amsmath} +\usepackage{amsthm} +\usepackage{amssymb} +\usepackage{bm} +\usepackage{breqn} +\pagestyle{empty} +\begin{document} +\begin{dmath*} +x^2 +\end{dmath*} +\end{document}''') + + +def test_genelatex_wrap_without_breqn(): + """ + Test genelatex with wrap=True for the case breqn.sty is not installed. + """ + def mock_kpsewhich(filename): + nt.assert_equals(filename, "breqn.sty") + return None + + with monkeypatch(latextools, "kpsewhich", mock_kpsewhich): + nt.assert_equals( + '\n'.join(latextools.genelatex("x^2", True)), + r'''\documentclass{article} +\usepackage{amsmath} +\usepackage{amsthm} +\usepackage{amssymb} +\usepackage{bm} +\pagestyle{empty} +\begin{document} +$$x^2$$ +\end{document}''') diff --git a/IPython/testing/decorators.py b/IPython/testing/decorators.py index d03b068..83ef955 100644 --- a/IPython/testing/decorators.py +++ b/IPython/testing/decorators.py @@ -72,6 +72,9 @@ from ipunittest import ipdoctest, ipdocstring # numpy.testing.decorators, we expose all of it here. from IPython.external.decorators import * +# For onlyif_cmd_exists decorator +from IPython.utils.process import is_cmd_found + #----------------------------------------------------------------------------- # Classes and functions #----------------------------------------------------------------------------- @@ -342,3 +345,14 @@ else: onlyif_unicode_paths = onlyif(unicode_paths, ("This test is only applicable " "where we can use unicode in filenames.")) + + +def onlyif_cmds_exist(*commands): + """ + Decorator to skip test when at least one of `commands` is not found. + """ + for cmd in commands: + if not is_cmd_found(cmd): + return skip("This test runs only if command '{0}' " + "is installed".format(cmd)) + return null_deco diff --git a/IPython/testing/tools.py b/IPython/testing/tools.py index a378a69..b29a718 100644 --- a/IPython/testing/tools.py +++ b/IPython/testing/tools.py @@ -390,3 +390,14 @@ def make_tempfile(name): yield finally: os.unlink(name) + + +@contextmanager +def monkeypatch(obj, name, attr): + """ + Context manager to replace attribute named `name` in `obj` with `attr`. + """ + orig = getattr(obj, name) + setattr(obj, name, attr) + yield + setattr(obj, name, orig) diff --git a/IPython/utils/process.py b/IPython/utils/process.py index 637914a..a5ae2a7 100644 --- a/IPython/utils/process.py +++ b/IPython/utils/process.py @@ -72,6 +72,15 @@ def find_cmd(cmd): return os.path.abspath(path) +def is_cmd_found(cmd): + """Check whether executable `cmd` exists or not and return a bool.""" + try: + find_cmd(cmd) + return True + except FindCmdError: + return False + + def pycmd2argv(cmd): r"""Take the path of a python command and return a list (argv-style).