diff --git a/changelog.d/20241108_192001_15r10nk-git_fix_cli.md b/changelog.d/20241108_192001_15r10nk-git_fix_cli.md
new file mode 100644
index 00000000..a4df405c
--- /dev/null
+++ b/changelog.d/20241108_192001_15r10nk-git_fix_cli.md
@@ -0,0 +1,40 @@
+
+
+
+### Added
+
+- command line shortcuts can be defined to simplify your workflows. `--review` and `--fix` are defined by default. See the [documentation](https://15r10nk.github.io/inline-snapshot/configuration/) for details.
+
+
+
+
+
diff --git a/changelog.d/20241109_074441_15r10nk-git_fix_cli.md b/changelog.d/20241109_074441_15r10nk-git_fix_cli.md
new file mode 100644
index 00000000..e4cd527b
--- /dev/null
+++ b/changelog.d/20241109_074441_15r10nk-git_fix_cli.md
@@ -0,0 +1,42 @@
+
+
+
+
+
+### Changed
+
+- `--inline-snapshot=create/fix/trim/update` will no longer show reports for other categories.
+ You can use `--inline-snapshot=create,report` if you want to use the old behaviour.
+
+
+
+
diff --git a/docs/categories.md b/docs/categories.md
index 8145aa02..dd124799 100644
--- a/docs/categories.md
+++ b/docs/categories.md
@@ -58,7 +58,7 @@ The result of each comparison is `True` if you change something from this catego
-
+
``` python
def test_something():
assert 8 == snapshot(5)
diff --git a/docs/configuration.md b/docs/configuration.md
index c3f86efd..76f269ef 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -1,15 +1,20 @@
-
-
Default configuration:
``` toml
[tool.inline-snapshot]
hash-length=15
default-flags=["short-report"]
+
+[tool.inline-snapshot.shortcuts]
+review=["review"]
+fix=["create","fix"]
```
-* *hash-length:* specifies the length of the hash used by `external()` in the code representation.
+* **hash-length:** specifies the length of the hash used by `external()` in the code representation.
This does not affect the hash length used to store the data.
The hash should be long enough to avoid hash collisions.
-* *default-flags:* defines which flags should be used if there are no flags specified with `--inline-snapshot=...`.
+* **default-flags:** defines which flags should be used if there are no flags specified with `--inline-snapshot=...`.
You can also use the environment variable `INLINE_SNAPSHOT_DEFAULT_FLAGS=...` to specify the flags and to override those in the configuration file.
+
+* **shortcuts:** allows you to define custom commands to simplify your workflows.
+ `--fix` and `--review` are defined by default, but this configuration can be changed to fit your needs.
diff --git a/docs/eq_snapshot.md b/docs/eq_snapshot.md
index 899ba13e..94b02f5f 100644
--- a/docs/eq_snapshot.md
+++ b/docs/eq_snapshot.md
@@ -21,7 +21,7 @@ Example:
```
=== "value changed"
-
+
``` python hl_lines="2"
def test_something():
assert 2 + 40 == snapshot(4)
@@ -111,7 +111,7 @@ Example:
```
=== "changed payload"
-
+
``` python hl_lines="9"
from inline_snapshot import snapshot
from dirty_equals import IsDatetime
diff --git a/docs/index.md b/docs/index.md
index d17d9c16..c8f8c957 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -55,7 +55,7 @@ Maybe that is correct and you should fix your code, or
your code is correct and you want to update your test results.
=== "changed code"
-
+
``` python hl_lines="2"
def something():
return (1548 * 18489) // 18
diff --git a/docs/limitations.md b/docs/limitations.md
new file mode 100644
index 00000000..1435e501
--- /dev/null
+++ b/docs/limitations.md
@@ -0,0 +1,8 @@
+
+## pytest assert rewriting is disabled
+
+inline-snapshot must disable pytest assert-rewriting if you use report/review/create/fix/trim/update flags.
+
+## xdist is not supported
+
+You can not use inline-snapshot in combination with `pytest-xdist`. The use of `-n=...` implies `--inline-snapshot=disable`.
diff --git a/docs/testing.md b/docs/testing.md
index b712b7aa..9f6b1a2b 100644
--- a/docs/testing.md
+++ b/docs/testing.md
@@ -59,7 +59,7 @@ The following example shows how you can use the `Example` class to test what inl
report=snapshot(
"""\
Error: one snapshot is missing a value (--inline-snapshot=create)
- You can also use --inline-snapshot=review to approve the changes interactiv\
+ You can also use --inline-snapshot=review to approve the changes interactively\
"""
),
).run_pytest( # run with create flag and check the changed files
diff --git a/mkdocs.yml b/mkdocs.yml
index 3158094f..82efbc38 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -46,6 +46,7 @@ nav:
- Configuration: configuration.md
- Code generation: code_generation.md
- Testing: testing.md
+- Limitations: limitations.md
- Contributing: contributing.md
- Changelog: changelog.md
diff --git a/pyproject.toml b/pyproject.toml
index 95026fd4..fdf30424 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -163,3 +163,7 @@ venvPath = ".nox"
[tool.scriv]
format = "md"
version = "command: cz bump --get-next"
+
+[tool.inline-snapshot.shortcuts]
+sfix="create,fix"
+review="create,review"
diff --git a/src/inline_snapshot/_config.py b/src/inline_snapshot/_config.py
index 4215b84e..32b27108 100644
--- a/src/inline_snapshot/_config.py
+++ b/src/inline_snapshot/_config.py
@@ -3,8 +3,10 @@
from dataclasses import dataclass
from dataclasses import field
from pathlib import Path
+from typing import Dict
from typing import List
+
if sys.version_info >= (3, 11):
from tomllib import loads
else:
@@ -15,6 +17,7 @@
class Config:
hash_length: int = 12
default_flags: List[str] = field(default_factory=lambda: ["short-report"])
+ shortcuts: Dict[str, List[str]] = field(default_factory=dict)
config = Config()
@@ -35,11 +38,16 @@ def read_config(path: Path) -> Config:
result.hash_length = config["hash-length"]
except KeyError:
pass
+
try:
result.default_flags = config["default-flags"]
except KeyError:
pass
+ result.shortcuts = config.get(
+ "shortcuts", {"fix": ["create", "fix"], "review": ["review"]}
+ )
+
env_var = "INLINE_SNAPSHOT_DEFAULT_FLAGS"
if env_var in os.environ:
result.default_flags = os.environ[env_var].split(",")
diff --git a/src/inline_snapshot/_inline_snapshot.py b/src/inline_snapshot/_inline_snapshot.py
index 586965a4..26c98478 100644
--- a/src/inline_snapshot/_inline_snapshot.py
+++ b/src/inline_snapshot/_inline_snapshot.py
@@ -44,6 +44,14 @@ class NotImplementedYet(Exception):
_files_with_snapshots: Set[str] = set()
_missing_values = 0
+_incorrect_values = 0
+
+
+def _return(result):
+ global _incorrect_values
+ if not result:
+ _incorrect_values += 1
+ return result
class InlineSnapshotSyntaxWarning(Warning):
@@ -328,8 +336,11 @@ def use_valid_old_values(old_value, new_value):
if self._new_value is undefined:
self._new_value = use_valid_old_values(self._old_value, clone(other))
-
- return self._visible_value() == other
+ if self._old_value is undefined or ignore_old_value():
+ return True
+ return _return(self._old_value == other)
+ else:
+ return _return(self._new_value == other)
def _new_code(self):
return self._value_to_code(self._new_value)
@@ -514,12 +525,14 @@ def _generic_cmp(self, other):
if self._new_value is undefined:
self._new_value = clone(other)
+ if self._old_value is undefined or ignore_old_value():
+ return True
+ return _return(self.cmp(self._old_value, other))
else:
- self._new_value = (
- self._new_value if self.cmp(self._new_value, other) else clone(other)
- )
+ if not self.cmp(self._new_value, other):
+ self._new_value = clone(other)
- return self.cmp(self._visible_value(), other)
+ return _return(self.cmp(self._visible_value(), other))
def _new_code(self):
return self._value_to_code(self._new_value)
@@ -609,7 +622,7 @@ def __contains__(self, item):
if ignore_old_value() or self._old_value is undefined:
return True
else:
- return item in self._old_value
+ return _return(item in self._old_value)
def _new_code(self):
return self._value_to_code(self._new_value)
diff --git a/src/inline_snapshot/pytest_plugin.py b/src/inline_snapshot/pytest_plugin.py
index d97a4407..ae8235a2 100644
--- a/src/inline_snapshot/pytest_plugin.py
+++ b/src/inline_snapshot/pytest_plugin.py
@@ -21,7 +21,7 @@
from ._rewrite_code import ChangeRecorder
-def pytest_addoption(parser):
+def pytest_addoption(parser, pluginmanager):
group = parser.getgroup("inline-snapshot")
group.addoption(
@@ -39,9 +39,22 @@ def pytest_addoption(parser):
"fix: change snapshots which currently break your tests\n",
)
+ config_path = Path("pyproject.toml")
+ if config_path.exists():
+ config = _config.read_config(Path("pyproject.toml"))
+ for name, value in config.shortcuts.items():
+ value = ",".join(value)
+ group.addoption(
+ f"--{name}",
+ action="store_const",
+ const=value,
+ dest="inline_snapshot",
+ help=f'shortcut for "--inline-snapshot={value}"',
+ )
+
categories = {"create", "update", "trim", "fix"}
-flags = {}
+flags = set()
def xdist_running(config):
@@ -104,20 +117,28 @@ def pytest_configure(config):
@pytest.fixture(autouse=True)
def snapshot_check():
_inline_snapshot._missing_values = 0
+ _inline_snapshot._incorrect_values = 0
yield
missing_values = _inline_snapshot._missing_values
+ incorrect_values = _inline_snapshot._incorrect_values
if missing_values != 0 and not _inline_snapshot._update_flags.create:
pytest.fail(
(
- f"your snapshot is missing one value run pytest with --inline-snapshot=create to create it"
+ f"your snapshot is missing one value."
if missing_values == 1
- else f"your snapshot is missing {missing_values} values run pytest with --inline-snapshot=create to create them"
+ else f"your snapshot is missing {missing_values} values."
),
pytrace=False,
)
+ if incorrect_values != 0 and not _inline_snapshot._update_flags.fix:
+ pytest.fail(
+ "some snapshots in this test have incorrect values.",
+ pytrace=False,
+ )
+
def pytest_assertrepr_compare(config, op, left, right):
results = []
@@ -264,7 +285,7 @@ def report(flag, message, message_n):
if sum(snapshot_changes.values()) != 0:
console.print(
- "\nYou can also use [b]--inline-snapshot=review[/] to approve the changes interactiv",
+ "\nYou can also use [b]--inline-snapshot=review[/] to approve the changes interactively",
highlight=False,
)
@@ -279,6 +300,9 @@ def report(flag, message, message_n):
if not changes[flag]:
continue
+ if not {"review", "report", flag} & flags:
+ continue
+
console.rule(f"[yellow bold]{flag.capitalize()} snapshots")
with ChangeRecorder().activate() as cr:
diff --git a/src/inline_snapshot/testing/_example.py b/src/inline_snapshot/testing/_example.py
index a52ae0b0..6ed4e7a3 100644
--- a/src/inline_snapshot/testing/_example.py
+++ b/src/inline_snapshot/testing/_example.py
@@ -32,6 +32,7 @@ def snapshot_env():
external.storage,
inline_snapshot._files_with_snapshots,
inline_snapshot._missing_values,
+ inline_snapshot._incorrect_values,
)
inline_snapshot.snapshots = {}
@@ -40,6 +41,7 @@ def snapshot_env():
external.storage = None
inline_snapshot._files_with_snapshots = set()
inline_snapshot._missing_values = 0
+ inline_snapshot._incorrect_values = 0
try:
yield
@@ -51,6 +53,7 @@ def snapshot_env():
external.storage,
inline_snapshot._files_with_snapshots,
inline_snapshot._missing_values,
+ inline_snapshot._incorrect_values,
) = current
diff --git a/tests/test_config.py b/tests/test_config.py
index 85d8e76d..98fcb518 100644
--- a/tests/test_config.py
+++ b/tests/test_config.py
@@ -41,3 +41,16 @@ def test_config_env():
Example(file_to_trim).run_pytest(
env={"INLINE_SNAPSHOT_DEFAULT_FLAGS": "trim"}, changed_files=trimmed_files
)
+
+
+def test_shortcuts():
+
+ Example(
+ {
+ **file_to_trim,
+ "pyproject.toml": """
+[tool.inline-snapshot.shortcuts]
+strim=["trim"]
+ """,
+ }
+ ).run_pytest(["--strim"], changed_files=trimmed_files)
diff --git a/tests/test_external.py b/tests/test_external.py
index acab3b7f..05958108 100644
--- a/tests/test_external.py
+++ b/tests/test_external.py
@@ -87,20 +87,6 @@ def test_something():
assert result.report == snapshot(
"""\
--------------------------------- Fix snapshots ---------------------------------
-+-------------------------------- test_file.py --------------------------------+
-| @@ -4,5 +4,5 @@ |
-| |
-| from inline_snapshot import external |
-| |
-| def test_something(): |
-| - assert "hello" == snapshot(external("bbbbb*.txt")) |
-| + assert "hello" == snapshot("hello") |
-| assert 2 == snapshot(1+1) |
-+------------------------------------------------------------------------------+
-These changes are not applied.
-Use --inline-snapshot=fix to apply them, or use the interactive mode with
---inline-snapshot=review
------------------------------- Update snapshots -------------------------------
+-------------------------------- test_file.py --------------------------------+
| @@ -5,4 +5,4 @@ |
diff --git a/tests/test_pytest_plugin.py b/tests/test_pytest_plugin.py
index 14413c96..896eec95 100644
--- a/tests/test_pytest_plugin.py
+++ b/tests/test_pytest_plugin.py
@@ -23,7 +23,7 @@ def test_a():
assert result.report == snapshot(
"""\
Error: one snapshot is missing a value (--inline-snapshot=create)
-You can also use --inline-snapshot=review to approve the changes interactiv
+You can also use --inline-snapshot=review to approve the changes interactively
"""
)
@@ -65,12 +65,12 @@ def test_a():
result = project.run()
- result.assert_outcomes(failed=1)
+ result.assert_outcomes(failed=1, errors=1)
assert result.report == snapshot(
"""\
Error: one snapshot has incorrect values (--inline-snapshot=fix)
-You can also use --inline-snapshot=review to approve the changes interactiv
+You can also use --inline-snapshot=review to approve the changes interactively
"""
)
@@ -157,7 +157,7 @@ def test_a():
assert result.report == snapshot(
"""\
Info: one snapshot can be trimmed (--inline-snapshot=trim)
-You can also use --inline-snapshot=review to approve the changes interactiv
+You can also use --inline-snapshot=review to approve the changes interactively
"""
)
@@ -199,13 +199,13 @@ def test_a():
result = project.run()
- result.assert_outcomes(failed=1)
+ result.assert_outcomes(failed=1, errors=1)
assert result.report == snapshot(
"""\
Error: one snapshot has incorrect values (--inline-snapshot=fix)
Info: one snapshot can be trimmed (--inline-snapshot=trim)
-You can also use --inline-snapshot=review to approve the changes interactiv
+You can also use --inline-snapshot=review to approve the changes interactively
"""
)
@@ -236,21 +236,6 @@ def test_a():
| assert 5 == snapshot(5) |
+------------------------------------------------------------------------------+
These changes will be applied, because you used --inline-snapshot=trim
-------------------------------- Update snapshots -------------------------------
-+-------------------------------- test_file.py --------------------------------+
-| @@ -4,6 +4,6 @@ |
-| |
-| |
-| |
-| def test_a(): |
-| - assert "5" == snapshot('''5''') |
-| + assert "5" == snapshot("5") |
-| assert 5 <= snapshot(5) |
-| assert 5 == snapshot(5) |
-+------------------------------------------------------------------------------+
-These changes are not applied.
-Use --inline-snapshot=update to apply them, or use the interactive mode with
---inline-snapshot=review
"""
)
@@ -283,6 +268,73 @@ def test_a():
)
+def test_multiple_report(project):
+ project.setup(
+ """\
+def test_a():
+ assert "5" == snapshot('''5''')
+ assert 5 <= snapshot(8)
+ assert 5 == snapshot(4)
+"""
+ )
+
+ result = project.run("--inline-snapshot=trim,report")
+
+ assert result.report == snapshot(
+ """\
+-------------------------------- Fix snapshots ---------------------------------
++-------------------------------- test_file.py --------------------------------+
+| @@ -6,4 +6,4 @@ |
+| |
+| def test_a(): |
+| assert "5" == snapshot('''5''') |
+| assert 5 <= snapshot(8) |
+| - assert 5 == snapshot(4) |
+| + assert 5 == snapshot(5) |
++------------------------------------------------------------------------------+
+These changes are not applied.
+Use --inline-snapshot=fix to apply them, or use the interactive mode with
+--inline-snapshot=review
+-------------------------------- Trim snapshots --------------------------------
++-------------------------------- test_file.py --------------------------------+
+| @@ -5,5 +5,5 @@ |
+| |
+| |
+| def test_a(): |
+| assert "5" == snapshot('''5''') |
+| - assert 5 <= snapshot(8) |
+| + assert 5 <= snapshot(5) |
+| assert 5 == snapshot(4) |
++------------------------------------------------------------------------------+
+These changes will be applied, because you used --inline-snapshot=trim
+------------------------------- Update snapshots -------------------------------
++-------------------------------- test_file.py --------------------------------+
+| @@ -4,6 +4,6 @@ |
+| |
+| |
+| |
+| def test_a(): |
+| - assert "5" == snapshot('''5''') |
+| + assert "5" == snapshot("5") |
+| assert 5 <= snapshot(5) |
+| assert 5 == snapshot(4) |
++------------------------------------------------------------------------------+
+These changes are not applied.
+Use --inline-snapshot=update to apply them, or use the interactive mode with
+--inline-snapshot=review
+"""
+ )
+
+ assert project.source == snapshot(
+ """\
+def test_a():
+ assert "5" == snapshot('''5''')
+ assert 5 <= snapshot(5)
+ assert 5 == snapshot(4)
+"""
+ )
+
+
def test_black_config(project):
project.setup(
"""\
@@ -492,12 +544,12 @@ def test_sub_snapshot():
"""\
============================================================================ ERRORS ============================================================================
____________________________________________________________ ERROR at teardown of test_sub_snapshot ____________________________________________________________
-your snapshot is missing one value run pytest with --inline-snapshot=create to create it
+your snapshot is missing one value.
======================================================================= inline snapshot ========================================================================
Error: one snapshot is missing a value (--inline-snapshot=create)
-You can also use --inline-snapshot=review to approve the changes interactiv
+You can also use --inline-snapshot=review to approve the changes interactively
=================================================================== short test summary info ====================================================================
-ERROR test_file.py::test_sub_snapshot - Failed: your snapshot is missing one value run pytest with --inline-snapshot=create to create it
+ERROR test_file.py::test_sub_snapshot - Failed: your snapshot is missing one value.
================================================================== 1 passed, 1 error in