Skip to content

Commit

Permalink
Property-ize the _to_logs. (ScreenPyHQ#133)
Browse files Browse the repository at this point in the history
* move all '_to_log' items to properties.

* fix test after change in IsInRange description.

* property-ize a couple more.
  • Loading branch information
perrygoy authored Feb 26, 2024
1 parent 8ba7ff8 commit 4195dee
Show file tree
Hide file tree
Showing 22 changed files with 181 additions and 56 deletions.
6 changes: 5 additions & 1 deletion screenpy/actions/attach_the_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ class AttachTheFile:
)
"""

@property
def filename(self) -> str:
"""Get the filename from the filepath."""
return os.path.basename(self.filepath)

def describe(self) -> str:
"""Describe the Action in present tense."""
return f"Attach a file named {self.filename}."
Expand All @@ -34,5 +39,4 @@ def perform_as(self, _: Actor) -> None:
# ANN401 ignored here to allow for new adapters to use any kwargs.
def __init__(self, filepath: str, **kwargs: Any) -> None: # noqa: ANN401
self.filepath = filepath
self.filename = os.path.basename(filepath)
self.attach_kwargs = kwargs
6 changes: 5 additions & 1 deletion screenpy/actions/eventually.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ def trying_every(self, amount: float) -> _TimeframeBuilder:
"""Alias for :meth:`~screenpy.actions.Eventually.polling`."""
return self.polling(amount)

@property
def performable_to_log(self) -> str:
"""Represent the Performable in a log-friendly way."""
return get_additive_description(self.performable)

def describe(self) -> str:
"""Describe the Action in present tense."""
return f"Eventually {self.performable_to_log}."
Expand Down Expand Up @@ -159,7 +164,6 @@ def perform_as(self, the_actor: Actor) -> None:

def __init__(self, performable: Performable) -> None:
self.performable = performable
self.performable_to_log = get_additive_description(self.performable)
self.caught_error = None
self.unique_errors: list[BaseException] = []
self.timeout = settings.TIMEOUT
Expand Down
6 changes: 5 additions & 1 deletion screenpy/actions/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ def the(cls, question: T_Q) -> Self:
"""Supply the Question to answer."""
return cls(question)

@property
def question_to_log(self) -> str:
"""Represent the Question in a log-friendly way."""
return get_additive_description(self.question)

@beat("{} examines {question_to_log}.")
def perform_as(self, the_actor: Actor) -> None:
"""Direct the Actor to announce the answer to the Question."""
Expand All @@ -44,4 +49,3 @@ def perform_as(self, the_actor: Actor) -> None:

def __init__(self, question: T_Q) -> None:
self.question = question
self.question_to_log = get_additive_description(self.question)
10 changes: 6 additions & 4 deletions screenpy/actions/make_note.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ class MakeNote:
"""

key: str | None
key_to_log: str | None
question: T_Q

@classmethod
Expand All @@ -57,12 +56,16 @@ def of_the(cls, question: T_Q) -> Self:
def as_(self, key: str) -> Self:
"""Set the key to use to recall this noted value."""
self.key = key
self.key_to_log = represent_prop(key)
return self

@property
def key_to_log(self) -> str | None:
"""Represent the key in a log-friendly way."""
return represent_prop(self.key)

def describe(self) -> str:
"""Describe the Action in present tense."""
return f"Make a note under {represent_prop(self.key)}."
return f"Make a note under {self.key_to_log}."

@beat("{} jots something down under {key_to_log}.")
def perform_as(self, the_actor: Actor) -> None:
Expand Down Expand Up @@ -90,4 +93,3 @@ def __init__(
) -> None:
self.question = question
self.key = key
self.key_to_log = represent_prop(key)
14 changes: 10 additions & 4 deletions screenpy/actions/see.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,23 @@ class See:
"""

question: T_Q
question_to_log: str
resolution: T_R
resolution_to_log: str

@classmethod
def the(cls, question: T_Q, resolution: T_R) -> Self:
"""Supply the Question (or value) and Resolution to test."""
return cls(question, resolution)

@property
def question_to_log(self) -> str:
"""Represent the Question in a log-friendly way."""
return get_additive_description(self.question)

@property
def resolution_to_log(self) -> str:
"""Represent the Resolution in a log-friendly way."""
return get_additive_description(self.resolution)

def describe(self) -> str:
"""Describe the Action in present tense."""
return f"See if {self.question_to_log} is {self.resolution_to_log}."
Expand All @@ -72,6 +80,4 @@ def perform_as(self, the_actor: Actor) -> None:

def __init__(self, question: T_Q, resolution: T_R) -> None:
self.question = question
self.question_to_log = get_additive_description(question)
self.resolution = resolution
self.resolution_to_log = get_additive_description(resolution)
16 changes: 12 additions & 4 deletions screenpy/resolutions/contains_the_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ class ContainsTheEntry:
the_actor.should(See.the(MathTestAnswers(), ContainsTheEntry("Problem3", 45)))
"""

@property
def entry_plural(self) -> str:
"""Decide if we need "entry" or "entries" in the beat message."""
return "entries" if len(self.entries) != 1 else "entry"

@property
def entries_to_log(self) -> str:
"""Represent the entries in a log-friendly way."""
return ", ".join(
f"{represent_prop(k)}->{represent_prop(v)}" for k, v in self.entries.items()
)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"A mapping with the {self.entry_plural} {self.entries_to_log}."
Expand Down Expand Up @@ -77,7 +89,3 @@ def __init__(self, *kv_args: Any, **kv_kwargs: Any) -> None:
(kv_args[i], kv_args[i + 1]) for i in range(0, len(kv_args), 2)
]
self.entries = dict(pairs, **kv_kwargs)
self.entry_plural = "entries" if len(self.entries) != 1 else "entry"
self.entries_to_log = ", ".join(
f"{represent_prop(k)}->{represent_prop(v)}" for k, v in self.entries.items()
)
14 changes: 11 additions & 3 deletions screenpy/resolutions/contains_the_item.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Matches a list that contains the desired item."""

from typing import Generic, Sequence, TypeVar
from __future__ import annotations

from typing import TYPE_CHECKING, Generic, Sequence, TypeVar

from hamcrest import has_item
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from hamcrest.core.matcher import Matcher

T = TypeVar("T")


Expand All @@ -21,6 +25,11 @@ class ContainsTheItem(Generic[T]):
)
"""

@property
def item_to_log(self) -> str | T:
"""Represent the item in a log-friendly way."""
return represent_prop(self.item)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"A sequence containing {self.item_to_log}."
Expand All @@ -32,4 +41,3 @@ def resolve(self) -> Matcher[Sequence[T]]:

def __init__(self, item: T) -> None:
self.item = item
self.item_to_log = represent_prop(item)
14 changes: 11 additions & 3 deletions screenpy/resolutions/contains_the_key.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Matches a dictionary that contains the desired key."""

from typing import Any, Generic, Hashable, Mapping, TypeVar
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Generic, Hashable, Mapping, TypeVar

from hamcrest import has_key
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from hamcrest.core.matcher import Matcher

K = TypeVar("K", bound=Hashable)


Expand All @@ -19,6 +23,11 @@ class ContainsTheKey(Generic[K]):
the_actor.should(See.the(LastResponseBody(), ContainsTheKey("skeleton")))
"""

@property
def key_to_log(self) -> str | K:
"""Represent the key in a log-friendly way."""
return represent_prop(self.key)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Containing the key {self.key_to_log}."
Expand All @@ -30,4 +39,3 @@ def resolve(self) -> Matcher[Mapping[K, Any]]:

def __init__(self, key: K) -> None:
self.key = key
self.key_to_log = represent_prop(key)
6 changes: 5 additions & 1 deletion screenpy/resolutions/contains_the_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class ContainsTheText:
)
"""

@property
def text_to_log(self) -> str:
"""Represent the text in a log-friendly way."""
return represent_prop(self.text)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Containing the text {self.text_to_log}."
Expand All @@ -28,4 +33,3 @@ def resolve(self) -> Matcher[str]:

def __init__(self, text: str) -> None:
self.text = text
self.text_to_log = represent_prop(text)
14 changes: 11 additions & 3 deletions screenpy/resolutions/contains_the_value.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Matches a dictionary that contains a specific value."""

from typing import Any, Generic, Mapping, TypeVar
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Generic, Mapping, TypeVar

from hamcrest import has_value
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from hamcrest.core.matcher import Matcher

V = TypeVar("V")


Expand All @@ -21,6 +25,11 @@ class ContainsTheValue(Generic[V]):
)
"""

@property
def value_to_log(self) -> str | V:
"""Represent the value in a log-friendly way."""
return represent_prop(self.value)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Containing the value {self.value_to_log}."
Expand All @@ -32,4 +41,3 @@ def resolve(self) -> Matcher[Mapping[Any, V]]:

def __init__(self, value: V) -> None:
self.value = value
self.value_to_log = represent_prop(value)
6 changes: 5 additions & 1 deletion screenpy/resolutions/ends_with.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class EndsWith:
)
"""

@property
def postfix_to_log(self) -> str:
"""Represent the postfix in a log-friendly way."""
return represent_prop(self.postfix)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Ending with {self.postfix_to_log}."
Expand All @@ -28,4 +33,3 @@ def resolve(self) -> Matcher[str]:

def __init__(self, postfix: str) -> None:
self.postfix = postfix
self.postfix_to_log = represent_prop(postfix)
10 changes: 7 additions & 3 deletions screenpy/resolutions/has_length.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ class HasLength:
)
"""

@property
def item_plural(self) -> str:
"""Decide if we need "item" or "items" in the beat message."""
return "items" if self.length != 1 else "item"

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"{self.length} item{self.plural} long."
return f"{self.length} {self.item_plural} long."

@beat("... hoping it's a collection with {length} item{plural} in it.")
@beat("... hoping it's a collection with {length} {item_plural} in it.")
def resolve(self) -> Matcher[Sized]:
"""Produce the Matcher to make the assertion."""
return has_length(self.length)

def __init__(self, length: int) -> None:
self.length = length
self.plural = "s" if self.length != 1 else ""
14 changes: 11 additions & 3 deletions screenpy/resolutions/is_equal_to.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Matches using equality."""

from typing import Any
from __future__ import annotations

from typing import TYPE_CHECKING, Any

from hamcrest import equal_to
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from hamcrest.core.matcher import Matcher


class IsEqualTo:
"""Match on an equal object.
Expand All @@ -19,6 +23,11 @@ class IsEqualTo:
)
"""

@property
def expected_to_log(self) -> str | object:
"""Represent the expected object in a log-friendly way."""
return represent_prop(self.expected)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Equal to {self.expected_to_log}."
Expand All @@ -30,4 +39,3 @@ def resolve(self) -> Matcher[Any]:

def __init__(self, obj: object) -> None:
self.expected = obj
self.expected_to_log = represent_prop(obj)
14 changes: 11 additions & 3 deletions screenpy/resolutions/is_greater_than.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
"""Matches a value greater than the given number."""

from typing import Any
from __future__ import annotations

from typing import TYPE_CHECKING, Any

from hamcrest import greater_than
from hamcrest.core.matcher import Matcher

from screenpy.pacing import beat
from screenpy.speech_tools import represent_prop

if TYPE_CHECKING:
from hamcrest.core.matcher import Matcher


class IsGreaterThan:
"""Match on a number that is greater than the given number.
Expand All @@ -17,6 +21,11 @@ class IsGreaterThan:
the_actor.should(See.the(Number.of(COUPONS), IsGreaterThan(1)))
"""

@property
def number_to_log(self) -> str | float:
"""Represent the number in a log-friendly way."""
return represent_prop(self.number)

def describe(self) -> str:
"""Describe the Resolution's expectation."""
return f"Greater than {self.number_to_log}."
Expand All @@ -28,4 +37,3 @@ def resolve(self) -> Matcher[Any]:

def __init__(self, number: float) -> None:
self.number = number
self.number_to_log = represent_prop(number)
Loading

0 comments on commit 4195dee

Please sign in to comment.