##// END OF EJS Templates
Add leave_padding option to fuzzy compare
Jonathan Frederic -
Show More
@@ -1,138 +1,142 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 TemporaryWorkingDirectory
22 22 from IPython.utils.process import get_output_error_code
23 23 from IPython.testing.tools import get_ipython_cmd
24 24
25 25 # a trailing space allows for simpler concatenation with the other arguments
26 26 ipy_cmd = get_ipython_cmd(as_string=True) + " "
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Classes and functions
30 30 #-----------------------------------------------------------------------------
31 31
32 32
33 33 class TestsBase(object):
34 34 """Base tests class. Contains useful fuzzy comparison and nbconvert
35 35 functions."""
36 36
37 37
38 38 def fuzzy_compare(self, a, b, newlines_are_spaces=True, tabs_are_spaces=True,
39 39 fuzzy_spacing=True, ignore_spaces=False,
40 ignore_newlines=False, case_sensitive=False):
40 ignore_newlines=False, case_sensitive=False, leave_padding=False):
41 41 """
42 42 Performs a fuzzy comparison of two strings. A fuzzy comparison is a
43 43 comparison that ignores insignificant differences in the two comparands.
44 44 The significance of certain differences can be specified via the keyword
45 45 parameters of this method.
46 46 """
47 47
48 if not leave_padding:
49 a = a.strip()
50 b = b.strip()
51
48 52 if ignore_newlines:
49 53 a = a.replace('\n', '')
50 54 b = b.replace('\n', '')
51 55
52 56 if newlines_are_spaces:
53 57 a = a.replace('\n', ' ')
54 58 b = b.replace('\n', ' ')
55 59
56 60 if tabs_are_spaces:
57 61 a = a.replace('\t', ' ')
58 62 b = b.replace('\t', ' ')
59 63
60 64 if ignore_spaces:
61 65 a = a.replace(' ', '')
62 66 b = b.replace(' ', '')
63 67
64 68 if fuzzy_spacing:
65 69 a = self.recursive_replace(a, ' ', ' ')
66 70 b = self.recursive_replace(b, ' ', ' ')
67 71
68 72 if not case_sensitive:
69 73 a = a.lower()
70 74 b = b.lower()
71 75
72 76 return a == b
73 77
74 78
75 79 def recursive_replace(self, text, search, replacement):
76 80 """
77 81 Performs a recursive replacement operation. Replaces all instances
78 82 of a search string in a text string with a replacement string until
79 83 the search string no longer exists. Recursion is needed because the
80 84 replacement string may generate additional search strings.
81 85
82 86 For example:
83 87 Replace "ii" with "i" in the string "Hiiii" yields "Hii"
84 88 Another replacement yields "Hi" (the desired output)
85 89
86 90 Parameters:
87 91 -----------
88 92 text : string
89 93 Text to replace in.
90 94 search : string
91 95 String to search for within "text"
92 96 replacement : string
93 97 String to replace "search" with
94 98 """
95 99 while search in text:
96 100 text = text.replace(search, replacement)
97 101 return text
98 102
99 103 def create_temp_cwd(self, copy_filenames=None):
100 104 temp_dir = TemporaryWorkingDirectory()
101 105
102 106 #Copy the files if requested.
103 107 if copy_filenames is not None:
104 108 self.copy_files_to(copy_filenames)
105 109
106 110 #Return directory handler
107 111 return temp_dir
108 112
109 113
110 114 def copy_files_to(self, copy_filenames, dest='.'):
111 115 "Copy test files into the destination directory"
112 116 if not os.path.isdir(dest):
113 117 os.makedirs(dest)
114 118 files_path = self._get_files_path()
115 119 for pattern in copy_filenames:
116 120 for match in glob.glob(os.path.join(files_path, pattern)):
117 121 shutil.copyfile(match, os.path.join(dest, os.path.basename(match)))
118 122
119 123
120 124 def _get_files_path(self):
121 125
122 126 #Get the relative path to this module in the IPython directory.
123 127 names = self.__module__.split('.')[1:-1]
124 128 names.append('files')
125 129
126 130 #Build a path using the IPython directory and the relative path we just
127 131 #found.
128 132 path = IPython.__path__[0]
129 133 for name in names:
130 134 path = os.path.join(path, name)
131 135 return path
132 136
133 137
134 138 def call(self, parameters, raise_on_error=True):
135 139 stdout, stderr, retcode = get_output_error_code(ipy_cmd + parameters)
136 140 if retcode != 0 and raise_on_error:
137 141 raise OSError(stderr)
138 142 return stdout, stderr
General Comments 0
You need to be logged in to leave comments. Login now