Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added inline_snapshot.testing.Example which can be used to test 3rd-party extensions #95

Merged
merged 1 commit into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions docs/testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@


`inline_snapshot.testing` provides tools which can be used to test inline-snapshot workflows.
This might be useful if you want to build your own libraries based on inline-snapshot.

The following example shows how you can use the `Example` class to test what inline-snapshot would do with given the source code. The snapshots in the argument are asserted inside the `run_*` methods, but only when they are provided.

=== "original"

<!-- inline-snapshot: outcome-passed=1 outcome-errors=1 -->
```python
from inline_snapshot.testing import Example
from inline_snapshot import snapshot


def test_something():

Example(
{
"test_a.py": """\
from inline_snapshot import snapshot
def test_a():
assert 1+1 == snapshot()
"""
}
).run_inline(
reported_flags=snapshot(),
).run_pytest(
changed_files=snapshot(),
report=snapshot(),
).run_pytest(
["--inline-snapshot=create"],
changed_files=snapshot(),
)
```

=== "--inline-snapshot=create"

<!-- inline-snapshot: create outcome-passed=1 -->
```python
from inline_snapshot.testing import Example
from inline_snapshot import snapshot


def test_something():

Example(
{
"test_a.py": """\
from inline_snapshot import snapshot
def test_a():
assert 1+1 == snapshot()
"""
}
).run_inline(
reported_flags=snapshot(["create"]),
).run_pytest(
changed_files=snapshot({}),
report=snapshot(
"""\
Error: one snapshot is missing a value (--inline-snapshot=create)
You can also use --inline-snapshot=review to approve the changes interactiv\
"""
),
).run_pytest(
["--inline-snapshot=create"],
changed_files=snapshot(
{
"test_a.py": """\
from inline_snapshot import snapshot
def test_a():
assert 1+1 == snapshot(2)
"""
}
),
)
```


## API
::: inline_snapshot.testing.Example
options:
separate_signature: true
show_signature_annotations: true


## Types

The following types are for type checking.

::: inline_snapshot.Category

see [categories](categories.md)

::: inline_snapshot.Snapshot

Can be used to annotate where snapshots can be passed as function arguments.

??? note "Example"
<!-- inline-snapshot: create fix trim this outcome-passed=2 -->
```python
from typing import Optional
from inline_snapshot import snapshot, Snapshot


def check_in_bounds(value, lower: Snapshot[int], upper: Snapshot[int]):
assert lower <= value <= upper


def test_numbers():
for c in "hello world":
check_in_bounds(ord(c), snapshot(32), snapshot(119))


def check_container(
value,
*,
value_repr: Optional[Snapshot[str]] = None,
length: Optional[Snapshot[int]] = None
):
if value_repr is not None:
assert repr(value) == value_repr

if length is not None:
assert len(value) == length


def test_container():
check_container([1, 2], value_repr=snapshot("[1, 2]"), length=snapshot(2))

check_container({1, 1}, length=snapshot(1))
```
2 changes: 2 additions & 0 deletions inline_snapshot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
from ._external import external
from ._external import outsource
from ._inline_snapshot import snapshot
from ._types import Category
from ._types import Snapshot

__all__ = ["snapshot", "external", "outsource", "customize_repr", "HasRepr"]

Expand Down
3 changes: 2 additions & 1 deletion inline_snapshot/_inline_snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from ._exceptions import UsageError
from ._format import format_code
from ._sentinels import undefined
from ._types import Category
from ._utils import ignore_tokens
from ._utils import normalize
from ._utils import simple_token
Expand Down Expand Up @@ -53,7 +54,7 @@ class Flags:
trim: the snapshot contains more values than neccessary. 1 could be trimmed in `5 in snapshot([1,5])`.
"""

def __init__(self, flags=set()):
def __init__(self, flags: Set[Category] = set()):
self.fix = "fix" in flags
self.update = "update" in flags
self.create = "create" in flags
Expand Down
11 changes: 11 additions & 0 deletions inline_snapshot/_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from typing import Literal
from typing import TypeVar

from typing_extensions import Annotated

T = TypeVar("T")

Snapshot = Annotated[T, "just an alias"]


Category = Literal["update", "fix", "create", "trim"]
3 changes: 3 additions & 0 deletions inline_snapshot/testing/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from ._example import Example

__all__ = ("Example",)
Loading
Loading