expectlib
Installation
$ pip install expectlib
Usage
Importing
from expectlib import expect
Defining vs Executing
The expect
does not execute the comparison on call. It returns a comparison function that will raise an AssertionError
if the comparison fails. You will see in the examples below.
Chain vs Expressive
There are two ways of using expectlib's expect: chain and expressions. The former is more traditional while the latter allows for terse expect expressions by abusing operator overloading.
Chain
The chain syntax should be very familiar if you've used libraries like chai or jasmine.
from expectlib import expect
# Simple equals comparison
# Remember this this does't run the comparison rather returns the comparison as a function.
expect(10).to.equal(10)
# To run the comparison simple call the returned function
expect(10).to.equal(10)()
# This will raise an AssertionError
expect(10).to.equal(100)()
Expressive
The expressive syntax uses operator overloading for terse expect expressions. Let's convert the chain syntax from above:
from expectlib import expect
# Simple equals comparison
# Remember this this does't run the comparison rather returns the comparison as a function.
(expect(10) == 10)
# To run the comparison simple call the returned function
(expect(10) == 10)()
# This will raise an AssertionError
(expect(10) == 100)()
Tip
You can alias the expect
function to e
for brevity's sake.
from expectlib import expect as e
Message
You can define a custom message which is appended to the assertion message.
from expectlib import expect
expect(10).to.equal(100)("Some meaningful failure message")
Comparisons
from expectlib import expect, expect as e
# Type
# Chain syntax
# Expressive syntax
# Equal
expect(10).to.equal(10)()
(e(10) == 10)()
# Negate
expect(10).to._not().equal(100)()
(~e(10) == 100)()
# Greater Than
expect(10).to.be.greater_than(9)()
(e(10) > 9)()
# Less Than
expect(100).to.be.lesser_than(1000)()
(e(100) < 1000)()
# Greater Than Or Equal
expect(10).to.be.greater_than_or_equal(9)
(e(10) >= 9)()
# Less Than Or Equal
expect(100).to.be.lesser_than_or_equal(1000)()
(e(100) <= 1000)()
# True
expect(True).to.be.true()
(e(True) % True)()
# False
expect(False).to.be.false()
(e(False) % False)()
# None
expect(None).to.be.none()
(e(None) % None)()
# Regex Match
expect("foobar").to.match("^foo")()
(e("foobar") // "^foo")()
# Starts With
expect("foobar").to.start_with("foo")()
(e("foobar") << "foo")()
# Ends With
expect("foobar").to.end_with("bar")()
(e("foobar") >> "bar")()
# Contains
expect(["foo", "bar"]).to.contain("foo")()
(e(["foo", "bar"]) ^ "foo")()
# Empty
expect([]).to.be.empty()()
Expression Cheatsheet
-
==
Equals -
~
Negate -
>
Greater Than -
<
Less Than -
<=
Greater Than Or Equal -
>=
Less Than Or Equal -
%
True, False, None -
//
Regex Match -
<<
Starts With -
>>
Ends With -
^
Contains
Integration
Built on AssertionError
All comparisons raise an AssertionError
so integration in to your tests should be seamless.
Callbacks
There are two callbacks provided for integration: on_init
& on_compare
.
on_init(comparison)
The on_init
callback is called when the comparison is initialized. The Comparison
instance is passed.
on_compare(result, message)
The on_compare
callback is called after the comparison has been called. The result
boolean and `message string are passed.
from expectlib.comparison import Comparison
def print_comparison(comparison):
print(comparison)
def print_compare(result, message):
print((result, message))
Comparison.on_init = staticmethod(print_comparison)
Comparison.on_compare = staticmethod(print_compare)