| # Copyright 2016 The Chromium Authors. All rights reserved. | |
| # Use of this source code is governed by a BSD-style license that can be | |
| # found in the LICENSE file. | |
| """A utility function to do text diffs of expected and actual layout test results.""" | |
| import difflib | |
| def unified_diff(expected_text, actual_text, expected_filename, actual_filename): | |
| """Returns a string containing the diff of the two text strings | |
| in 'unified diff' format. | |
| """ | |
| # The filenames show up in the diff output, make sure they're | |
| # raw bytes and not unicode, so that they don't trigger join() | |
| # trying to decode the input. | |
| expected_filename = _to_raw_bytes(expected_filename) | |
| actual_filename = _to_raw_bytes(actual_filename) | |
| diff = difflib.unified_diff( | |
| expected_text.splitlines(True), | |
| actual_text.splitlines(True), | |
| expected_filename, | |
| actual_filename) | |
| return ''.join(_diff_fixup(diff)) | |
| def _to_raw_bytes(string_value): | |
| if isinstance(string_value, unicode): | |
| return string_value.encode('utf-8') | |
| return string_value | |
| def _diff_fixup(diff): | |
| # The diff generated by the difflib is incorrect if one of the files | |
| # does not have a newline at the end of the file and it is present in | |
| # the diff. Relevant Python issue: http://bugs.python.org/issue2142 | |
| for line in diff: | |
| yield line | |
| if not line.endswith('\n'): | |
| yield '\n\\ No newline at end of file\n' |