Skip to content

Commit

Permalink
use pydantic-examples to test examples (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelcolvin committed Apr 27, 2023
1 parent b8909ec commit caa4a73
Show file tree
Hide file tree
Showing 15 changed files with 121 additions and 132 deletions.
4 changes: 2 additions & 2 deletions dirty_equals/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def value(self) -> T:
assert 't-123' == token_is_str
print(token_is_str.value)
#> 't-123'
#> t-123
```
"""
if self._was_equal:
Expand Down Expand Up @@ -220,7 +220,7 @@ def __init__(self, expected_value: Any, *more_expected_values: Any):
*more_expected_values: More expected values for equals to return true.
```py title="IsOneOf"
from dirty_equals import IsOneOf, Contains
from dirty_equals import Contains, IsOneOf
assert 1 == IsOneOf(1, 2, 3)
assert 4 != IsOneOf(1, 2, 3)
Expand Down
12 changes: 8 additions & 4 deletions dirty_equals/_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ def __init__(
Examples of basic usage:
```py title="IsDatetime"
from dirty_equals import IsDatetime
from datetime import datetime
from dirty_equals import IsDatetime
y2k = datetime(2000, 1, 1)
assert datetime(2000, 1, 1) == IsDatetime(approx=y2k)
# Note: this requires the system timezone to be UTC
Expand Down Expand Up @@ -144,9 +145,10 @@ def __init__(
if provided now will be converted to this timezone.
```py title="IsNow"
from dirty_equals import IsNow
from datetime import datetime, timezone
from dirty_equals import IsNow
now = datetime.now()
assert now == IsNow
assert now.timestamp() == IsNow(unix_number=True)
Expand Down Expand Up @@ -226,9 +228,10 @@ def __init__(
Examples of basic usage:
```py title="IsDate"
from dirty_equals import IsDate
from datetime import date
from dirty_equals import IsDate
y2k = date(2000, 1, 1)
assert date(2000, 1, 1) == IsDate(approx=y2k)
assert '2000-01-01' == IsDate(approx=y2k, iso_string=True)
Expand Down Expand Up @@ -284,9 +287,10 @@ def __init__(
iso_string: whether to allow iso formatted strings in comparison
format_string: if provided, `format_string` is used with `datetime.strptime` to parse strings
```py title="IsToday"
from dirty_equals import IsToday
from datetime import date, timedelta
from dirty_equals import IsToday
today = date.today()
assert today == IsToday
assert today.isoformat() == IsToday(iso_string=True)
Expand Down
14 changes: 9 additions & 5 deletions dirty_equals/_dict.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,18 @@ def settings(
from dirty_equals import IsDict
assert {'a': 1, 'b': 2, 'c': None} != IsDict(a=1, b=2)
assert {'a': 1, 'b': 2, 'c': None} == IsDict(a=1, b=2).settings(partial=True) #(1)!
assert {'a': 1, 'b': 2, 'c': None} == IsDict(a=1, b=2).settings(partial=True) # (1)!
assert {'b': 2, 'a': 1} == IsDict(a=1, b=2)
assert {'b': 2, 'a': 1} != IsDict(a=1, b=2).settings(strict=True) #(2)!
assert {'b': 2, 'a': 1} != IsDict(a=1, b=2).settings(strict=True) # (2)!
# combining partial and strict
assert {'a': 1, 'b': None, 'c': 3} == IsDict(a=1, c=3).settings(strict=True, partial=True)
assert {'b': None, 'c': 3, 'a': 1} != IsDict(a=1, c=3).settings(strict=True, partial=True)
assert {'a': 1, 'b': None, 'c': 3} == IsDict(a=1, c=3).settings(
strict=True, partial=True
)
assert {'b': None, 'c': 3, 'a': 1} != IsDict(a=1, c=3).settings(
strict=True, partial=True
)
```
1. This is the same as [`IsPartialDict(a=1, b=2)`][dirty_equals.IsPartialDict]
Expand Down Expand Up @@ -188,7 +192,7 @@ class IsIgnoreDict(IsDict):
from dirty_equals import IsIgnoreDict
assert {'a': 1, 'b': 2, 'c': None} == IsIgnoreDict(a=1, b=2)
assert {'a': 1, 'b': 2, 'c': None, 'c': 'ignore'} == (
assert {'a': 1, 'b': 2, 'c': 'ignore'} == (
IsIgnoreDict(a=1, b=2).settings(ignore={None, 'ignore'})
)
Expand Down
2 changes: 1 addition & 1 deletion dirty_equals/_inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ def __init__(self, *expected_args: Dict[Any, Any], **expected_kwargs: Any):
Example:
```py title="HasAttributes"
from dirty_equals import HasAttributes, IsInt, IsStr, AnyThing
from dirty_equals import AnyThing, HasAttributes, IsInt, IsStr
class Foo:
def __init__(self, a, b):
Expand Down
11 changes: 10 additions & 1 deletion dirty_equals/_numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,10 @@ def __init__(
Example of direct usage:
```py title="IsNumeric"
from dirty_equals import IsNumeric
from datetime import datetime
from dirty_equals import IsNumeric
assert 1.0 == IsNumeric
assert 4 == IsNumeric(gt=3)
d = datetime(2020, 1, 1, 12, 0, 0)
Expand Down Expand Up @@ -191,6 +192,7 @@ class IsPositive(IsNumber):
```py title="IsPositive"
from decimal import Decimal
from dirty_equals import IsPositive
assert 1.0 == IsPositive
Expand All @@ -213,6 +215,7 @@ class IsNegative(IsNumber):
```py title="IsNegative"
from decimal import Decimal
from dirty_equals import IsNegative
assert -1.0 == IsNegative
Expand All @@ -235,6 +238,7 @@ class IsNonNegative(IsNumber):
```py title="IsNonNegative"
from decimal import Decimal
from dirty_equals import IsNonNegative
assert 1.0 == IsNonNegative
Expand All @@ -258,6 +262,7 @@ class IsNonPositive(IsNumber):
```py title="IsNonPositive"
from decimal import Decimal
from dirty_equals import IsNonPositive
assert -1.0 == IsNonPositive
Expand Down Expand Up @@ -307,6 +312,7 @@ class IsPositiveInt(IsInt):
```py title="IsPositiveInt"
from decimal import Decimal
from dirty_equals import IsPositiveInt
assert 1 == IsPositiveInt
Expand All @@ -328,6 +334,7 @@ class IsNegativeInt(IsInt):
```py title="IsNegativeInt"
from decimal import Decimal
from dirty_equals import IsNegativeInt
assert -1 == IsNegativeInt
Expand Down Expand Up @@ -371,6 +378,7 @@ class IsPositiveFloat(IsFloat):
```py title="IsPositiveFloat"
from decimal import Decimal
from dirty_equals import IsPositiveFloat
assert 1.0 == IsPositiveFloat
Expand All @@ -392,6 +400,7 @@ class IsNegativeFloat(IsFloat):
```py title="IsNegativeFloat"
from decimal import Decimal
from dirty_equals import IsNegativeFloat
assert -1.0 == IsNegativeFloat
Expand Down
10 changes: 7 additions & 3 deletions dirty_equals/_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(self, version: Literal[None, 1, 2, 3, 4, 5] = None):
```py title="IsUUID"
import uuid
from dirty_equals import IsUUID
assert 'edf9f29e-45c7-431c-99db-28ea44df9785' == IsUUID
Expand Down Expand Up @@ -87,7 +88,7 @@ def __init__(self, expected_value: JsonType = AnyJson, **expected_kwargs: Any):
```py title="IsJson"
from dirty_equals import IsJson, IsStrictDict, IsPositiveInt
from dirty_equals import IsJson, IsPositiveInt, IsStrictDict
assert '{"a": 1, "b": 2}' == IsJson
assert '{"a": 1, "b": 2}' == IsJson(a=1, b=2)
Expand Down Expand Up @@ -285,7 +286,9 @@ def __init__(self, hash_type: HashTypes):
assert 'f1e069787ece74531d112559945c6871' != IsHash('sha-256')
assert 'F1E069787ECE74531D112559945C6871' == IsHash('md5')
assert '40bd001563085fc35165329ea1ff5c5ecbdbbeef' == IsHash('sha-1')
assert 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3' == IsHash('sha-256')
assert 'a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3' == IsHash(
'sha-256'
)
```
"""

Expand Down Expand Up @@ -326,7 +329,8 @@ def __init__(self, *, version: Literal[None, 4, 6] = None, netmask: Optional[str
netmask: The netmask of the IP to check, if omitted, any netmask is accepted. Requires version.
```py title="IsIP"
from ipaddress import IPv4Address, IPv6Address, IPv4Network
from ipaddress import IPv4Address, IPv4Network, IPv6Address
from dirty_equals import IsIP
assert '179.27.154.96' == IsIP
Expand Down
28 changes: 13 additions & 15 deletions dirty_equals/_sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ def __init__(self, min_length: int, max_length: Union[None, int, Any] = None):
```py title="HasLen"
from dirty_equals import HasLen
assert [1, 2, 3] == HasLen(3) #(1)!
assert '123' == HasLen(3, ...) #(2)!
assert (1, 2, 3) == HasLen(3, 5) #(3)!
assert (1, 2, 3) == HasLen(0, ...) #(4)!
assert [1, 2, 3] == HasLen(3) # (1)!
assert '123' == HasLen(3, ...) # (2)!
assert (1, 2, 3) == HasLen(3, 5) # (3)!
assert (1, 2, 3) == HasLen(0, ...) # (4)!
```
1. Length must be 3.
Expand Down Expand Up @@ -125,28 +125,26 @@ def __init__(
of [`HasLen`][dirty_equals.HasLen].
```py title="IsListOrTuple"
from dirty_equals import IsListOrTuple, AnyThing
from dirty_equals import AnyThing, IsListOrTuple
assert [1, 2, 3] == IsListOrTuple(1, 2, 3)
assert (1, 3, 2) == IsListOrTuple(1, 2, 3, check_order=False)
assert [{'a': 1}, {'a': 2}] == (
IsListOrTuple({'a': 2}, {'a': 1}, check_order=False) #(1)!
IsListOrTuple({'a': 2}, {'a': 1}, check_order=False) # (1)!
)
assert [1, 2, 3, 3] != IsListOrTuple(1, 2, 3, check_order=False) #(2)!
assert [1, 2, 3, 3] != IsListOrTuple(1, 2, 3, check_order=False) # (2)!
assert [1, 2, 3, 4, 5] == IsListOrTuple(1, 2, 3, length=...) #(3)!
assert [1, 2, 3, 4, 5] != IsListOrTuple(1, 2, 3, length=(8, 10)) #(4)!
assert [1, 2, 3, 4, 5] == IsListOrTuple(1, 2, 3, length=...) # (3)!
assert [1, 2, 3, 4, 5] != IsListOrTuple(1, 2, 3, length=(8, 10)) # (4)!
assert ['a', 'b', 'c', 'd'] == (IsListOrTuple(positions={2: 'c', 3: 'd'})) # (5)!
assert ['a', 'b', 'c', 'd'] == (
IsListOrTuple(positions={2: 'c', 3: 'd'}) #(5)!
)
assert ['a', 'b', 'c', 'd'] == (
IsListOrTuple(positions={2: 'c', 3: 'd'}, length=4) #(6)!
IsListOrTuple(positions={2: 'c', 3: 'd'}, length=4) # (6)!
)
assert [1, 2, 3, 4] == IsListOrTuple(3, check_order=False, length=(0, ...)) #(7)!
assert [1, 2, 3, 4] == IsListOrTuple(3, check_order=False, length=(0, ...)) # (7)!
assert [1, 2, 3] == IsListOrTuple(AnyThing, AnyThing, 3) #(8)!
assert [1, 2, 3] == IsListOrTuple(AnyThing, AnyThing, 3) # (8)!
```
1. Unlike using sets for comparison, we can do order-insensitive comparisons on objects that are not hashable.
Expand Down
2 changes: 1 addition & 1 deletion dirty_equals/_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def __init__(
assert b'foobar' == IsAnyStr()
assert 123 != IsAnyStr()
assert 'foobar' == IsAnyStr(regex='foo...')
assert 'foobar' == IsAnyStr(regex=b'foo...') #(1)!
assert 'foobar' == IsAnyStr(regex=b'foo...') # (1)!
assert 'foobar' == IsAnyStr(min_length=6)
assert 'foobar' != IsAnyStr(min_length=8)
Expand Down
28 changes: 14 additions & 14 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ applications where you're commonly checking the response to API calls and the co

Here's a trivial example of what *dirty-equals* can do:

```{.py title="Trival Usage" test="false"}
```{.py title="Trival Usage" test="skip"}
from dirty_equals import IsPositive

assert 1 == IsPositive #(1)!
assert 1 == IsPositive # (1)!
assert -2 == IsPositive # this will fail! (2)
```

Expand All @@ -49,21 +49,21 @@ assert -2 == IsPositive # this will fail! (2)

**Not that interesting yet!**, but consider the following unit test code using **dirty-equals**:

```py
title="More Powerful Usage"
```{.py title="More Powerful Usage" lint="skip"}
from dirty_equals import IsJson, IsNow, IsPositiveInt, IsStr


def test_user_endpoint(client: 'HttpClient', db_conn: 'Database'):
client.pust('/users/create/', data=...)

user_data = db_conn.fetchrow('select * from users')
assert user_data == {
'id': IsPositiveInt, #(1)!
'username': 'samuelcolvin', #(2)!
'avatar_file': IsStr(regex=r'/[a-z0-9\-]{10}/example\.png'), #(3)!
'settings_json': IsJson({'theme': 'dark', 'language': 'en'}), #(4)!
'created_ts': IsNow(delta=3), #(5)!
}
client.pust('/users/create/', data=...)

user_data = db_conn.fetchrow('select * from users')
assert user_data == {
'id': IsPositiveInt, # (1)!
'username': 'samuelcolvin', # (2)!
'avatar_file': IsStr(regex=r'/[a-z0-9\-]{10}/example\.png'), # (3)!
'settings_json': IsJson({'theme': 'dark', 'language': 'en'}), # (4)!
'created_ts': IsNow(delta=3), # (5)!
}
```

1. We don't actually care what the `id` is, just that it's present, it's an `int` and it's positive.
Expand Down
9 changes: 5 additions & 4 deletions docs/types/custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ To demonstrate the use of custom types, we'll create a custom type that matches

We won't inherit from [`IsNumeric`][dirty_equals.IsNumeric] in this case to keep the example simple.

```py
title="IsEven"
```py title="IsEven"
from decimal import Decimal
from typing import Any, Union
from dirty_equals import IsOneOf
from dirty_equals import DirtyEquals

from dirty_equals import DirtyEquals, IsOneOf


class IsEven(DirtyEquals[Union[int, float, Decimal]]):
def equals(self, other: Any) -> bool:
return other % 2 == 0


assert 2 == IsEven
assert 3 != IsEven
assert 'foobar' != IsEven
Expand Down
6 changes: 3 additions & 3 deletions docs/types/datetime.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ based on the `enforce_tz` parameter:

Example

```py
title="IsDatetime & timezones"
```py title="IsDatetime & timezones"
from datetime import datetime

from dirty_equals import IsDatetime
import pytz

from dirty_equals import IsDatetime

tz_london = pytz.timezone('Europe/London')
new_year_london = tz_london.localize(datetime(2000, 1, 1))

Expand Down
Loading

0 comments on commit caa4a73

Please sign in to comment.