diff options
| author | Takayuki SHIMIZUKAWA <shimizukawa@gmail.com> | 2019-01-13 18:40:35 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-13 18:40:35 +0900 |
| commit | 795b51846484a5465c821873a19d32567e1d4e32 (patch) | |
| tree | 2998d89b2b36c54a06dbf36b23277803c61ee7c2 /sphinx/testing | |
| parent | 75afed1549cd273c5b69e4388b2a8ab77cd523cc (diff) | |
| download | sphinx-git-795b51846484a5465c821873a19d32567e1d4e32.tar.gz | |
Add PathComparer for testing and fix 2 test failure on Windows. (#5943)
commits are squashed.
* Add PathComparer for testing and fix 2 test failure on Windows.
* fix flake8
* add type information by f2f review. Thanks to @tk0miya!
* fix mypy, flake8 again..
Diffstat (limited to 'sphinx/testing')
| -rw-r--r-- | sphinx/testing/comparer.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/sphinx/testing/comparer.py b/sphinx/testing/comparer.py new file mode 100644 index 000000000..45cae8dde --- /dev/null +++ b/sphinx/testing/comparer.py @@ -0,0 +1,101 @@ +""" + sphinx.testing.comparer + ~~~~~~~~~~~~~~~~~~~~~~~ + + Sphinx test comparer for pytest + + :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +""" +import difflib +import pathlib +from typing import List, Union + + +class PathComparer: + """ + OS-independent path comparison. + + Windows path sep and posix path sep: + + >>> '\\to\\index' == PathComparer('/to/index') + True + >>> '\\to\\index' == PathComparer('/to/index2') + False + + Windows path with drive letters + + >>> 'C:\\to\\index' == PathComparer('/to/index') + True + >>> 'C:\\to\\index' == PathComparer('C:/to/index') + True + >>> 'C:\\to\\index' == PathComparer('D:/to/index') + False + """ + def __init__(self, path: Union[str, pathlib.Path]): + """ + :param str path: path string, it will be cast as pathlib.Path. + """ + self.path = pathlib.Path(path) + + def __str__(self): + return self.path.as_posix() + + def __repr__(self): + return "<{0.__class__.__name__}: '{0}'>".format(self) + + def __eq__(self, other): + return not bool(self.ldiff(other)) + + def diff(self, other: Union[str, pathlib.Path]) -> List[str]: + """compare self and other. + + When different is not exist, return empty list. + + >>> PathComparer('/to/index').diff('C:\\to\\index') + [] + + When different is exist, return unified diff style list as: + + >>> PathComparer('/to/index').diff('C:\\to\\index2') + [ + '- C:/to/index' + '+ C:/to/index2' + '? +' + ] + """ + return self.ldiff(other) + + def ldiff(self, other: Union[str, pathlib.Path]) -> List[str]: + return self._diff( + self.path, + pathlib.Path(other), + ) + + def rdiff(self, other: Union[str, pathlib.Path]) -> List[str]: + return self._diff( + pathlib.Path(other), + self.path, + ) + + def _diff(self, lhs: pathlib.Path, rhs: pathlib.Path) -> List[str]: + if lhs == rhs: + return [] + + if lhs.drive or rhs.drive: + # If either has a drive letter compare by absolute path + s_path, o_path = lhs.absolute().as_posix(), rhs.absolute().as_posix() + else: + s_path, o_path = lhs.as_posix(), rhs.as_posix() + + if s_path == o_path: + return [] + + return [line.strip() for line in difflib.Differ().compare([s_path], [o_path])] + + +def pytest_assertrepr_compare(op, left, right): + if isinstance(left, PathComparer) and op == "==": + return ['Comparing path:'] + left.ldiff(right) + if isinstance(right, PathComparer) and op == "==": + return ['Comparing path:'] + right.rdiff(left) |
