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