You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.8 KiB
104 lines
2.8 KiB
"""
|
|
sphinx.testing.comparer
|
|
~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Sphinx test comparer for pytest
|
|
|
|
:copyright: Copyright 2007-2020 by the Sphinx team, see AUTHORS.
|
|
:license: BSD, see LICENSE for details.
|
|
"""
|
|
import difflib
|
|
import pathlib
|
|
from typing import Any, 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) -> str:
|
|
return self.path.as_posix()
|
|
|
|
def __repr__(self) -> str:
|
|
return "<{0.__class__.__name__}: '{0}'>".format(self)
|
|
|
|
def __eq__(self, other: Union[str, pathlib.Path]) -> bool: # type: ignore
|
|
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: str, left: Any, right: Any) -> List[str]:
|
|
if isinstance(left, PathComparer) and op == "==":
|
|
return ['Comparing path:'] + left.ldiff(right)
|
|
elif isinstance(right, PathComparer) and op == "==":
|
|
return ['Comparing path:'] + right.rdiff(left)
|
|
else:
|
|
return []
|