# Fluent Checks
A Python library for creating fluent, readable, and composable checks for your tests or application logic.
## Installation
Install the package using pip:
```bash
pip install fluent-checks
```
## Core Concepts
The core of the library is the `Check` class. A `Check` is a simple wrapper around a function that returns a boolean (a `Condition`).
```python
from fluent_checks import Check
# Create a check from a lambda
is_even = Check(lambda: 2 % 2 == 0)
# Evaluate the check
if is_even:
print("It's even!")
# Or more explicitly
assert bool(is_even) is True
```
## Usage
### Combining Checks
Checks can be combined using logical operators to create more complex conditions.
```python
a = Check(lambda: True)
b = Check(lambda: False)
assert bool(a & b) is False # And
assert bool(a | b) is True # Or
assert bool(~b) is True # Not
```
### Waiting for Conditions
You can wait for a condition to become true.
```python
import time
start_time = time.time()
flaky_check = Check(lambda: time.time() - start_time > 2)
# as_waiting will block until the check is true, or the timeout is reached.
assert flaky_check.as_waiting(timeout=3) is True
assert flaky_check.as_waiting(timeout=1) is False
```
### Timeouts and Deadlines
You can enforce time limits on checks.
```python
from datetime import datetime, timedelta
# This check will raise a TimeoutException if it takes longer than 1 second
slow_check = Check(lambda: time.sleep(2) or True)
failing_check = slow_check.with_timeout(1)
try:
bool(failing_check)
except TimeoutException:
print("Caught expected timeout!")
# You can also use a specific deadline
deadline = datetime.now() + timedelta(seconds=1)
check_with_deadline = slow_check.with_deadline(deadline)
```
### Repeating Checks
You can verify that a condition holds true multiple times.
```python
# succeeds_in_attempts: True if the check passes at least once in 5 attempts
flaky_check = Check(lambda: random.random() > 0.5)
assert flaky_check.succeeds_in_attempts(5)
# is_consistent_for: True if the check passes 5 times in a row
stable_check = Check(lambda: True)
assert stable_check.is_consistent_for(5)
```
### Looping Checks
The `sometimes` and `always` checks will run in a background thread until they are explicitly stopped.
```python
# The 'sometimes' check will pass if the condition is met at least once.
check = Check(lambda: random.random() > 0.8).sometimes()
time.sleep(1) # Give it some time to run
assert bool(check) is True
check.stop()
# The 'always' check will only pass if the condition is met every single time.
check = Check(lambda: random.random() > 0.2).always()
time.sleep(1) # Give it some time to run
assert bool(check) is False
check.stop()
```
### Checking for Exceptions
You can check that a piece of code raises a specific exception.
```python
def might_fail():
raise ValueError("Something went wrong")
check = Check(might_fail).raises(ValueError)
assert bool(check) is True
```
### Callbacks
You can add callbacks to your checks, that will be executed on success or on failure.
```python
a = Check(lambda: True)
a.on_success(lambda: print("I've passed"))
a.on_failure(lambda: print("I've failed"))
bool(a) # This will print "I've passed"
```
### File System Checks
You can check for files and directories.
```python
# Check if a file exists
assert FileExistsCheck("path/to/file")
# Check if a directory exists
assert DirectoryExistsCheck("path/to/dir")
# Check if a file contains specific content
assert FileContainsCheck("path/to/file", "content")
```
### Comparison Checks
You can compare values.
```python
# Equality
assert IsEqualCheck(1, 1)
assert IsNotEqualCheck(1, 2)
# Comparison
assert IsGreaterThanCheck(2, 1)
assert IsLessThanCheck(1, 2)
# Containment
assert IsInCheck(1, [1, 2, 3])
# Instance
assert IsInstanceOfCheck(1, int)
```
## API Overview
### Base Class
| Class/Method | Description |
| --- | --- |
| **`Check(condition: Callable[[], bool])`** | The base class for all checks. |
| **`&`, `\|`, `~`** | Operators for AND, OR, and NOT logic. |
| **`bool(check)`, `check.check()`** | Evaluates the check and returns the boolean result. |
### Waiting and Timeouts
| Class/Method | Description |
| --- | --- |
| **`as_waiting(timeout: float) -> WaitingCheck`** | Blocks until the check is `True` or the timeout expires. |
| **`with_timeout(timeout: float) -> TimeoutCheck`** | Returns a new check that will raise a `TimeoutException` if it doesn't complete within the timeout. |
| **`with_deadline(deadline: datetime) -> DeadlineCheck`** | Similar to `with_timeout` but uses an absolute deadline. |
| **`succeeds_within(timeout: float) -> SucceedsWithinCheck`** | Checks if the condition is met at least once within a time limit. `eventually` is an alias for this. |
| **`fails_within(timeout: float) -> FailsWithinCheck`** | Checks if the condition fails at least once within a time limit. |
### Repeating and Looping
| Class/Method | Description |
| --- | --- |
| **`succeeds_in_attempts(times: int) -> RepeatingOrCheck`** | Checks if the condition is met at least once within a number of tries. |
| **`is_consistent_for(times: int) -> RepeatingAndCheck`** | Checks if the condition is met consecutively for a number of tries. |
| **`sometimes() -> LoopingOrCheck`** | Runs the check in a background thread and succeeds if the condition is met at least once. Remember to call `stop()`.|
| **`always() -> LoopingAndCheck`** | Runs the check in a background thread and succeeds only if the condition is always met. Remember to call `stop()`.|
### Exceptions and Callbacks
| Class/Method | Description |
| --- | --- |
| **`raises(exception: type[Exception]) -> RaisesCheck`** | Checks if the condition raises a specific exception. |
| **`on_success(callback: Callable[[], None]) -> Check`** | Registers a callback to be executed when the check succeeds. |
| **`on_failure(callback: Callable[[], None]) -> Check`** | Registers a callback to be executed when the check fails. |
### File System
| Class/Method | Description |
| --- | --- |
| **`FileExistsCheck(path: str)`** | Checks if a file exists at the given path. |
| **`DirectoryExistsCheck(path: str)`** | Checks if a directory exists at the given path. |
| **`FileContainsCheck(path: str, content: str)`** | Checks if a file at the given path contains the given content. |
### Comparisons
| Class/Method | Description |
| --- | --- |
| **`IsEqualCheck(left, right)`** | Checks if `left == right`. |
| **`IsNotEqualCheck(left, right)`** | Checks if `left != right`. |
| **`IsGreaterThanCheck(left, right)`** | Checks if `left > right`. |
| **`IsLessThanCheck(left, right)`** | Checks if `left < right`. |
| **`IsInCheck(member, container)`** | Checks if `member in container`. |
| **`IsInstanceOfCheck(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](LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "fluent-checks",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "fluent, checks, testing, assertions, validation",
"author": "vantorrewannes",
"author_email": "vantorrewannes <vantorrewannes@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/dc/9c/6ba905008db8eb993f500c5d24b1f919cef73637059d927d4beaf64e8059/fluent_checks-0.3.0.tar.gz",
"platform": null,
"description": "# Fluent Checks\n\nA Python library for creating fluent, readable, and composable checks for your tests or application logic.\n\n## Installation\n\nInstall the package using pip:\n\n```bash\npip install fluent-checks\n```\n\n## Core Concepts\n\nThe core of the library is the `Check` class. A `Check` is a simple wrapper around a function that returns a boolean (a `Condition`).\n```python\nfrom fluent_checks import Check\n\n# Create a check from a lambda\nis_even = Check(lambda: 2 % 2 == 0)\n\n# Evaluate the check\nif is_even:\n print(\"It's even!\")\n\n# Or more explicitly\nassert bool(is_even) is True\n```\n\n## Usage\n### Combining Checks\n\nChecks can be combined using logical operators to create more complex conditions.\n```python\na = Check(lambda: True)\nb = Check(lambda: False)\n\nassert bool(a & b) is False # And\nassert bool(a | b) is True # Or\nassert bool(~b) is True # Not\n```\n\n### Waiting for Conditions\n\nYou can wait for a condition to become true.\n```python\nimport time\n\nstart_time = time.time()\nflaky_check = Check(lambda: time.time() - start_time > 2)\n\n# as_waiting will block until the check is true, or the timeout is reached.\nassert flaky_check.as_waiting(timeout=3) is True\nassert flaky_check.as_waiting(timeout=1) is False\n```\n\n### Timeouts and Deadlines\n\nYou can enforce time limits on checks.\n\n```python\nfrom datetime import datetime, timedelta\n\n# This check will raise a TimeoutException if it takes longer than 1 second\nslow_check = Check(lambda: time.sleep(2) or True)\nfailing_check = slow_check.with_timeout(1)\n\ntry:\n bool(failing_check)\nexcept TimeoutException:\n print(\"Caught expected timeout!\")\n\n# You can also use a specific deadline\ndeadline = datetime.now() + timedelta(seconds=1)\ncheck_with_deadline = slow_check.with_deadline(deadline)\n```\n\n### Repeating Checks\n\nYou can verify that a condition holds true multiple times.\n\n```python\n# succeeds_in_attempts: True if the check passes at least once in 5 attempts\nflaky_check = Check(lambda: random.random() > 0.5)\nassert flaky_check.succeeds_in_attempts(5)\n\n# is_consistent_for: True if the check passes 5 times in a row\nstable_check = Check(lambda: True)\nassert stable_check.is_consistent_for(5)\n```\n\n### Looping Checks\nThe `sometimes` and `always` checks will run in a background thread until they are explicitly stopped.\n```python\n# The 'sometimes' check will pass if the condition is met at least once.\ncheck = Check(lambda: random.random() > 0.8).sometimes()\ntime.sleep(1) # Give it some time to run\nassert bool(check) is True\ncheck.stop()\n\n# The 'always' check will only pass if the condition is met every single time.\ncheck = Check(lambda: random.random() > 0.2).always()\ntime.sleep(1) # Give it some time to run\nassert bool(check) is False\ncheck.stop()\n```\n\n### Checking for Exceptions\n\nYou can check that a piece of code raises a specific exception.\n\n```python\ndef might_fail():\n raise ValueError(\"Something went wrong\")\n\ncheck = Check(might_fail).raises(ValueError)\n\nassert bool(check) is True\n```\n\n### Callbacks\nYou can add callbacks to your checks, that will be executed on success or on failure.\n```python\na = Check(lambda: True)\na.on_success(lambda: print(\"I've passed\"))\na.on_failure(lambda: print(\"I've failed\"))\n\nbool(a) # This will print \"I've passed\"\n```\n\n### File System Checks\nYou can check for files and directories.\n```python\n# Check if a file exists\nassert FileExistsCheck(\"path/to/file\")\n\n# Check if a directory exists\nassert DirectoryExistsCheck(\"path/to/dir\")\n\n# Check if a file contains specific content\nassert FileContainsCheck(\"path/to/file\", \"content\")\n```\n\n### Comparison Checks\nYou can compare values.\n```python\n# Equality\nassert IsEqualCheck(1, 1)\nassert IsNotEqualCheck(1, 2)\n\n# Comparison\nassert IsGreaterThanCheck(2, 1)\nassert IsLessThanCheck(1, 2)\n\n# Containment\nassert IsInCheck(1, [1, 2, 3])\n\n# Instance\nassert IsInstanceOfCheck(1, int)\n```\n\n## API Overview\n\n### Base Class\n| Class/Method | Description |\n| --- | --- |\n| **`Check(condition: Callable[[], bool])`** | The base class for all checks. |\n| **`&`, `\\|`, `~`** | Operators for AND, OR, and NOT logic. |\n| **`bool(check)`, `check.check()`** | Evaluates the check and returns the boolean result. |\n\n### Waiting and Timeouts\n| Class/Method | Description |\n| --- | --- |\n| **`as_waiting(timeout: float) -> WaitingCheck`** | Blocks until the check is `True` or the timeout expires. |\n| **`with_timeout(timeout: float) -> TimeoutCheck`** | Returns a new check that will raise a `TimeoutException` if it doesn't complete within the timeout. |\n| **`with_deadline(deadline: datetime) -> DeadlineCheck`** | Similar to `with_timeout` but uses an absolute deadline. |\n| **`succeeds_within(timeout: float) -> SucceedsWithinCheck`** | Checks if the condition is met at least once within a time limit. `eventually` is an alias for this. |\n| **`fails_within(timeout: float) -> FailsWithinCheck`** | Checks if the condition fails at least once within a time limit. |\n\n### Repeating and Looping\n| Class/Method | Description |\n| --- | --- |\n| **`succeeds_in_attempts(times: int) -> RepeatingOrCheck`** | Checks if the condition is met at least once within a number of tries. |\n| **`is_consistent_for(times: int) -> RepeatingAndCheck`** | Checks if the condition is met consecutively for a number of tries. |\n| **`sometimes() -> LoopingOrCheck`** | Runs the check in a background thread and succeeds if the condition is met at least once. Remember to call `stop()`.|\n| **`always() -> LoopingAndCheck`** | Runs the check in a background thread and succeeds only if the condition is always met. Remember to call `stop()`.|\n\n### Exceptions and Callbacks\n| Class/Method | Description |\n| --- | --- |\n| **`raises(exception: type[Exception]) -> RaisesCheck`** | Checks if the condition raises a specific exception. |\n| **`on_success(callback: Callable[[], None]) -> Check`** | Registers a callback to be executed when the check succeeds. |\n| **`on_failure(callback: Callable[[], None]) -> Check`** | Registers a callback to be executed when the check fails. |\n\n### File System\n| Class/Method | Description |\n| --- | --- |\n| **`FileExistsCheck(path: str)`** | Checks if a file exists at the given path. |\n| **`DirectoryExistsCheck(path: str)`** | Checks if a directory exists at the given path. |\n| **`FileContainsCheck(path: str, content: str)`** | Checks if a file at the given path contains the given content. |\n\n### Comparisons\n| Class/Method | Description |\n| --- | --- |\n| **`IsEqualCheck(left, right)`** | Checks if `left == right`. |\n| **`IsNotEqualCheck(left, right)`** | Checks if `left != right`. |\n| **`IsGreaterThanCheck(left, right)`** | Checks if `left > right`. |\n| **`IsLessThanCheck(left, right)`** | Checks if `left < right`. |\n| **`IsInCheck(member, container)`** | Checks if `member in container`. |\n| **`IsInstanceOfCheck(obj, class_or_tuple)`** | Checks if `isinstance(obj, class_or_tuple)`. |\n\n\n## License\n\nThis project is licensed under the GNU General Public License v3.0 - see the [LICENSE](LICENSE) file for details.\n\n",
"bugtrack_url": null,
"license": null,
"summary": "A library for creating fluent, readable, and composable checks for your tests or application logic.",
"version": "0.3.0",
"project_urls": {
"Bug Tracker": "https://github.com/VantorreWannes/fluent-checks/issues",
"Homepage": "https://github.com/VantorreWannes/fluent-checks"
},
"split_keywords": [
"fluent",
" checks",
" testing",
" assertions",
" validation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "bcb5baed64c5f460534425607862311c3192bf09d4c3f94263f3b09c459ca21d",
"md5": "3ff665a8a431fcb4ea37ed87137eca0a",
"sha256": "50124827608a559e6cd694145f37499e3d180b4d0462a2fbeb164422cbacba6e"
},
"downloads": -1,
"filename": "fluent_checks-0.3.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3ff665a8a431fcb4ea37ed87137eca0a",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 6409,
"upload_time": "2025-09-01T10:52:12",
"upload_time_iso_8601": "2025-09-01T10:52:12.991717Z",
"url": "https://files.pythonhosted.org/packages/bc/b5/baed64c5f460534425607862311c3192bf09d4c3f94263f3b09c459ca21d/fluent_checks-0.3.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "dc9c6ba905008db8eb993f500c5d24b1f919cef73637059d927d4beaf64e8059",
"md5": "cb16a416548b6b7a134397f2d73867ca",
"sha256": "a0be7611f0a225396d76891ef33407a0733774a7e9c197f0014c09c66cad72ec"
},
"downloads": -1,
"filename": "fluent_checks-0.3.0.tar.gz",
"has_sig": false,
"md5_digest": "cb16a416548b6b7a134397f2d73867ca",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 5726,
"upload_time": "2025-09-01T10:52:14",
"upload_time_iso_8601": "2025-09-01T10:52:14.183764Z",
"url": "https://files.pythonhosted.org/packages/dc/9c/6ba905008db8eb993f500c5d24b1f919cef73637059d927d4beaf64e8059/fluent_checks-0.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-09-01 10:52:14",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "VantorreWannes",
"github_project": "fluent-checks",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "fluent-checks"
}