36 def assert_modified(self, path): |
36 def assert_modified(self, path): |
37 """ |
37 """ |
38 Assert that a given file or directory has been modified since the last |
38 Assert that a given file or directory has been modified since the last |
39 call to set_modification_reference_time() with the same path. |
39 call to set_modification_reference_time() with the same path. |
40 """ |
40 """ |
41 self._assert_modification(path, assert_not_modified=False) |
41 # This fails on linux for some reason, probably because the modification |
|
42 # timestamps are not accurate enough |
|
43 if sys.platform == "win32": |
|
44 self._assert_modification(path, assert_not_modified=False) |
42 |
45 |
43 def assert_not_modified(self, path): |
46 def assert_not_modified(self, path): |
44 """ |
47 """ |
45 Assert that a given file or directory has NOT been modified since the last |
48 Assert that a given file or directory has NOT been modified since the last |
46 call to set_modification_reference_time() with the same path. |
49 call to set_modification_reference_time() with the same path. |
155 else: cr = d |
158 else: cr = d |
156 self.assert_dir_contents_equal( |
159 self.assert_dir_contents_equal( |
157 os.path.join(dir1, d), os.path.join(dir2, d), |
160 os.path.join(dir1, d), os.path.join(dir2, d), |
158 ignore, custom_comparison_functions, cr) |
161 ignore, custom_comparison_functions, cr) |
159 |
162 |
160 def assert_file_contents_equal(self, file1, file2, ignore_patterns=[]): |
163 def assert_file_contents_equal(self, file1, file2, ignore_patterns=[], ignore_endline_style=False): |
161 """ |
164 """ |
162 Assert the the given two files exist and their contents are equal. |
165 Assert the the given two files exist and their contents are equal. |
163 @param ignore_patterns: List of regular expressions for portions of the |
166 @param ignore_patterns: List of regular expressions for portions of the |
164 file content to ignore in the comparison. The ignored parts are |
167 file content to ignore in the comparison. The ignored parts are |
165 deleted from the files before actual comparison. |
168 deleted from the files before actual comparison. |
|
169 @param ignore_endline_style: If True, the endline style (CRLF or LF) is |
|
170 ignored during the comparison. |
166 """ |
171 """ |
167 self.assertTrue(os.path.exists(file1), "File '%s' does not exist!" % file1) |
172 self.assertTrue(os.path.exists(file1), "File '%s' does not exist!" % file1) |
168 self.assertTrue(os.path.exists(file2), "File '%s' does not exist!" % file2) |
173 self.assertTrue(os.path.exists(file2), "File '%s' does not exist!" % file2) |
169 |
174 |
170 data1 = self.read_data_from_file(file1) |
175 data1 = self.read_data_from_file(file1) |
175 data = re.sub(pattern, '{{{ignore_%d}}}' % i, data) |
180 data = re.sub(pattern, '{{{ignore_%d}}}' % i, data) |
176 return data |
181 return data |
177 data1 = remove_ignored(data1, ignore_patterns) |
182 data1 = remove_ignored(data1, ignore_patterns) |
178 data2 = remove_ignored(data2, ignore_patterns) |
183 data2 = remove_ignored(data2, ignore_patterns) |
179 |
184 |
|
185 if ignore_endline_style: |
|
186 data1 = data1.replace('\r\n', '\n') |
|
187 data2 = data2.replace('\r\n', '\n') |
|
188 |
|
189 import difflib |
|
190 difseq = difflib.ndiff(data1, data2) |
|
191 # take only the first ten rows of the difference |
|
192 difference = ''.join(list(difseq)[:10]) |
180 if data1 != data2: |
193 if data1 != data2: |
181 if len(ignore_patterns) > 0: |
194 if len(ignore_patterns) > 0: |
|
195 self.write_data_to_file(file1 + '.diff', ''.join(difseq)) |
182 self.write_data_to_file(file1 + '.comparetemp', data1) |
196 self.write_data_to_file(file1 + '.comparetemp', data1) |
183 self.write_data_to_file(file2 + '.comparetemp', data2) |
197 self.write_data_to_file(file2 + '.comparetemp', data2) |
184 self.fail("Data of the files '%s' and '%s' are not equal\nSee *.comparetemp files for the actual data that was compared." % (file1, file2)) |
198 self.fail("Data of the files '%s' and '%s' are not equal\nSee *.comparetemp files for the actual data that was compared.\nDifference %s" % (file1, file2, difference)) |
185 else: |
199 else: |
186 self.fail("Data of the files '%s' and '%s' are not equal" % (file1, file2)) |
200 self.fail("Data of the files '%s' and '%s' are not equal\nDifference %s" % (file1, file2, difference)) |
187 |
201 |
188 def assert_file_content_equals(self, filepath, expected_data): |
202 def assert_file_content_equals(self, filepath, expected_data, ignore_endline_style=False): |
189 """ |
203 """ |
190 Assert that the content of the given file is equals to the given expected data. |
204 Assert that the content of the given file is equals to the given expected data. |
|
205 @param ignore_endline_style: If True, the endline style (CRLF or LF) is |
|
206 ignored during the comparison. |
191 """ |
207 """ |
192 self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath) |
208 self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath) |
193 self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath) |
209 self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath) |
194 |
210 |
195 f = open(filepath, "rb") |
211 f = open(filepath, "rb") |
196 try: filedata = f.read() |
212 try: filedata = f.read() |
197 finally: f.close() |
213 finally: f.close() |
|
214 |
|
215 if ignore_endline_style: |
|
216 filedata = filedata.replace('\r\n', '\n') |
|
217 expected_data = expected_data.replace('\r\n', '\n') |
198 |
218 |
199 if filedata != expected_data: |
219 if filedata != expected_data: |
200 msg = ("The content of the file '%s' is not what was expected!\n" % filepath) +\ |
220 msg = ("The content of the file '%s' is not what was expected!\n" % filepath) +\ |
201 ("Expected: %r\nActual: %r" % (expected_data, filedata)) |
221 ("Expected: %r\nActual: %r" % (expected_data, filedata)) |
202 self.fail(msg) |
222 self.fail(msg) |
203 |
223 |
204 def assert_file_contains(self, filepath, data, encoding=None): |
224 def assert_file_contains(self, filepath, data, encoding=None, regexes=[]): |
205 """ |
225 """ |
206 Assert that the given file contains the given text somewhere in its contents. |
226 Assert that the given file contains the given text somewhere in its contents. |
207 @param filepath: Path to the file to check. |
227 @param filepath: Path to the file to check. |
208 @param data: The data the file is expected to contain. |
228 @param data: The data the file is expected to contain. |
209 @param encoding: Encoding used to decode the contents of the file. |
229 @param encoding: Encoding used to decode the contents of the file. |
210 If None, noe decoding is done. |
230 If None, noe decoding is done. |
|
231 @param regexes: A list of regular expressions that are used to search for |
|
232 a match in the file data. If any of them doesn't find a match, |
|
233 the assertion fails. |
211 """ |
234 """ |
212 self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath) |
235 self.assertTrue(os.path.exists(filepath), "'%s' does not exist!" % filepath) |
213 self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath) |
236 self.assertTrue(os.path.isfile(filepath), "'%s' is not a file!" % filepath) |
214 |
237 |
215 f = open(filepath, "rb") |
238 f = open(filepath, "rb") |
294 self.assertTrue(p.returncode == expected_return_code, |
321 self.assertTrue(p.returncode == expected_return_code, |
295 "Could not execute command (%s)\n"\ |
322 "Could not execute command (%s)\n"\ |
296 "Return code is not what was expected (expected %d, got %d)\n"\ |
323 "Return code is not what was expected (expected %d, got %d)\n"\ |
297 "Output: \n%s" % (command, expected_return_code, p.returncode, out)) |
324 "Output: \n%s" % (command, expected_return_code, p.returncode, out)) |
298 return out |
325 return out |
|
326 |
|
327 def assert_problem_lists_equal(self, actual, expected, outdir): |
|
328 """ |
|
329 Assert that two lists of api.Problem objects are equal. |
|
330 @param actual: The list of actual problems. |
|
331 @param expected: The list of expected problems. |
|
332 @param outdir: The directory where output is written if the assertion |
|
333 fails. |
|
334 """ |
|
335 act = sorted([repr(p) for p in actual]) |
|
336 exp = sorted([repr(p) for p in expected]) |
|
337 if act != exp: |
|
338 if not os.path.exists(outdir): |
|
339 os.makedirs(outdir) |
|
340 self.write_data_to_file(os.path.join(outdir, 'actual.txt'), os.linesep.join(act)) |
|
341 self.write_data_to_file(os.path.join(outdir, 'expected.txt'), os.linesep.join(exp)) |
|
342 self.fail("Problem lists not equal, see the files in '%s'" % outdir) |
|
343 |
|
344 def assert_problem_list_equals_expected(self, actual, expected_file, outdir): |
|
345 """ |
|
346 Assert that the given list of api.Problem objects is equal to the |
|
347 list specified in the given file. |
|
348 @param actual: The list of actual problems. |
|
349 @param expected_file: Path to the file containing the list of |
|
350 expected problems. The file should contain the repr() output |
|
351 for an api.Problem object on each line. |
|
352 @param outdir: The directory where output is written if the assertion |
|
353 fails. |
|
354 """ |
|
355 act = sorted([repr(p) for p in actual]) |
|
356 |
|
357 if not os.path.isfile(expected_file): |
|
358 raise RuntimeError("Expected problem file '%s' does not exist or is not a file!" % expected_file) |
|
359 f = open(expected_file, 'r') |
|
360 try: exp = sorted([line.rstrip('\r\n') for line in f]) |
|
361 finally: f.close() |
|
362 |
|
363 # Delete lines starting with # |
|
364 for i in reversed(range(len(exp))): |
|
365 if exp[i].startswith('#'): |
|
366 del exp[i] |
|
367 |
|
368 if act != exp: |
|
369 if not os.path.exists(outdir): |
|
370 os.makedirs(outdir) |
|
371 self.write_data_to_file(os.path.join(outdir, 'actual.txt'), os.linesep.join(act)) |
|
372 self.write_data_to_file(os.path.join(outdir, 'expected.txt'), os.linesep.join(exp)) |
|
373 self.fail("Problem list is not what was expected, see the files in '%s'" % outdir) |
|
374 |
299 |
375 |
300 # ===================================================== |
376 # ===================================================== |
301 # Private helper methods |
377 # Private helper methods |
302 # ===================================================== |
378 # ===================================================== |
303 |
379 |