fluent-checks


Namefluent-checks JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryA library for creating fluent, readable, and composable checks for your tests or application logic.
upload_time2025-09-01 10:52:14
maintainerNone
docs_urlNone
authorvantorrewannes
requires_python>=3.12
licenseNone
keywords fluent checks testing assertions validation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # 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"
}
        
Elapsed time: 0.72955s