diff --git a/changelog.d/170.feature.rst b/changelog.d/170.feature.rst new file mode 100644 index 00000000..8c4acbb1 --- /dev/null +++ b/changelog.d/170.feature.rst @@ -0,0 +1 @@ +* Add pretty string representation for matchers objects \ No newline at end of file diff --git a/src/hamcrest/core/base_matcher.py b/src/hamcrest/core/base_matcher.py index c1c01ea4..7edc994f 100644 --- a/src/hamcrest/core/base_matcher.py +++ b/src/hamcrest/core/base_matcher.py @@ -1,3 +1,4 @@ +from textwrap import shorten from typing import Optional, TypeVar from hamcrest.core.description import Description @@ -25,6 +26,12 @@ class BaseMatcher(Matcher[T]): def __str__(self) -> str: return tostring(self) + def __repr__(self) -> str: + """Returns matcher string representation.""" + return "<{0}({1})>".format( + self.__class__.__name__, shorten(tostring(self), 60, placeholder="...") + ) + def _matches(self, item: T) -> bool: raise NotImplementedError("_matches") diff --git a/tests/hamcrest_unit_test/base_matcher_test.py b/tests/hamcrest_unit_test/base_matcher_test.py index 1817388a..5ad2a610 100644 --- a/tests/hamcrest_unit_test/base_matcher_test.py +++ b/tests/hamcrest_unit_test/base_matcher_test.py @@ -37,6 +37,19 @@ def testMismatchDescriptionShouldDescribeItem(self): def testMatchDescriptionShouldDescribeItem(self): assert_match_description("was <99>", PassingBaseMatcher(), 99) + def testMatcherReprShouldDescribeMatcher(self): + assert repr(FailingBaseMatcher()) == "" + + def testMatcherReprShouldTruncateLongDescription(self): + class LongDescriptionMatcher(BaseMatcher): + def describe_to(self, description): + description.append_text("1234 " * 13) + + assert ( + repr(LongDescriptionMatcher()) + == "" + ) + if __name__ == "__main__": unittest.main()