Skip to content

Commit

Permalink
[#530] TEST: ensure passing Condition to Match as by works...
Browse files Browse the repository at this point in the history
... in case of custom falsy_exceptions set for Condition
  • Loading branch information
yashaka committed Jul 19, 2024
1 parent 67c2cce commit 0ed4982
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 7 deletions.
4 changes: 0 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,6 @@ check vscode pylance, mypy, jetbrains qodana...

consider customizing them via config

### TODO: when to Match we pass by as Condition, that has its own _falsy_exceptions...

should not we take them to set below, or at least override our default?

### Deprecated conditions

- `be.present` in favor of `be.present_in_dom`
Expand Down
10 changes: 8 additions & 2 deletions selene/core/condition.py
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,7 @@ def __init__(
_by: Predicate[R] | None = None,
_describe_actual_result: Lambda[R, str] | None = None,
_inverted=False,
# todo: should we find more "human-readable" name? like in Wait(at_most) over Wait(timeout)
_falsy_exceptions: Iterable[Type[Exception]] = (AssertionError,),
):
# can be already stored
Expand Down Expand Up @@ -1699,9 +1700,14 @@ def __init__(
name,
by,
_inverted=_inverted,
# TODO: since by is Condition, already defined with its _falsy_exceptions...
# should not we take them to set below, or at least override our default?
_falsy_exceptions=_falsy_exceptions,
# Seems like the following is not needed, because by will catch everything internally
# – See also unit tests for this case
# todo: once finalized naming of falsy_exceptions, consider making it protected
# for easier access in cases like here...
# _falsy_exceptions=getattr(
# by, f'_{by.__class__.__name__}__falsy_exceptions', _falsy_exceptions
# ),
)
else:
# todo: fix "cannot infer type of argument 1 of __init__" or ignore
Expand Down
141 changes: 140 additions & 1 deletion tests/unit/core/condition_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,145 @@ def test___init__renamed_match_not__of_constructed_via__init__actual_by_compared
assert 'condition not matched' == str(error)


# TODO: add InvalidCompareError tests (positive and negative)
def test_constructed_via_Match__init__actual_by_n_falsy_exc__compared():
# GIVEN
# - compare definition
nth_positive__________________ = lambda number: Match(
f'element number {number} is positive',
actual=lambda iterable: iterable[number - 1],
by=lambda nth: nth > 0,
)
nth_positive__falsy_IndexError = lambda number: Match(
f'element number {number} is positive',
actual=lambda iterable: iterable[number - 1],
by=lambda nth: nth > 0,
_falsy_exceptions=(AssertionError, IndexError),
)

# THEN as is
# - compare name
assert 'element number 2 is positive' == str(nth_positive__________________(2))
assert 'element number 2 is positive' == str(nth_positive__falsy_IndexError(2))
# - compare pass
nth_positive__________________(2)._test([0, 1, 0])
nth_positive__falsy_IndexError(2)._test([0, 1, 0])
# - compare fail (mismatch)
try:
nth_positive__________________(3)([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'actual: 0' == str(error)
try:
nth_positive__falsy_IndexError(3)([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'actual: 0' == str(error)
# - compare fail (IndexError) vs fail (AssertionError)
try:
nth_positive__________________(4)([0, 1, 0])
pytest.fail('on failure')
except IndexError as error: # ⬅️❗
assert 'list index out of range' == str(error)
try:
nth_positive__falsy_IndexError(4)([0, 1, 0])
pytest.fail('on failure')
except AssertionError as error: # ⬅️❗️
assert 'list index out of range' == str(error)

# THEN inverted
# - compare name
assert 'not (element number 2 is positive)' == str(
nth_positive__________________(2).not_
)
assert 'not (element number 2 is positive)' == str(
nth_positive__falsy_IndexError(2).not_
)
# - compare pass (inverted mismatch)
nth_positive__________________(3).not_([0, 1, 0])
nth_positive__falsy_IndexError(3).not_([0, 1, 0])
# - compare fail vs pass (inverted failure)
try:
nth_positive__________________(4).not_([0, 1, 0])
pytest.fail('on failure')
except IndexError as error: # ⬅️❗
assert 'list index out of range' == str(error)
nth_positive__falsy_IndexError(4).not_([0, 1, 0])
# - compare fail (inverted mismatch)
try:
nth_positive__________________(2).not_([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'actual: 1' == str(error)
try:
nth_positive__falsy_IndexError(2).not_([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'actual: 1' == str(error)

# THEN renamed inverted
# - compare name
assert 'not (2nd is positive)' == str(
Match('2nd is positive', by=nth_positive__________________(2)).not_
)
assert 'not (2nd is positive)' == str(
Match('2nd is positive', by=nth_positive__falsy_IndexError(2)).not_
)
# - compare pass (inverted mismatch)
Match('3rd is positive', by=nth_positive__________________(3)).not_([0, 1, 0])
Match('3rd is positive', by=nth_positive__falsy_IndexError(3)).not_([0, 1, 0])
# - compare fail vs pass (inverted failure)
try:
Match('4th is positive', by=nth_positive__________________(4)).not_([0, 1, 0])
pytest.fail('on failure')
except IndexError as error:
assert 'list index out of range' == str(error)
Match('4th is positive', by=nth_positive__falsy_IndexError(4)).not_([0, 1, 0])
# - compare fail (inverted mismatch)
try:
Match('2nd is positive', by=nth_positive__________________(2)).not_([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'condition not matched' == str(error) # 😢 # todo: can we improve it?
try:
Match('2nd is positive', by=nth_positive__falsy_IndexError(2)).not_([0, 1, 0])
pytest.fail('on mismatch')
except AssertionError as error:
assert 'condition not matched' == str(error)

# THEN inverted renamed
# - compare name
assert '2nd is negative or zero' == str(
Match('2nd is negative or zero', by=nth_positive__________________(2).not_)
)
assert '2nd is negative or zero' == str(
Match('2nd is negative or zero', by=nth_positive__falsy_IndexError(2).not_)
)
# - compare pass (inverted mismatch)
Match('3rd is negative or zero', by=nth_positive__________________(3).not_)(
[0, 1, 0]
)
Match('3rd is negative or zero', by=nth_positive__falsy_IndexError(3).not_)(
[0, 1, 0]
)
# - compare fail vs pass (inverted failure)
try:
Match('4th is negative or zero', by=nth_positive__________________(4).not_)(
[0, 1, 0]
)
pytest.fail('on failure')
except IndexError as error:
assert 'list index out of range' == str(error)
Match('4th is negative or zero', by=nth_positive__falsy_IndexError(4).not_)(
[0, 1, 0]
)
# - compare fail (inverted mismatch)
try:
Match('2nd is negative or zero', by=nth_positive__________________(2).not_)(
[0, 1, 0]
)
pytest.fail('on mismatch')
except AssertionError as error:
assert 'actual: 1' == str(error)


# TODO: cover subclass based conditions

0 comments on commit 0ed4982

Please sign in to comment.