base.py
164 lines
| 5.3 KiB
| text/x-python
|
PythonLexer
Jonathan Frederic
|
r11477 | """ | ||
Contains base test class for nbconvert | ||||
""" | ||||
#----------------------------------------------------------------------------- | ||||
#Copyright (c) 2013, the IPython Development Team. | ||||
# | ||||
#Distributed under the terms of the Modified BSD License. | ||||
# | ||||
#The full license is in the file COPYING.txt, distributed with this software. | ||||
#----------------------------------------------------------------------------- | ||||
#----------------------------------------------------------------------------- | ||||
# Imports | ||||
#----------------------------------------------------------------------------- | ||||
MinRK
|
r14961 | import io | ||
Jonathan Frederic
|
r11478 | import os | ||
import glob | ||||
import shutil | ||||
Thomas Kluyver
|
r12373 | import unittest | ||
Jonathan Frederic
|
r11478 | |||
import IPython | ||||
MinRK
|
r14961 | from IPython.nbformat import current | ||
Paul Ivanov
|
r11873 | from IPython.utils.tempdir import TemporaryWorkingDirectory | ||
MinRK
|
r14961 | from IPython.utils.path import get_ipython_package_dir | ||
Paul Ivanov
|
r11828 | from IPython.utils.process import get_output_error_code | ||
Paul Ivanov
|
r11862 | from IPython.testing.tools import get_ipython_cmd | ||
Paul Ivanov
|
r11834 | |||
Paul Ivanov
|
r11862 | # a trailing space allows for simpler concatenation with the other arguments | ||
ipy_cmd = get_ipython_cmd(as_string=True) + " " | ||||
Jonathan Frederic
|
r11477 | |||
#----------------------------------------------------------------------------- | ||||
# Classes and functions | ||||
#----------------------------------------------------------------------------- | ||||
Jonathan Frederic
|
r11478 | |||
Thomas Kluyver
|
r12373 | class TestsBase(unittest.TestCase): | ||
Paul Ivanov
|
r11878 | """Base tests class. Contains useful fuzzy comparison and nbconvert | ||
Jonathan Frederic
|
r11477 | functions.""" | ||
def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True, | ||||
fuzzy_spacing=True, ignore_spaces=False, | ||||
Jonathan Frederic
|
r11905 | ignore_newlines=False, case_sensitive=False, leave_padding=False): | ||
Jonathan Frederic
|
r11477 | """ | ||
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. | ||||
""" | ||||
Jonathan Frederic
|
r11905 | if not leave_padding: | ||
a = a.strip() | ||||
b = b.strip() | ||||
Jonathan Frederic
|
r11904 | if ignore_newlines: | ||
a = a.replace('\n', '') | ||||
b = b.replace('\n', '') | ||||
Jonathan Frederic
|
r11477 | 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, ' ', ' ') | ||||
Jonathan Frederic
|
r11482 | if not case_sensitive: | ||
Jonathan Frederic
|
r11477 | a = a.lower() | ||
b = b.lower() | ||||
Jonathan Frederic
|
r11910 | |||
Jonathan Frederic
|
r11936 | self.assertEqual(a, b) | ||
Jonathan Frederic
|
r11477 | |||
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" | ||||
Thomas Kluyver
|
r12373 | Another replacement cds "Hi" (the desired output) | ||
Jonathan Frederic
|
r11477 | |||
Thomas Kluyver
|
r13587 | Parameters | ||
---------- | ||||
Jonathan Frederic
|
r11477 | 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 | ||||
Jonathan Frederic
|
r11478 | |||
def create_temp_cwd(self, copy_filenames=None): | ||||
temp_dir = TemporaryWorkingDirectory() | ||||
#Copy the files if requested. | ||||
Paul Ivanov
|
r11878 | if copy_filenames is not None: | ||
Thomas Kluyver
|
r15360 | self.copy_files_to(copy_filenames, dest=temp_dir.name) | ||
Jonathan Frederic
|
r11478 | |||
#Return directory handler | ||||
return temp_dir | ||||
MinRK
|
r14961 | |||
def create_empty_notebook(self, path): | ||||
nb = current.new_notebook() | ||||
nb.worksheets.append(current.new_worksheet()) | ||||
with io.open(path, 'w', encoding='utf-8') as f: | ||||
current.write(nb, f, 'json') | ||||
Jonathan Frederic
|
r11478 | |||
Paul Ivanov
|
r11877 | 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))) | ||||
Jonathan Frederic
|
r11478 | |||
def _get_files_path(self): | ||||
Jonathan Frederic
|
r11479 | |||
#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. | ||||
MinRK
|
r14961 | path = get_ipython_package_dir() | ||
Jonathan Frederic
|
r11479 | for name in names: | ||
path = os.path.join(path, name) | ||||
return path | ||||
Jonathan Frederic
|
r11478 | |||
Jonathan Frederic
|
r12133 | def call(self, parameters, ignore_return_code=False): | ||
""" | ||||
Execute a, IPython shell command, listening for both Errors and non-zero | ||||
return codes. | ||||
Thomas Kluyver
|
r13587 | Parameters | ||
---------- | ||||
Jonathan Frederic
|
r12133 | parameters : str | ||
List of parameters to pass to IPython. | ||||
ignore_return_code : optional bool (default False) | ||||
Throw an OSError if the return code | ||||
""" | ||||
Paul Ivanov
|
r11834 | stdout, stderr, retcode = get_output_error_code(ipy_cmd + parameters) | ||
Jonathan Frederic
|
r12134 | if not (retcode == 0 or ignore_return_code): | ||
Paul Ivanov
|
r11828 | raise OSError(stderr) | ||
return stdout, stderr | ||||