Skip to content

Commit 3ac2ce8

Browse files
authored
feat(serializer): add snapshot regex value matcher and bypass custom repr helper (#791)
1 parent 9a2fffb commit 3ac2ce8

File tree

9 files changed

+314
-56
lines changed

9 files changed

+314
-56
lines changed

README.md

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ def __repr__(self) -> str:
8282
return "MyCustomClass(...)"
8383
```
8484

85+
If you need bypass a custom object representation to use the amber standard, it is easy using the following helpers.
86+
87+
```python
88+
def test_object_as_named_tuple(snapshot):
89+
assert snapshot == AmberDataSerializer.object_as_named_tuple(obj_with_custom_repr)
90+
```
91+
92+
> See `test_snapshot_object_as_named_tuple_class` for an example on automatically doing this for all nested properties
93+
8594
#### Attributes
8695

8796
If you want to limit what properties are serialized at a class type level you could either:
@@ -153,12 +162,13 @@ Syrupy comes with built-in helpers that can be used to make easy work of using p
153162
Easy way to build a matcher that uses the path and value type to replace serialized data.
154163
When strict, this will raise a `ValueError` if the types specified are not matched.
155164

156-
| Argument | Description |
157-
| --------- | ---------------------------------------------------------------------------------------------------------------------------------- |
158-
| `mapping` | Dict of path string to tuples of class types, including primitives e.g. (MyClass, UUID, datetime, int, str) |
159-
| `types` | Tuple of class types used if none of the path strings from the mapping are matched |
160-
| `strict` | If a path is matched but the value at the path does not match one of the class types in the tuple then a `PathTypeError` is raised |
161-
| `regex` | If true, the `mapping` key is treated as a regular expression when matching paths |
165+
| Argument | Description |
166+
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------- |
167+
| `mapping` | Dict of path string to tuples of class types, including primitives e.g. (MyClass, UUID, datetime, int, str) |
168+
| `types` | Tuple of class types used if none of the path strings from the mapping are matched |
169+
| `strict` | If a path is matched but the value at the path does not match one of the class types in the tuple then a `PathTypeError` is raised |
170+
| `regex` | If true, the `mapping` key is treated as a regular expression when matching paths |
171+
| `replacer` | Called with any matched value and result is used as the replacement that is serialized. Defaults to the object type when not given |
162172

163173
```py
164174
from syrupy.matchers import path_type
@@ -183,6 +193,19 @@ def test_bar(snapshot):
183193
# ---
184194
```
185195

196+
> NOTE: When `regex` is `True` all matcher mappings are treated as regex patterns
197+
198+
###### `path_value(mapping=None, *, **kwargs)`
199+
200+
Shares the same `kwargs` as `path_type` matcher, with the exception of the `mapping` argument type.
201+
Only runs replacement for objects at a matching path where the value of the mapping also matches the object data string repr.
202+
203+
| Argument | Description |
204+
| --------- | ---------------------------------------------------------- |
205+
| `mapping` | Dict of path string to object value string representations |
206+
207+
> See `test_regex_matcher_str_value` for example usage.
208+
186209
#### `exclude`
187210

188211
This allows you to filter out object properties from the serialized snapshot.
@@ -359,6 +382,32 @@ The generated snapshot:
359382
}
360383
```
361384

385+
Or a case where the value needs to be replaced using a condition e.g. file path string
386+
387+
```py
388+
import re
389+
390+
from syrupy.matchers import path_type
391+
392+
def test_matches_generated_string_value(snapshot, tmp_file):
393+
matcher = path_value(
394+
mapping={"file_path": r"\w+://(.*/)+dir/filename.txt"},
395+
replacer=lambda _, match: match[0].replace(match[1], "<tmp-file-path>/"),
396+
types=(str,),
397+
)
398+
399+
assert snapshot(matcher=matcher) == tmp_file
400+
```
401+
402+
The generated snapshot:
403+
404+
```json
405+
{
406+
"name": "Temp Files",
407+
"file_path": "scheme://<tmp-file-path>/dir/filename.txt"
408+
}
409+
```
410+
362411
### Extending Syrupy
363412

364413
- [Custom snapshot directory 1](https://github.com/tophat/syrupy/tree/main/tests/examples/test_custom_snapshot_directory.py)

0 commit comments

Comments
 (0)