##// END OF EJS Templates
generate unicode filename...
MinRK -
Show More
@@ -1,155 +1,164 b''
1 """
1 """
2 Contains base test class for nbconvert
2 Contains base test class for nbconvert
3 """
3 """
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 #Copyright (c) 2013, the IPython Development Team.
5 #Copyright (c) 2013, the IPython Development Team.
6 #
6 #
7 #Distributed under the terms of the Modified BSD License.
7 #Distributed under the terms of the Modified BSD License.
8 #
8 #
9 #The full license is in the file COPYING.txt, distributed with this software.
9 #The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11
11
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13 # Imports
13 # Imports
14 #-----------------------------------------------------------------------------
14 #-----------------------------------------------------------------------------
15
15
16 import io
16 import os
17 import os
17 import glob
18 import glob
18 import shutil
19 import shutil
19 import unittest
20 import unittest
20
21
21 import IPython
22 import IPython
23 from IPython.nbformat import current
22 from IPython.utils.tempdir import TemporaryWorkingDirectory
24 from IPython.utils.tempdir import TemporaryWorkingDirectory
25 from IPython.utils.path import get_ipython_package_dir
23 from IPython.utils.process import get_output_error_code
26 from IPython.utils.process import get_output_error_code
24 from IPython.testing.tools import get_ipython_cmd
27 from IPython.testing.tools import get_ipython_cmd
25
28
26 # a trailing space allows for simpler concatenation with the other arguments
29 # a trailing space allows for simpler concatenation with the other arguments
27 ipy_cmd = get_ipython_cmd(as_string=True) + " "
30 ipy_cmd = get_ipython_cmd(as_string=True) + " "
28
31
29 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
30 # Classes and functions
33 # Classes and functions
31 #-----------------------------------------------------------------------------
34 #-----------------------------------------------------------------------------
32
35
33
36
34 class TestsBase(unittest.TestCase):
37 class TestsBase(unittest.TestCase):
35 """Base tests class. Contains useful fuzzy comparison and nbconvert
38 """Base tests class. Contains useful fuzzy comparison and nbconvert
36 functions."""
39 functions."""
37
40
38
41
39 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
42 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
40 fuzzy_spacing=True, ignore_spaces=False,
43 fuzzy_spacing=True, ignore_spaces=False,
41 ignore_newlines=False, case_sensitive=False, leave_padding=False):
44 ignore_newlines=False, case_sensitive=False, leave_padding=False):
42 """
45 """
43 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
46 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
44 comparison that ignores insignificant differences in the two comparands.
47 comparison that ignores insignificant differences in the two comparands.
45 The significance of certain differences can be specified via the keyword
48 The significance of certain differences can be specified via the keyword
46 parameters of this method.
49 parameters of this method.
47 """
50 """
48
51
49 if not leave_padding:
52 if not leave_padding:
50 a = a.strip()
53 a = a.strip()
51 b = b.strip()
54 b = b.strip()
52
55
53 if ignore_newlines:
56 if ignore_newlines:
54 a = a.replace('\n', '')
57 a = a.replace('\n', '')
55 b = b.replace('\n', '')
58 b = b.replace('\n', '')
56
59
57 if newlines_are_spaces:
60 if newlines_are_spaces:
58 a = a.replace('\n', ' ')
61 a = a.replace('\n', ' ')
59 b = b.replace('\n', ' ')
62 b = b.replace('\n', ' ')
60
63
61 if tabs_are_spaces:
64 if tabs_are_spaces:
62 a = a.replace('\t', ' ')
65 a = a.replace('\t', ' ')
63 b = b.replace('\t', ' ')
66 b = b.replace('\t', ' ')
64
67
65 if ignore_spaces:
68 if ignore_spaces:
66 a = a.replace(' ', '')
69 a = a.replace(' ', '')
67 b = b.replace(' ', '')
70 b = b.replace(' ', '')
68
71
69 if fuzzy_spacing:
72 if fuzzy_spacing:
70 a = self.recursive_replace(a, ' ', ' ')
73 a = self.recursive_replace(a, ' ', ' ')
71 b = self.recursive_replace(b, ' ', ' ')
74 b = self.recursive_replace(b, ' ', ' ')
72
75
73 if not case_sensitive:
76 if not case_sensitive:
74 a = a.lower()
77 a = a.lower()
75 b = b.lower()
78 b = b.lower()
76
79
77 self.assertEqual(a, b)
80 self.assertEqual(a, b)
78
81
79
82
80 def recursive_replace(self, text, search, replacement):
83 def recursive_replace(self, text, search, replacement):
81 """
84 """
82 Performs a recursive replacement operation. Replaces all instances
85 Performs a recursive replacement operation. Replaces all instances
83 of a search string in a text string with a replacement string until
86 of a search string in a text string with a replacement string until
84 the search string no longer exists. Recursion is needed because the
87 the search string no longer exists. Recursion is needed because the
85 replacement string may generate additional search strings.
88 replacement string may generate additional search strings.
86
89
87 For example:
90 For example:
88 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
91 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
89 Another replacement cds "Hi" (the desired output)
92 Another replacement cds "Hi" (the desired output)
90
93
91 Parameters
94 Parameters
92 ----------
95 ----------
93 text : string
96 text : string
94 Text to replace in.
97 Text to replace in.
95 search : string
98 search : string
96 String to search for within "text"
99 String to search for within "text"
97 replacement : string
100 replacement : string
98 String to replace "search" with
101 String to replace "search" with
99 """
102 """
100 while search in text:
103 while search in text:
101 text = text.replace(search, replacement)
104 text = text.replace(search, replacement)
102 return text
105 return text
103
106
104 def create_temp_cwd(self, copy_filenames=None):
107 def create_temp_cwd(self, copy_filenames=None):
105 temp_dir = TemporaryWorkingDirectory()
108 temp_dir = TemporaryWorkingDirectory()
106
109
107 #Copy the files if requested.
110 #Copy the files if requested.
108 if copy_filenames is not None:
111 if copy_filenames is not None:
109 self.copy_files_to(copy_filenames)
112 self.copy_files_to(copy_filenames)
110
113
111 #Return directory handler
114 #Return directory handler
112 return temp_dir
115 return temp_dir
116
117 def create_empty_notebook(self, path):
118 nb = current.new_notebook()
119 nb.worksheets.append(current.new_worksheet())
120 with io.open(path, 'w', encoding='utf-8') as f:
121 current.write(nb, f, 'json')
113
122
114
123
115 def copy_files_to(self, copy_filenames, dest='.'):
124 def copy_files_to(self, copy_filenames, dest='.'):
116 "Copy test files into the destination directory"
125 "Copy test files into the destination directory"
117 if not os.path.isdir(dest):
126 if not os.path.isdir(dest):
118 os.makedirs(dest)
127 os.makedirs(dest)
119 files_path = self._get_files_path()
128 files_path = self._get_files_path()
120 for pattern in copy_filenames:
129 for pattern in copy_filenames:
121 for match in glob.glob(os.path.join(files_path, pattern)):
130 for match in glob.glob(os.path.join(files_path, pattern)):
122 shutil.copyfile(match, os.path.join(dest, os.path.basename(match)))
131 shutil.copyfile(match, os.path.join(dest, os.path.basename(match)))
123
132
124
133
125 def _get_files_path(self):
134 def _get_files_path(self):
126
135
127 #Get the relative path to this module in the IPython directory.
136 #Get the relative path to this module in the IPython directory.
128 names = self.__module__.split('.')[1:-1]
137 names = self.__module__.split('.')[1:-1]
129 names.append('files')
138 names.append('files')
130
139
131 #Build a path using the IPython directory and the relative path we just
140 #Build a path using the IPython directory and the relative path we just
132 #found.
141 #found.
133 path = IPython.__path__[0]
142 path = get_ipython_package_dir()
134 for name in names:
143 for name in names:
135 path = os.path.join(path, name)
144 path = os.path.join(path, name)
136 return path
145 return path
137
146
138
147
139 def call(self, parameters, ignore_return_code=False):
148 def call(self, parameters, ignore_return_code=False):
140 """
149 """
141 Execute a, IPython shell command, listening for both Errors and non-zero
150 Execute a, IPython shell command, listening for both Errors and non-zero
142 return codes.
151 return codes.
143
152
144 Parameters
153 Parameters
145 ----------
154 ----------
146 parameters : str
155 parameters : str
147 List of parameters to pass to IPython.
156 List of parameters to pass to IPython.
148 ignore_return_code : optional bool (default False)
157 ignore_return_code : optional bool (default False)
149 Throw an OSError if the return code
158 Throw an OSError if the return code
150 """
159 """
151
160
152 stdout, stderr, retcode = get_output_error_code(ipy_cmd + parameters)
161 stdout, stderr, retcode = get_output_error_code(ipy_cmd + parameters)
153 if not (retcode == 0 or ignore_return_code):
162 if not (retcode == 0 or ignore_return_code):
154 raise OSError(stderr)
163 raise OSError(stderr)
155 return stdout, stderr
164 return stdout, stderr
@@ -1,207 +1,209 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Test NbConvertApp"""
2 """Test NbConvertApp"""
3
3
4 #-----------------------------------------------------------------------------
4 #-----------------------------------------------------------------------------
5 # Copyright (C) 2013 The IPython Development Team
5 # Copyright (C) 2013 The IPython Development Team
6 #
6 #
7 # Distributed under the terms of the BSD License. The full license is in
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10
10
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12 # Imports
12 # Imports
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14
14
15 import os
15 import os
16 import glob
16 import glob
17 import sys
17 import sys
18
18
19 from .base import TestsBase
19 from .base import TestsBase
20
20
21 import IPython.testing.tools as tt
21 import IPython.testing.tools as tt
22 from IPython.testing import decorators as dec
22 from IPython.testing import decorators as dec
23
23
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Constants
26 # Constants
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29
29
30 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
31 # Classes and functions
31 # Classes and functions
32 #-----------------------------------------------------------------------------
32 #-----------------------------------------------------------------------------
33
33
34 class TestNbConvertApp(TestsBase):
34 class TestNbConvertApp(TestsBase):
35 """Collection of NbConvertApp tests"""
35 """Collection of NbConvertApp tests"""
36
36
37
37
38 def test_notebook_help(self):
38 def test_notebook_help(self):
39 """Will help show if no notebooks are specified?"""
39 """Will help show if no notebooks are specified?"""
40 with self.create_temp_cwd():
40 with self.create_temp_cwd():
41 out, err = self.call('nbconvert --log-level 0', ignore_return_code=True)
41 out, err = self.call('nbconvert --log-level 0', ignore_return_code=True)
42 self.assertIn("see '--help-all'", out)
42 self.assertIn("see '--help-all'", out)
43
43
44 def test_help_output(self):
44 def test_help_output(self):
45 """ipython nbconvert --help-all works"""
45 """ipython nbconvert --help-all works"""
46 tt.help_all_output_test('nbconvert')
46 tt.help_all_output_test('nbconvert')
47
47
48 def test_glob(self):
48 def test_glob(self):
49 """
49 """
50 Do search patterns work for notebook names?
50 Do search patterns work for notebook names?
51 """
51 """
52 with self.create_temp_cwd(['notebook*.ipynb']):
52 with self.create_temp_cwd(['notebook*.ipynb']):
53 self.call('nbconvert --to python *.ipynb --log-level 0')
53 self.call('nbconvert --to python *.ipynb --log-level 0')
54 assert os.path.isfile('notebook1.py')
54 assert os.path.isfile('notebook1.py')
55 assert os.path.isfile('notebook2.py')
55 assert os.path.isfile('notebook2.py')
56
56
57
57
58 def test_glob_subdir(self):
58 def test_glob_subdir(self):
59 """
59 """
60 Do search patterns work for subdirectory notebook names?
60 Do search patterns work for subdirectory notebook names?
61 """
61 """
62 with self.create_temp_cwd():
62 with self.create_temp_cwd():
63 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
63 self.copy_files_to(['notebook*.ipynb'], 'subdir/')
64 self.call('nbconvert --to python --log-level 0 ' +
64 self.call('nbconvert --to python --log-level 0 ' +
65 os.path.join('subdir', '*.ipynb'))
65 os.path.join('subdir', '*.ipynb'))
66 assert os.path.isfile('notebook1.py')
66 assert os.path.isfile('notebook1.py')
67 assert os.path.isfile('notebook2.py')
67 assert os.path.isfile('notebook2.py')
68
68
69
69
70 def test_explicit(self):
70 def test_explicit(self):
71 """
71 """
72 Do explicit notebook names work?
72 Do explicit notebook names work?
73 """
73 """
74 with self.create_temp_cwd(['notebook*.ipynb']):
74 with self.create_temp_cwd(['notebook*.ipynb']):
75 self.call('nbconvert --log-level 0 --to python notebook2')
75 self.call('nbconvert --log-level 0 --to python notebook2')
76 assert not os.path.isfile('notebook1.py')
76 assert not os.path.isfile('notebook1.py')
77 assert os.path.isfile('notebook2.py')
77 assert os.path.isfile('notebook2.py')
78
78
79
79
80 @dec.onlyif_cmds_exist('pdflatex')
80 @dec.onlyif_cmds_exist('pdflatex')
81 @dec.onlyif_cmds_exist('pandoc')
81 @dec.onlyif_cmds_exist('pandoc')
82 def test_filename_spaces(self):
82 def test_filename_spaces(self):
83 """
83 """
84 Generate PDFs with graphics if notebooks have spaces in the name?
84 Generate PDFs with graphics if notebooks have spaces in the name?
85 """
85 """
86 with self.create_temp_cwd(['notebook2.ipynb']):
86 with self.create_temp_cwd(['notebook2.ipynb']):
87 os.rename('notebook2.ipynb', 'notebook with spaces.ipynb')
87 os.rename('notebook2.ipynb', 'notebook with spaces.ipynb')
88 o,e = self.call('nbconvert --log-level 0 --to latex '
88 o,e = self.call('nbconvert --log-level 0 --to latex '
89 '"notebook with spaces" --post PDF '
89 '"notebook with spaces" --post PDF '
90 '--PDFPostProcessor.verbose=True')
90 '--PDFPostProcessor.verbose=True')
91 assert os.path.isfile('notebook with spaces.tex')
91 assert os.path.isfile('notebook with spaces.tex')
92 assert os.path.isdir('notebook with spaces_files')
92 assert os.path.isdir('notebook with spaces_files')
93 assert os.path.isfile('notebook with spaces.pdf')
93 assert os.path.isfile('notebook with spaces.pdf')
94
94
95 @dec.onlyif_cmds_exist('pdflatex')
95 @dec.onlyif_cmds_exist('pdflatex')
96 @dec.onlyif_cmds_exist('pandoc')
96 @dec.onlyif_cmds_exist('pandoc')
97 def test_post_processor(self):
97 def test_post_processor(self):
98 """
98 """
99 Do post processors work?
99 Do post processors work?
100 """
100 """
101 with self.create_temp_cwd(['notebook1.ipynb']):
101 with self.create_temp_cwd(['notebook1.ipynb']):
102 self.call('nbconvert --log-level 0 --to latex notebook1 '
102 self.call('nbconvert --log-level 0 --to latex notebook1 '
103 '--post PDF --PDFPostProcessor.verbose=True')
103 '--post PDF --PDFPostProcessor.verbose=True')
104 assert os.path.isfile('notebook1.tex')
104 assert os.path.isfile('notebook1.tex')
105 assert os.path.isfile('notebook1.pdf')
105 assert os.path.isfile('notebook1.pdf')
106
106
107 @dec.onlyif_cmds_exist('pandoc')
107 @dec.onlyif_cmds_exist('pandoc')
108 def test_spurious_cr(self):
108 def test_spurious_cr(self):
109 """Check for extra CR characters"""
109 """Check for extra CR characters"""
110 with self.create_temp_cwd(['notebook2.ipynb']):
110 with self.create_temp_cwd(['notebook2.ipynb']):
111 self.call('nbconvert --log-level 0 --to latex notebook2')
111 self.call('nbconvert --log-level 0 --to latex notebook2')
112 assert os.path.isfile('notebook2.tex')
112 assert os.path.isfile('notebook2.tex')
113 with open('notebook2.tex') as f:
113 with open('notebook2.tex') as f:
114 tex = f.read()
114 tex = f.read()
115 self.call('nbconvert --log-level 0 --to html notebook2')
115 self.call('nbconvert --log-level 0 --to html notebook2')
116 assert os.path.isfile('notebook2.html')
116 assert os.path.isfile('notebook2.html')
117 with open('notebook2.html') as f:
117 with open('notebook2.html') as f:
118 html = f.read()
118 html = f.read()
119 self.assertEqual(tex.count('\r'), tex.count('\r\n'))
119 self.assertEqual(tex.count('\r'), tex.count('\r\n'))
120 self.assertEqual(html.count('\r'), html.count('\r\n'))
120 self.assertEqual(html.count('\r'), html.count('\r\n'))
121
121
122 @dec.onlyif_cmds_exist('pandoc')
122 @dec.onlyif_cmds_exist('pandoc')
123 def test_png_base64_html_ok(self):
123 def test_png_base64_html_ok(self):
124 """Is embedded png data well formed in HTML?"""
124 """Is embedded png data well formed in HTML?"""
125 with self.create_temp_cwd(['notebook2.ipynb']):
125 with self.create_temp_cwd(['notebook2.ipynb']):
126 self.call('nbconvert --log-level 0 --to HTML '
126 self.call('nbconvert --log-level 0 --to HTML '
127 'notebook2.ipynb --template full')
127 'notebook2.ipynb --template full')
128 assert os.path.isfile('notebook2.html')
128 assert os.path.isfile('notebook2.html')
129 with open('notebook2.html') as f:
129 with open('notebook2.html') as f:
130 assert "data:image/png;base64,b'" not in f.read()
130 assert "data:image/png;base64,b'" not in f.read()
131
131
132 @dec.onlyif_cmds_exist('pandoc')
132 @dec.onlyif_cmds_exist('pandoc')
133 def test_template(self):
133 def test_template(self):
134 """
134 """
135 Do export templates work?
135 Do export templates work?
136 """
136 """
137 with self.create_temp_cwd(['notebook2.ipynb']):
137 with self.create_temp_cwd(['notebook2.ipynb']):
138 self.call('nbconvert --log-level 0 --to slides '
138 self.call('nbconvert --log-level 0 --to slides '
139 'notebook2.ipynb')
139 'notebook2.ipynb')
140 assert os.path.isfile('notebook2.slides.html')
140 assert os.path.isfile('notebook2.slides.html')
141 with open('notebook2.slides.html') as f:
141 with open('notebook2.slides.html') as f:
142 assert '/reveal.css' in f.read()
142 assert '/reveal.css' in f.read()
143
143
144
144
145 def test_glob_explicit(self):
145 def test_glob_explicit(self):
146 """
146 """
147 Can a search pattern be used along with matching explicit notebook names?
147 Can a search pattern be used along with matching explicit notebook names?
148 """
148 """
149 with self.create_temp_cwd(['notebook*.ipynb']):
149 with self.create_temp_cwd(['notebook*.ipynb']):
150 self.call('nbconvert --log-level 0 --to python '
150 self.call('nbconvert --log-level 0 --to python '
151 '*.ipynb notebook1.ipynb notebook2.ipynb')
151 '*.ipynb notebook1.ipynb notebook2.ipynb')
152 assert os.path.isfile('notebook1.py')
152 assert os.path.isfile('notebook1.py')
153 assert os.path.isfile('notebook2.py')
153 assert os.path.isfile('notebook2.py')
154
154
155
155
156 def test_explicit_glob(self):
156 def test_explicit_glob(self):
157 """
157 """
158 Can explicit notebook names be used and then a matching search pattern?
158 Can explicit notebook names be used and then a matching search pattern?
159 """
159 """
160 with self.create_temp_cwd(['notebook*.ipynb']):
160 with self.create_temp_cwd(['notebook*.ipynb']):
161 self.call('nbconvert --log-level 0 --to=python '
161 self.call('nbconvert --log-level 0 --to=python '
162 'notebook1.ipynb notebook2.ipynb *.ipynb')
162 'notebook1.ipynb notebook2.ipynb *.ipynb')
163 assert os.path.isfile('notebook1.py')
163 assert os.path.isfile('notebook1.py')
164 assert os.path.isfile('notebook2.py')
164 assert os.path.isfile('notebook2.py')
165
165
166
166
167 def test_default_config(self):
167 def test_default_config(self):
168 """
168 """
169 Does the default config work?
169 Does the default config work?
170 """
170 """
171 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
171 with self.create_temp_cwd(['notebook*.ipynb', 'ipython_nbconvert_config.py']):
172 self.call('nbconvert --log-level 0')
172 self.call('nbconvert --log-level 0')
173 assert os.path.isfile('notebook1.py')
173 assert os.path.isfile('notebook1.py')
174 assert not os.path.isfile('notebook2.py')
174 assert not os.path.isfile('notebook2.py')
175
175
176
176
177 def test_override_config(self):
177 def test_override_config(self):
178 """
178 """
179 Can the default config be overriden?
179 Can the default config be overriden?
180 """
180 """
181 with self.create_temp_cwd(['notebook*.ipynb',
181 with self.create_temp_cwd(['notebook*.ipynb',
182 'ipython_nbconvert_config.py',
182 'ipython_nbconvert_config.py',
183 'override.py']):
183 'override.py']):
184 self.call('nbconvert --log-level 0 --config="override.py"')
184 self.call('nbconvert --log-level 0 --config="override.py"')
185 assert not os.path.isfile('notebook1.py')
185 assert not os.path.isfile('notebook1.py')
186 assert os.path.isfile('notebook2.py')
186 assert os.path.isfile('notebook2.py')
187
187
188 def test_accents_in_filename(self):
188 def test_accents_in_filename(self):
189 """
189 """
190 Can notebook names include accents?
190 Can notebook names include accents?
191 """
191 """
192 with self.create_temp_cwd(['nb*.ipynb']):
192 with self.create_temp_cwd():
193 self.create_empty_notebook(u'nb1_análisis.ipynb')
193 self.call('nbconvert --log-level 0 --to python nb1_*')
194 self.call('nbconvert --log-level 0 --to python nb1_*')
194 assert os.path.isfile(u'nb1_análisis.py')
195 assert os.path.isfile(u'nb1_análisis.py')
195
196
196 @dec.onlyif_cmds_exist('pdflatex')
197 @dec.onlyif_cmds_exist('pdflatex')
197 @dec.onlyif_cmds_exist('pandoc')
198 @dec.onlyif_cmds_exist('pandoc')
198 def test_filename_accent(self):
199 def test_filename_accent(self):
199 """
200 """
200 Generate PDFs if notebooks have an accent in their name?
201 Generate PDFs if notebooks have an accent in their name?
201 """
202 """
202 with self.create_temp_cwd(['nb*.ipynb']):
203 with self.create_temp_cwd():
204 self.create_empty_notebook(u'nb1_análisis.ipynb')
203 o,e = self.call('nbconvert --log-level 0 --to latex '
205 o,e = self.call('nbconvert --log-level 0 --to latex '
204 '"nb1_*" --post PDF '
206 '"nb1_*" --post PDF '
205 '--PDFPostProcessor.verbose=True')
207 '--PDFPostProcessor.verbose=True')
206 assert os.path.isfile(u'nb1_análisis.tex')
208 assert os.path.isfile(u'nb1_análisis.tex')
207 assert os.path.isfile(u'nb1_análisis.pdf')
209 assert os.path.isfile(u'nb1_análisis.pdf')
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now