##// END OF EJS Templates
updated tests to use get_output_error_code
Paul Ivanov -
Show More
@@ -1,177 +1,171 b''
1 1 """
2 2 Contains base test class for nbconvert
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 #Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 #Distributed under the terms of the Modified BSD License.
8 8 #
9 9 #The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 import subprocess
17 16 import os
18 17 import glob
19 18 import shutil
20 import sys
21 19
22 20 import IPython
23 21 from IPython.utils.tempdir import TemporaryDirectory
24 from IPython.utils import py3compat
22 from IPython.utils.process import get_output_error_code
25 23
26 24 #-----------------------------------------------------------------------------
27 25 # Classes and functions
28 26 #-----------------------------------------------------------------------------
29 27
30 28 class TemporaryWorkingDirectory(TemporaryDirectory):
31 29 """
32 30 Creates a temporary directory and sets the cwd to that directory.
33 31 Automatically reverts to previous cwd upon cleanup.
34 32 Usage example:
35 33
36 34 with TemporaryWorakingDirectory() as tmpdir:
37 35 ...
38 36 """
39 37
40 38 def __init__(self, **kw):
41 39 """
42 40 Constructor
43 41 """
44 42 super(TemporaryWorkingDirectory, self).__init__(**kw)
45 43
46 44 #Change cwd to new temp dir. Remember old cwd.
47 45 self.old_wd = os.getcwd()
48 46 os.chdir(self.name)
49 47
50 48
51 49 def cleanup(self):
52 50 """
53 51 Destructor
54 52 """
55 53
56 54 #Revert to old cwd.
57 55 os.chdir(self.old_wd)
58 56
59 57 #Cleanup
60 58 super(TemporaryWorkingDirectory, self).cleanup()
61 59
62 60
63 61 class TestsBase(object):
64 62 """Base tests class. Contains usefull fuzzy comparison and nbconvert
65 63 functions."""
66 64
67 65
68 66 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
69 67 fuzzy_spacing=True, ignore_spaces=False,
70 68 ignore_newlines=False, case_sensitive=False):
71 69 """
72 70 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
73 71 comparison that ignores insignificant differences in the two comparands.
74 72 The significance of certain differences can be specified via the keyword
75 73 parameters of this method.
76 74 """
77 75
78 76 if newlines_are_spaces:
79 77 a = a.replace('\n', ' ')
80 78 b = b.replace('\n', ' ')
81 79
82 80 if tabs_are_spaces:
83 81 a = a.replace('\t', ' ')
84 82 b = b.replace('\t', ' ')
85 83
86 84 if ignore_spaces:
87 85 a = a.replace(' ', '')
88 86 b = b.replace(' ', '')
89 87
90 88 if fuzzy_spacing:
91 89 a = self.recursive_replace(a, ' ', ' ')
92 90 b = self.recursive_replace(b, ' ', ' ')
93 91
94 92 if ignore_newlines:
95 93 a = a.replace('\n', '')
96 94 b = b.replace('\n', '')
97 95
98 96 if not case_sensitive:
99 97 a = a.lower()
100 98 b = b.lower()
101 99
102 100 return a == b
103 101
104 102
105 103 def recursive_replace(self, text, search, replacement):
106 104 """
107 105 Performs a recursive replacement operation. Replaces all instances
108 106 of a search string in a text string with a replacement string until
109 107 the search string no longer exists. Recursion is needed because the
110 108 replacement string may generate additional search strings.
111 109
112 110 For example:
113 111 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
114 112 Another replacement yields "Hi" (the desired output)
115 113
116 114 Parameters:
117 115 -----------
118 116 text : string
119 117 Text to replace in.
120 118 search : string
121 119 String to search for within "text"
122 120 replacement : string
123 121 String to replace "search" with
124 122 """
125 123 while search in text:
126 124 text = text.replace(search, replacement)
127 125 return text
128 126
129 127
130 128 def create_temp_cwd(self, copy_filenames=None):
131 129 temp_dir = TemporaryWorkingDirectory()
132 130
133 131 #Copy the files if requested.
134 132 if not copy_filenames is None:
135 133 self.copy_files_to(copy_filenames)
136 134
137 135 #Return directory handler
138 136 return temp_dir
139 137
140 138
141 139 def copy_files_to(self, copy_filenames=None, destination=None):
142 140
143 141 #Copy test files into the destination directory.
144 142 if copy_filenames:
145 143 for pattern in copy_filenames:
146 144 for match in glob.glob(os.path.join(self._get_files_path(), pattern)):
147 145 if destination is None:
148 146 shutil.copyfile(match, os.path.basename(match))
149 147 else:
150 148 if not os.path.isdir(destination):
151 149 os.makedirs(destination)
152 150 shutil.copyfile(match, os.path.join(destination, os.path.basename(match)))
153 151
154 152
155 153 def _get_files_path(self):
156 154
157 155 #Get the relative path to this module in the IPython directory.
158 156 names = self.__module__.split('.')[1:-1]
159 157 names.append('files')
160 158
161 159 #Build a path using the IPython directory and the relative path we just
162 160 #found.
163 161 path = IPython.__path__[0]
164 162 for name in names:
165 163 path = os.path.join(path, name)
166 164 return path
167 165
168 166
169 def call(self, parameters):
170 output = subprocess.Popen(parameters, stdout=subprocess.PIPE).communicate()[0]
171
172 #Convert the output to a string if running Python3
173 if py3compat.PY3:
174 return output.decode('utf-8')
175 else:
176 return output
177 No newline at end of file
167 def call(self, parameters, raise_on_error=True):
168 stdout, stderr, retcode = get_output_error_code(parameters)
169 if retcode != 0 and raise_on_error:
170 raise OSError(stderr)
171 return stdout, stderr
@@ -1,149 +1,152 b''
1 1 """
2 2 Contains tests for the nbconvertapp
3 3 """
4 4 #-----------------------------------------------------------------------------
5 5 #Copyright (c) 2013, the IPython Development Team.
6 6 #
7 7 #Distributed under the terms of the Modified BSD License.
8 8 #
9 9 #The full license is in the file COPYING.txt, distributed with this software.
10 10 #-----------------------------------------------------------------------------
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Imports
14 14 #-----------------------------------------------------------------------------
15 15
16 16 import os
17 17 from .base import TestsBase
18 18
19 19 from IPython.utils import py3compat
20 20 from IPython.testing import decorators as dec
21 21
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Constants
25 25 #-----------------------------------------------------------------------------
26 26
27 27 # Define ipython commandline name
28 28 if py3compat.PY3:
29 29 IPYTHON = 'ipython3'
30 30 else:
31 31 IPYTHON = 'ipython'
32 32
33 33
34 34 #-----------------------------------------------------------------------------
35 35 # Classes and functions
36 36 #-----------------------------------------------------------------------------
37 37
38 38 class TestNbConvertApp(TestsBase):
39 39 """Collection of NbConvertApp tests"""
40 40
41 41
42 42 def test_notebook_help(self):
43 43 """
44 44 Will help show if no notebooks are specified?
45 45 """
46 46 with self.create_temp_cwd():
47 assert "see '--help-all'" in self.call([IPYTHON, 'nbconvert'])
47 out, err = self.call(IPYTHON + ' nbconvert', raise_on_error=False)
48 assert "see '--help-all'" in out
48 49
49 50
50 51 def test_glob(self):
51 52 """
52 53 Do search patterns work for notebook names?
53 54 """
54 55 with self.create_temp_cwd(['notebook*.ipynb']):
55 assert not 'error' in self.call([IPYTHON, 'nbconvert',
56 '--to="python"', '--notebooks=["*.ipynb"]']).lower()
56 self.call(IPYTHON + ' nbconvert --to="python"'
57 ' --notebooks=["*.ipynb"]')
57 58 assert os.path.isfile('notebook1.py')
58 59 assert os.path.isfile('notebook2.py')
59 60
60 61
61 62 def test_glob_subdir(self):
62 63 """
63 64 Do search patterns work for subdirectory notebook names?
64 65 """
65 with self.create_temp_cwd() as cwd:
66 with self.create_temp_cwd():
66 67 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
67 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="python"',
68 '--notebooks=["%s"]' % os.path.join('subdir', '*.ipynb')]).lower()
68 self.call(IPYTHON + ' nbconvert --to="python"',
69 ' --notebooks=["%s"]' % os.path.join('subdir', '*.ipynb'))
69 70 assert os.path.isfile('notebook1.py')
70 71 assert os.path.isfile('notebook2.py')
71 72
72 73
73 74 def test_explicit(self):
74 75 """
75 76 Do explicit notebook names work?
76 77 """
77 78 with self.create_temp_cwd(['notebook*.ipynb']):
78 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="python"',
79 '--notebooks=["notebook2.ipynb"]']).lower()
79 self.call(IPYTHON + ' nbconvert --to="python"'
80 ' --notebooks=["notebook2.ipynb"]')
80 81 assert not os.path.isfile('notebook1.py')
81 82 assert os.path.isfile('notebook2.py')
82 83
83 84
84 85 @dec.onlyif_cmds_exist('pdflatex')
85 86 def test_post_processor(self):
86 87 """
87 88 Do post processors work?
88 89 """
89 90 with self.create_temp_cwd(['notebook1.ipynb']):
90 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="latex"',
91 'notebook1', '--post="PDF"', '--PDFPostProcessor.verbose=True']).lower()
91 self.call(IPYTHON + ' nbconvert --to="latex" notebook1'
92 ' --post="PDF" --PDFPostProcessor.verbose=True')
92 93 assert os.path.isfile('notebook1.tex')
93 94 print("\n\n\t" + "\n\t".join([f for f in os.listdir('.') if os.path.isfile(f)]) + "\n\n")
94 95 assert os.path.isfile('notebook1.pdf')
95 96
96 97
97 98 def test_template(self):
98 99 """
99 100 Do export templates work?
100 101 """
101 102 with self.create_temp_cwd(['notebook2.ipynb']):
102 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to=slides',
103 '--notebooks=["notebook2.ipynb"]', '--template=reveal']).lower()
103 self.call(IPYTHON + ' nbconvert --to=slides'
104 ' --notebooks=["notebook2.ipynb"]'
105 ' --template=reveal')
104 106 assert os.path.isfile('notebook2.slides.html')
105 107 with open('notebook2.slides.html') as f:
106 108 assert '/reveal.css' in f.read()
107 109
108 110
109 111 def test_glob_explicit(self):
110 112 """
111 113 Can a search pattern be used along with matching explicit notebook names?
112 114 """
113 115 with self.create_temp_cwd(['notebook*.ipynb']):
114 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="python"',
115 '--notebooks=["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]']).lower()
116 self.call(IPYTHON + ' nbconvert --to="python" --notebooks='
117 '["*.ipynb", "notebook1.ipynb", "notebook2.ipynb"]')
116 118 assert os.path.isfile('notebook1.py')
117 119 assert os.path.isfile('notebook2.py')
118 120
119 121
120 122 def test_explicit_glob(self):
121 123 """
122 124 Can explicit notebook names be used and then a matching search pattern?
123 125 """
124 126 with self.create_temp_cwd(['notebook*.ipynb']):
125 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--to="python"',
126 '--notebooks=["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]']).lower()
127 self.call(IPYTHON + ' nbconvert --to="python" --notebooks='
128 '["notebook1.ipynb", "notebook2.ipynb", "*.ipynb"]')
127 129 assert os.path.isfile('notebook1.py')
128 130 assert os.path.isfile('notebook2.py')
129 131
130 132
131 133 def test_default_config(self):
132 134 """
133 135 Does the default config work?
134 136 """
135 137 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
136 assert not 'error' in self.call([IPYTHON, 'nbconvert']).lower()
138 self.call(IPYTHON + ' nbconvert')
137 139 assert os.path.isfile('notebook1.py')
138 140 assert not os.path.isfile('notebook2.py')
139 141
140 142
141 143 def test_override_config(self):
142 144 """
143 145 Can the default config be overriden?
144 146 """
145 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py',
147 with self.create_temp_cwd(['notebook*.ipynb',
148 'ipython_nbconvert_config.py',
146 149 'override.py']):
147 assert not 'error' in self.call([IPYTHON, 'nbconvert', '--config="override.py"']).lower()
150 self.call(IPYTHON + ' nbconvert --config="override.py"')
148 151 assert not os.path.isfile('notebook1.py')
149 152 assert os.path.isfile('notebook2.py')
General Comments 0
You need to be logged in to leave comments. Login now