Skip to content
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
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Contributing to Selfie

- To improve our webpage go to [`selfie.dev/README.md`](selfie.dev/README.md)
- To improve our Python, go to [`python/README.md`](python/README.md)
- To improve our JVM, Javascript, or WASM implementations, go to [`jvm/README.md`](jvm/README.md)
- To improve the webpage of our published kdoc, [kdoc.selfie.dev](https://kdoc.selfie.dev), go to [`jvm/gradle/dokka/README.md`](jvm/gradle/dokka/README.md)
- To contribute for a different platform (python, go, etc.) we're happy to help! It should probably live in a different repo until it's close to `1.0`, but once it's near completion we're happy to maintain it here if you would like. Discuss in [selfie#85](https://github.com/diffplug/selfie/issues/85), but also feel free to open a PR with any ideas you have.
Expand Down
25 changes: 12 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,30 @@
# Selfie: snapshot testing and [memoizing](https://selfie.dev/jvm/cache) for Java, Kotlin, and the JVM
# Selfie: snapshot testing and memoizing for Python, JVM, and [(your PR here)](https://github.com/diffplug/selfie/issues/85)

![gif demo of selfie in action](https://docs.diffplug.com/selfie/selfie-demo.gif)

## Key features

- Just [add a test dependency](https://selfie.dev/jvm/get-started#installation), zero setup, zero config.
- Snapshots can be [inline literals](https://selfie.dev/jvm#literal) or [on disk](https://selfie.dev/jvm#like-a-filesystem).
- Use `expectSelfie` for testing or `cacheSelfie` for [memoizing expensive API calls](https://selfie.dev/jvm/cache).
- Just add a test dependency ([py](https://selfie.dev/py/get-started#installation), [jvm](https://selfie.dev/jvm/get-started#installation)), zero setup, zero config.
- Snapshots can be [inline literals](https://selfie.dev/py#literal) or [on disk](https://selfie.dev/py#like-a-filesystem).
- Use `expect_selfie` for testing or `cache_selfie` for [memoizing expensive API calls](https://selfie.dev/py/cache).
- Disk snapshots are automatically [garbage collected](https://github.com/diffplug/selfie/blob/main/jvm/selfie-runner-junit5/src/main/kotlin/com/diffplug/selfie/junit5/SelfieGC.kt) when the test class or test method is removed.
- Snapshots are **just strings**. Use html, json, markdown, whatever. No [magic serializers](https://selfie.dev/jvm/facets#typed-snapshots).
- Snapshots are **just strings**. Use html, json, markdown, whatever. No [magic serializers](https://selfie.dev/py/cache#roundtripping-typed-data).
- Record **multiple facets** of the entity under test, e.g. for a web request...
- store the HTML as one facet
- store HTML-rendered-to-markdown as another facet
- store cookies in another facet
- **assert some facets on disk, others inline**
- see gif above for live demo, detailed example [here](https://selfie.dev/jvm/advanced)
- see gif above for live demo, detailed example [here](https://selfie.dev/py/facets#harmonizing-disk-and-inline-literals)

JVM only for now, [python](https://github.com/diffplug/selfie/issues/170) is in progress, other platforms on the way: [js](https://github.com/diffplug/selfie/issues/84), [.NET, go, ...](https://github.com/diffplug/selfie/issues/85)
Python and JVM ports are both production-ready, other platforms on the way: [js](https://github.com/diffplug/selfie/issues/84), [.NET, go, ...](https://github.com/diffplug/selfie/issues/85)

## Documentation

- [Installation](https://selfie.dev/jvm/get-started#installation)
- [Quickstart](https://selfie.dev/jvm/get-started#quickstart)
- [Facets](https://selfie.dev/jvm/facets)
- [Caching / memoizing](https://selfie.dev/jvm/cache)
- [Why selfie](https://selfie.dev/jvm)
- [API reference](https://kdoc.selfie.dev/)
- Quickstart **([py](https://selfie.dev/py/get-started#quickstart), [jvm](https://selfie.dev/jvm/get-started#quickstart))**
- Facets **([py](https://selfie.dev/py/facets), [jvm](https://selfie.dev/jvm/facets))**
- Caching / memoizing **([py](https://selfie.dev/py/cache), [jvm](https://selfie.dev/jvm/cache))**
- Why selfie **([py](https://selfie.dev/py), [jvm](https://selfie.dev/jvm))**
- API reference **([py](https://pydoc.selfie.dev/namespacemembers_func), [jvm](https://kdoc.selfie.dev/))**

## Contributing

Expand Down
7 changes: 3 additions & 4 deletions jvm/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Selfie snapshot testing for Java, Kotlin, and the JVM

- [Quickstart](https://selfie.dev/jvm/get-started)
- [Facets](https://selfie.dev/jvm/facets)
- [Caching / memoizing](https://selfie.dev/jvm/cache)
- [Why selfie](https://selfie.dev/jvm)
- High-level documentation - [selfie.dev](https://selfie.dev/jvm/get-started).
- API documentation - [pydoc.selfie.dev](https://kdoc.selfie.dev).
- Source code - [github.com/diffplug/selfie](https://github.com/diffplug/selfie)

## Contributing

Expand Down
4 changes: 3 additions & 1 deletion python/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Selfie snapshot testing for Python

- High-level documentation - [selfie.dev](https://selfie.dev/py/get-started).
- API documentation - [pydoc.selfie.dev](https://pydoc.selfie.dev/namespaces).
- Source code - [github.com/diffplug/selfie](https://github.com/diffplug/selfie)

## Contributing

Dependencies are managed using uv:
PR's welcome! Dependencies are managed using uv:

- https://docs.astral.sh/uv/getting-started/installation/
- then cd into `selfie-lib` and run `uv sync` to get the dependencies
Expand Down
4 changes: 2 additions & 2 deletions python/example-pytest-selfie/tests/binary_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def test_binary_file_duplicate_unequal():
"tests/binary_test__test_binary_file_duplicate_unequal.bin"
)
expect_selfie(safify(str(exc_info.value))).to_be(
"Snapshot mismatch, TODO: string comparison"
"Snapshot mismatch (error msg could be better https://github.com/diffplug/selfie/issues/501)"
)


Expand All @@ -65,7 +65,7 @@ def test_base64_mismatch():
with pytest.raises(Exception) as exc_info:
expect_selfie(b"test data").to_be_base64("AAAA")
expect_selfie(safify(str(exc_info.value))).to_be(
"Snapshot mismatch, TODO: string comparison"
"Snapshot mismatch (error msg could be better https://github.com/diffplug/selfie/issues/501)"
)


Expand Down
4 changes: 3 additions & 1 deletion python/selfie-lib/selfie_lib/SnapshotSystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,9 @@ def msg_snapshot_not_found_no_such_file(self, file) -> str:
return self.msg(f"Snapshot not found: no such file {file}")

def msg_snapshot_mismatch(self, expected: str, actual: str) -> str: # noqa: ARG002
return self.msg("Snapshot mismatch, TODO: string comparison")
return self.msg(
"Snapshot mismatch (error msg could be better https://github.com/diffplug/selfie/issues/501)"
)

def msg_snapshot_mismatch_binary(self, expected: bytes, actual: bytes) -> str:
return self.msg_snapshot_mismatch(
Expand Down
4 changes: 1 addition & 3 deletions selfie.dev/public/_redirects
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/jvm/advanced /jvm/facets 301
/js https://github.com/diffplug/selfie/issues/84
/js/* https://github.com/diffplug/selfie/issues/84
/py https://github.com/diffplug/selfie/issues/85
/go https://github.com/diffplug/selfie/issues/85
/go/* https://github.com/diffplug/selfie/issues/85
/other-platforms https://github.com/diffplug/selfie/issues/85
/other-platforms/* https://github.com/diffplug/selfie/issues/85
/cs490 https://docs.google.com/presentation/d/1K_xOISzzx0NRnNi_p7GrLIFVh5u9s0mstq2m3Idq19Q/edit?usp=sharing
/other-platforms/* https://github.com/diffplug/selfie/issues/85
16 changes: 8 additions & 8 deletions selfie.dev/src/components/ButtonList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,24 @@ export function ButtonList() {
"desktop:w-[490px]"
)}
>
<Link href="/jvm">
<Link href="/py">
<Button
className={
["jvm", ""].includes(selectedLanguage)
? pressedClasses
: unPressedClasses
selectedLanguage === "py" ? pressedClasses : unPressedClasses
}
>
jvm
py
</Button>
</Link>
<Link href="/py">
<Link href="/jvm">
<Button
className={
selectedLanguage === "py" ? pressedClasses : unPressedClasses
["jvm", ""].includes(selectedLanguage)
? pressedClasses
: unPressedClasses
}
>
py
jvm
</Button>
</Link>
<Link href="/js">
Expand Down
6 changes: 3 additions & 3 deletions selfie.dev/src/components/HeroDemoGif.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ export function ButtonList() {
"desktop:w-[490px]"
)}
>
<Link href="/py">
<Button className={unPressedClasses}>py</Button>
</Link>{" "}
<Link href="/jvm">
<Button className={unPressedClasses}>jvm</Button>
</Link>{" "}
<Link href="/js">
<Button className={unPressedClasses}>js</Button>
</Link>{" "}
<Link href="/other-platforms">
<Button className={unPressedClasses}>py</Button>
</Link>{" "}
<Link href="/other-platforms">
<Button className={unPressedClasses}>...</Button>
</Link>
Expand Down
5 changes: 3 additions & 2 deletions selfie.dev/src/pages/jvm/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ expectSelfie(TimeUnit.DAYS.toMillis(365*1_000_000L)).toBe(31_536_000_000_000_000
expectSelfie(new byte[100]).toMatchDisk();
```

But the real power of selfie is asserting on arbitrary objects using **facets**, which are covered in the [advanced section](/jvm/facets).
But the real power of selfie is asserting on arbitrary objects using **facets**, which are covered in the [facets section](/jvm/facets).

## Reference

Expand All @@ -203,6 +203,7 @@ Full API documentation is available at [kdoc.selfie.dev](https://kdoc.selfie.dev
- `interactive`, default
- `readonly`, default if `CI` environment variable is `true`
- `overwrite`, all snapshots can be overwritten
- `Camera` and `Lens` are covered in the [advanced section](/jvm/facets).
- `Camera` and `Lens` are covered in the [facet section](/jvm/facets)
- `cacheSelfie` and binary snapshots (`toBeBase64` and `toBeFile`) are covered in the [cache section](/jvm/cache)

*Pull requests to improve the landing page and documentation are greatly appreciated, you can find the [source code here](https://github.com/diffplug/selfie).*
4 changes: 2 additions & 2 deletions selfie.dev/src/pages/py/cache.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export const imageUrl = "https://selfie.dev/cache.webp";

<DocsImage imgAbsoluteUrl={imageUrl} />

*`cacheSelfie` helps you build fast deterministic tests even if they contain slow non-deterministic components. A generative AI example is available [here](https://github.com/diffplug/selfie/blob/main/python/example-pytest-selfie/tests/cache_selfie_test.py).*
*`cache_selfie` helps you build fast deterministic tests even if they contain slow non-deterministic components. A generative AI example is available [here](https://github.com/diffplug/selfie/blob/main/python/example-pytest-selfie/tests/cache_test.py).*

To use `expect_selfie`, you pass a _value_ that you want to snapshot.

Expand Down Expand Up @@ -46,7 +46,7 @@ You have these choices for specifying the data in a snapshot:

```python
cache_selfie(lambda: "string").to_be("string")
cache_selfie(lambda:"string").to_match_disk()
cache_selfie(lambda: "string").to_match_disk()
cache_selfie_binary(lambda: bytearray[3]).to_be_base64("AAAA")
cache_selfie_binary(lambda: bytearray[3]).to_be_file("pkg/someFile.ext")
cache_selfie_binary(lambda: bytearray[3]).to_match_disk()
Expand Down
1 change: 1 addition & 0 deletions selfie.dev/src/pages/py/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,6 @@ Full API documentation is available at [pydoc.selfie.dev](https://pydoc.selfie.d
- `readonly`, default if `CI` environment variable is `true`
- `overwrite`, all snapshots can be overwritten
- `Camera` and `Lens` are covered in the [facets section](/py/facets).
- `cache_selfie` and binary snapshots (`to_be_base64` and `to_be_file`) are covered in the [cache section](/py/cache)

_Pull requests to improve the landing page and documentation are greatly appreciated, you can find the [source code here](https://github.com/diffplug/selfie)._
Loading