A library for creating fluent, readable, and composable checks for your tests or application logic.
Project description
Fluent Checks
A Python library for creating fluent, readable, and composable checks for your tests or application logic.
Installation
Install the package using pip:
pip install fluent-checks
Core Concepts
The core of the library is the abstract Check class. A Check is a simple wrapper around a function that returns a boolean (Condition). For custom logic, you use CustomCheck.
from fluent_checks import CustomCheck
# Create a check from a lambda
is_even = CustomCheck(lambda: 2 % 2 == 0)
# The base class for all checks is `Check`.
# You can evaluate any check directly in a boolean context.
if is_even:
print("It's even!")
# Or more explicitly
assert is_even.check() is True
Usage
Combining Checks
Checks can be combined using logical operators to create more complex conditions.
from fluent_checks import CustomCheck
a = CustomCheck(lambda: True)
b = CustomCheck(lambda: False)
assert (a & b).check() is False # And
assert (a | b).check() is True # Or
assert (~b).check() is True # Not
Waiting for Conditions
You can wait for a condition to become true.
import time
from datetime import timedelta
from fluent_checks import CustomCheck
start_time = time.time()
wait_check = CustomCheck(lambda: time.time() - start_time > 1)
# Block indefinitely until a check passes
wait_check.wait()
assert wait_check.check() is True
# Check if something becomes true within a timeout
passing_check = CustomCheck(lambda: True).with_delay(timedelta(seconds=1))
assert passing_check.within(timedelta(seconds=2)) is True
failing_check = CustomCheck(lambda: True).with_delay(timedelta(seconds=2))
assert failing_check.within(timedelta(seconds=1)) is False
# `eventually` is a convenient alias for `within`
assert passing_check.eventually(timedelta(seconds=2)) is True
Repeating Checks
You can verify that a condition holds true multiple times.
import random
from fluent_checks import CustomCheck
# any_attempt: True if the check passes at least once in 10 attempts
flaky_check = CustomCheck(lambda: random.random() > 0.8)
flaky_check.any_attempt(10)
# all_attempts: True if the check passes 5 times in a row
stable_check = CustomCheck(lambda: True)
assert stable_check.all_attempts(5)
Background Checks
You can run any check in a background thread.
import time
from datetime import timedelta
from fluent_checks import CustomCheck
# Run a long-running check in the background
long_check = CustomCheck(lambda: True).with_delay(timedelta(seconds=1))
background_check = long_check.background()
# You can start it and check on it later
background_check.start()
assert background_check.is_finished().check() is False
time.sleep(1.1)
assert background_check.is_finished().check() is True
assert background_check.result() is True
Checking for Exceptions
You can check that a piece of code raises a specific exception.
from fluent_checks import CustomCheck
def might_fail():
raise ValueError("Something went wrong")
check = CustomCheck(might_fail).raises(ValueError)
assert check.check() is True
Callbacks
You can add callbacks to your checks that will be executed on success or on failure.
from fluent_checks import CustomCheck
a = CustomCheck(lambda: True)
a.on_success(lambda: print("I've passed"))
a.on_failure(lambda: print("I've failed"))
a.check() # This will print "I've passed"
File System Checks
You can use pre-built factory functions to check the file system.
from pathlib import Path
from fluent_checks import file_exists, dir_exists, file_contains
# (Example using pytest's tmp_path fixture)
def test_fs(tmp_path: Path):
# Check if a file exists
my_file = tmp_path / "file.txt"
my_file.touch()
assert file_exists(my_file)
# Check if a directory exists
my_dir = tmp_path / "dir"
my_dir.mkdir()
assert dir_exists(my_dir)
# Check if a file contains specific content
my_file.write_text("hello")
assert file_contains(my_file, b"hello")
Comparison Checks
You can use factory functions to compare values.
from fluent_checks import is_equal, is_not_equal, is_greater_than, is_less_than, is_in, is_instance_of
# Equality
assert is_equal(1, 1)
assert is_not_equal(1, 2)
# Comparison
assert is_greater_than(2, 1)
assert is_less_than(1, 2)
# Containment
assert is_in(1, [1, 2, 3])
# Instance
assert is_instance_of(1, int)
API Overview
Base Check Methods
| Method | Description |
|---|---|
.check() |
Evaluates the check and returns the boolean result. |
&, |, ~ |
Operators for AND, OR, and NOT logic. |
.on_success(callback) |
Registers a callback to be executed when the check succeeds. |
.on_failure(callback) |
Registers a callback to be executed when the check fails. |
.all_attempts(times) |
Checks if the condition is met consecutively for a number of tries. |
.any_attempt(times) |
Checks if the condition is met at least once within a number of tries. |
.before(deadline) |
Checks if the condition becomes true before a specific datetime. |
.within(timeout) |
Checks if the condition becomes true within a certain timedelta. |
.eventually(timeout) |
An alias for within. |
.wait() |
Blocks indefinitely until the check returns True. |
.raises(exception) |
Checks if the condition raises a specific exception. |
.with_delay(delay) |
Returns a new check that waits for a delay before executing. |
.background() |
Returns a BackgroundCheck wrapper to run the check in a thread. |
Filesystem Functions
| Function | Description |
|---|---|
file_exists(path: Path) |
Checks if a file exists at the given path. |
dir_exists(path: Path) |
Checks if a directory exists at the given path. |
file_contains(path: Path, content: bytes) |
Checks if a file contains the given bytes. |
Comparison Functions
| Function | Description |
|---|---|
is_equal(left, right) |
Checks if left == right. |
is_not_equal(left, right) |
Checks if left != right. |
is_greater_than(left, right) |
Checks if left > right. |
is_less_than(left, right) |
Checks if left < right. |
is_in(member, container) |
Checks if member in container. |
is_instance_of(obj, class_or_tuple) |
Checks if isinstance(obj, class_or_tuple). |
License
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fluent_checks-0.4.0.tar.gz.
File metadata
- Download URL: fluent_checks-0.4.0.tar.gz
- Upload date:
- Size: 5.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e142f735e66b1c71ff270fd290d2eb936f66969b92996833e0af44e8aa55ecee
|
|
| MD5 |
1f582636ebddf8ae9f961a491afff6b4
|
|
| BLAKE2b-256 |
b8808b899e12307ef81b613ff65cde834ccd99b80e25ce4d776f89be160c7ab9
|
File details
Details for the file fluent_checks-0.4.0-py3-none-any.whl.
File metadata
- Download URL: fluent_checks-0.4.0-py3-none-any.whl
- Upload date:
- Size: 6.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.24 {"installer":{"name":"uv","version":"0.11.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
afad8b527369e5b6a0c0fd21cc54303e58bb7dcda3b1c232f55517253f081be4
|
|
| MD5 |
5a9f5f6236ef8a3dd90af23254b34c3d
|
|
| BLAKE2b-256 |
a580c1641762210c4035e79d7b59e139fdea3b48f159fe626a50d4b8d9a85df1
|