##// END OF EJS Templates
Make all tests async display safe
Make all tests async display safe

File last commit:

r18613:380a2e94
r18910:4100b1b7
Show More
base.py
148 lines | 4.7 KiB | text/x-python | PythonLexer
"""Base test class for nbconvert"""
# Copyright (c) IPython Development Team.
# Distributed under the terms of the Modified BSD License.
import io
import os
import glob
import shutil
import unittest
import IPython
from IPython.nbformat import v4, write
from IPython.utils.tempdir import TemporaryWorkingDirectory
from IPython.utils.path import get_ipython_package_dir
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) + " "
class TestsBase(unittest.TestCase):
"""Base tests class. Contains useful fuzzy comparison and nbconvert
functions."""
def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
fuzzy_spacing=True, ignore_spaces=False,
ignore_newlines=False, case_sensitive=False, leave_padding=False):
"""
Performs a fuzzy comparison of two strings. A fuzzy comparison is a
comparison that ignores insignificant differences in the two comparands.
The significance of certain differences can be specified via the keyword
parameters of this method.
"""
if not leave_padding:
a = a.strip()
b = b.strip()
if ignore_newlines:
a = a.replace('\n', '')
b = b.replace('\n', '')
if newlines_are_spaces:
a = a.replace('\n', ' ')
b = b.replace('\n', ' ')
if tabs_are_spaces:
a = a.replace('\t', ' ')
b = b.replace('\t', ' ')
if ignore_spaces:
a = a.replace(' ', '')
b = b.replace(' ', '')
if fuzzy_spacing:
a = self.recursive_replace(a, ' ', ' ')
b = self.recursive_replace(b, ' ', ' ')
if not case_sensitive:
a = a.lower()
b = b.lower()
self.assertEqual(a, b)
def recursive_replace(self, text, search, replacement):
"""
Performs a recursive replacement operation. Replaces all instances
of a search string in a text string with a replacement string until
the search string no longer exists. Recursion is needed because the
replacement string may generate additional search strings.
For example:
Replace "ii" with "i" in the string "Hiiii" yields "Hii"
Another replacement cds "Hi" (the desired output)
Parameters
----------
text : string
Text to replace in.
search : string
String to search for within "text"
replacement : string
String to replace "search" with
"""
while search in text:
text = text.replace(search, replacement)
return text
def create_temp_cwd(self, copy_filenames=None):
temp_dir = TemporaryWorkingDirectory()
#Copy the files if requested.
if copy_filenames is not None:
self.copy_files_to(copy_filenames, dest=temp_dir.name)
#Return directory handler
return temp_dir
def create_empty_notebook(self, path):
nb = v4.new_notebook()
with io.open(path, 'w', encoding='utf-8') as f:
write(nb, f, 4)
def copy_files_to(self, copy_filenames, dest='.'):
"Copy test files into the destination directory"
if not os.path.isdir(dest):
os.makedirs(dest)
files_path = self._get_files_path()
for pattern in copy_filenames:
for match in glob.glob(os.path.join(files_path, pattern)):
shutil.copyfile(match, os.path.join(dest, os.path.basename(match)))
def _get_files_path(self):
#Get the relative path to this module in the IPython directory.
names = self.__module__.split('.')[1:-1]
names.append('files')
#Build a path using the IPython directory and the relative path we just
#found.
path = get_ipython_package_dir()
for name in names:
path = os.path.join(path, name)
return path
def call(self, parameters, ignore_return_code=False):
"""
Execute a, IPython shell command, listening for both Errors and non-zero
return codes.
Parameters
----------
parameters : 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 not (retcode == 0 or ignore_return_code):
raise OSError(stderr)
return stdout, stderr