Skip to content

Commit

Permalink
allowing Matches to accept re.compile
Browse files Browse the repository at this point in the history
  • Loading branch information
bandophahita committed Mar 19, 2024
1 parent 22adbc5 commit 89da8d8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
22 changes: 18 additions & 4 deletions screenpy/resolutions/matches.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
"""Matches a string using a regex pattern."""

from __future__ import annotations

from re import Pattern
from typing import TYPE_CHECKING

from hamcrest import matches_regexp
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat

if TYPE_CHECKING: # pragma: no cover
from hamcrest.core.matcher import Matcher


class Matches:
"""Match a string using a regular expression.
Expand All @@ -17,14 +24,21 @@ class Matches:
)
"""

@property
def item_to_log(self) -> str:
"""Represent the item in a log-friendly way."""
if isinstance(self.pattern, Pattern):
return f"r'{self.pattern.pattern}'"
return f"r'{self.pattern}'"

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f'Text matching the pattern r"{self.pattern}".'
return f"Text matching the pattern {self.item_to_log}."

@beat('... hoping it\'s text matching the pattern r"{pattern}".')
@beat("... hoping it's text matching the pattern {item_to_log}.")
def resolve(self) -> Matcher[str]:
"""Produce the Matcher to make the assertion."""
return matches_regexp(self.pattern)

def __init__(self, pattern: str) -> None:
def __init__(self, pattern: str | Pattern[str]) -> None:
self.pattern = pattern
27 changes: 26 additions & 1 deletion tests/test_resolutions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import logging
import re
from itertools import chain
from unittest import mock

Expand Down Expand Up @@ -570,12 +572,35 @@ def test_the_test(self) -> None:
assert m.matches("Spam spam spam spam baked beans and spam")
assert not m.matches("What do you mean Eugh?!")

def test_the_test_with_compile(self) -> None:
m = Matches(re.compile(r"([Ss]pam ?)+")).resolve()

assert m.matches("Spam spam spam spam baked beans and spam")
assert not m.matches("What do you mean Eugh?!")

def test_description(self) -> None:
test_match = r"(spam)+"

m = Matches(test_match)

expected_description = 'Text matching the pattern r"(spam)+".'
expected_description = "Text matching the pattern r'(spam)+'."
assert m.describe() == expected_description

def test_beat_logging(self, caplog: pytest.LogCaptureFixture) -> None:
caplog.set_level(logging.INFO)
Matches(r"pattern").resolve()

assert [r.msg for r in caplog.records] == [
"... hoping it's text matching the pattern r'pattern'.",
" => a string matching 'pattern'",
]

def test_description_with_compile(self) -> None:
test_match = re.compile(r"(spam)+")

m = Matches(test_match)

expected_description = "Text matching the pattern r'(spam)+'."
assert m.describe() == expected_description


Expand Down

0 comments on commit 89da8d8

Please sign in to comment.