Skip to content

petuzk/predeq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

51 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

predeq

PredEq is a utility for testing objects using an equivalence predicate. It facilitates writing declarative-style tests for complex requirements, and for cases where the default __eq__ is inapplicable or missing.

At its core, predeq(predicate) is an object which tests equal to X if predicate(X) returns True.

from predeq import predeq, instanceof


def test_tuple_of_int_and_str():
    """Test that value is a tuple of an int and a string."""

    value = (123, 'abc')

    # without predeq
    assert isinstance(value, tuple) and len(value) == 2
    assert isinstance(value[0], int)
    assert isinstance(value[1], str)

    # with predeq
    assert value == (
       predeq(lambda x: isinstance(x, int)),  # provide your own predicate
       instanceof(str),                       # or use one of the recipes
    )

Since PredEq is primarily designed for tests, it also tries to be helpful when they fail. If lambda is used as a predicate, predeq attempts to locate its source code and show it in pytest output:

==================================== FAILURES ====================================
_______________________ test_tuple_of_int_and_str_issue_1 ________________________

    def test_tuple_of_int_and_str_issue_1():
        value = (123.0, 'abc')

>       assert value == (
            predeq(lambda x: isinstance(x, int)),
            instanceof(str),
        )
E       AssertionError: assert (123.0, 'abc') == (<predeq to m...stanceof(str))
E
E         At index 0 diff: 123.0 != <predeq to meet lambda x: isinstance(x, int)>
E         Use -v to get more diff

Each built-in recipe also provides a readable representation, which typically looks like the corresponding code:

==================================== FAILURES ====================================
_______________________ test_tuple_of_int_and_str_issue_2 ________________________

    def test_tuple_of_int_and_str_issue_2():
        value = (123, b'abc')

>       assert value == (
            predeq(lambda x: isinstance(x, int)),
            instanceof(str),
        )
E       AssertionError: assert (123, b'abc') == (<predeq to m...stanceof(str))
E
E         At index 1 diff: b'abc' != instanceof(str)
E         Use -v to get more diff

About

Predicate-based equivalence testing

Resources

License

Stars

Watchers

Forks

Languages