diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 51340beb..da22c03c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: python-version: ${{matrix.python-version}} - run: | - uv run ${{matrix.extra_deps}} -m ${{ matrix.os == 'ubuntu-latest' && 'coverage run -m' || '' }} pytest -n=auto + uv run ${{matrix.extra_deps}} --extra black -m ${{ matrix.os == 'ubuntu-latest' && 'coverage run -m' || '' }} pytest -n=auto -vv - run: | uv run -m coverage combine mv .coverage .coverage.${{ matrix.python-version }}-${{matrix.os}}-${{strategy.job-index}} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9a05e291..de72e6fe 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,6 +27,14 @@ repos: repo: https://github.com/myint/autoflake rev: v2.3.1 +- repo: local + hooks: + - id: replace-words + name: Replace Words + entry: python3 scripts/replace_words.py + language: system + files: \.(md|py)$ + - repo: https://github.com/asottile/setup-cfg-fmt rev: v2.5.0 hooks: diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bf28927..5eb44e99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ ## Fixed -- use '.model_fields' on pydantic model class and not instance. This fixes a deprecation warning in the upcomming pydantic v2.11 (#169) +- use '.model_fields' on pydantic model class and not instance. This fixes a deprecation warning in the upcoming pydantic v2.11 (#169) # 0.18.1 — 2024-12-22 @@ -346,7 +346,7 @@ ### Fix -- remove upper bound from dependencies in pyproject.toml +- remove upper bound from dependency in pyproject.toml ## v0.5.1 (2023-10-20) diff --git a/changelog.d/20250106_220025_15r10nk-git_format_cmd.md b/changelog.d/20250106_220025_15r10nk-git_format_cmd.md new file mode 100644 index 00000000..fa816755 --- /dev/null +++ b/changelog.d/20250106_220025_15r10nk-git_format_cmd.md @@ -0,0 +1,7 @@ +### Added + +- You can now specify which tool you want to use to format your code by setting a `format-command` in your [configuration](https://15r10nk.github.io/inline-snapshot/latest/configuration/#format-command). + +### Changed + +- **BREAKING-CHANGE** you have to install `inline-snapshot[black]` now if you want to format your code like in the previous versions. This option is not required if you use a `format-command`. diff --git a/changelog.d/20250109_071706_15r10nk-git_format_cmd.md b/changelog.d/20250109_071706_15r10nk-git_format_cmd.md new file mode 100644 index 00000000..95548c00 --- /dev/null +++ b/changelog.d/20250109_071706_15r10nk-git_format_cmd.md @@ -0,0 +1,4 @@ +### Fixed + +- Load default config values even if `[tool.inline-snapshot]` is missing. + This makes the documented default shortcuts `--review` and `--fix` work. diff --git a/docs/changelog.md b/docs/changelog.md index 786b75d5..3e1b4202 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1 +1,16 @@ + + +``` python exec="1" +from pathlib import Path + +new_changes = list(Path.cwd().glob("changelog.d/*.md")) + +if new_changes: + print("# upcomming changes") + +for file in new_changes: + print(file.read_text().replace("###", "##")) +``` + + --8<-- "CHANGELOG.md" diff --git a/docs/code_generation.md b/docs/code_generation.md index 42ccbcfd..fd76d618 100644 --- a/docs/code_generation.md +++ b/docs/code_generation.md @@ -97,15 +97,25 @@ The code is generated in the following way: ``` -4. The code is formatted with black. +4. The new code fragments are formatted with black if it is installed. + !!! note + Black is an optional dependency since inline-snapshot v0.19.0. + You can install it with: + ``` sh + pip install inline-snapshot[black] + ``` -5. The whole file is formatted with black if it was formatted before. +5. The whole file is formatted + * with black if it was formatted with black before. - !!! note - The black formatting of the whole file could not work for the following reasons: + !!! note + The black formatting of the whole file could not work for the following reasons: + + 1. black is configured with cli arguments and not in a configuration file.
+ **Solution:** configure black in a [configuration file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file) + 2. inline-snapshot uses a different black version.
+ **Solution:** specify which black version inline-snapshot should use by adding black with a specific version to your dependencies. + 3. black is not installed. Black is an optional dependency since inline-snapshot v0.19.0 - 1. black is configured with cli arguments and not in a configuration file.
- **Solution:** configure black in a [configuration file](https://black.readthedocs.io/en/stable/usage_and_configuration/the_basics.html#configuration-via-a-file) - 2. inline-snapshot uses a different black version.
- **Solution:** specify which black version inline-snapshot should use by adding black with a specific version to your dependencies. + * or with the [format-command][format-command] if you defined one. diff --git a/docs/configuration.md b/docs/configuration.md index 851c99cc..0a88cf84 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -4,6 +4,7 @@ Default configuration: [tool.inline-snapshot] hash-length=15 default-flags=["short-report"] +format-command="" [tool.inline-snapshot.shortcuts] review=["review"] @@ -23,3 +24,12 @@ fix=["create","fix"] By default, it will be `/.inline-snapshot`, where `` is replaced by the directory containing the Pytest configuration file, if any. External snapshots will be stored in the `external` subfolder of the storage directory. +* **format-command:[](){#format-command}** allows you to specify a custom command which is used to format the python code after code is changed. + ``` toml + [tool.inline-snapshot] + format-command="ruff format --stdin-filename {filename}" + ``` + The placeholder `{filename}` can be used to specify the filename if it is needed to find the correct formatting options for this file. + + !!! important + The command should **not** format the file on disk. The current file content (with the new code changes) is passed to *stdin* and the formatted content should be written to *stdout*. diff --git a/mkdocs.yml b/mkdocs.yml index 04fe6417..87cf55d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,6 +72,7 @@ markdown_extensions: - pymdownx.superfences - pymdownx.tabbed: alternate_style: true +- attr_list plugins: - mkdocstrings: @@ -85,6 +86,7 @@ plugins: - markdown-exec: ansi: required - replace-url +- autorefs extra: diff --git a/pyproject.toml b/pyproject.toml index 1801ebcf..45f718ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,12 +25,9 @@ classifiers = [ ] dependencies = [ "asttokens>=2.0.5", - "black>=23.3.0", - "click>=8.1.4", "executing>=2.1.0", "rich>=13.7.1", - "tomli>=2.0.0; python_version < '3.11'", - "typing-extensions" + "tomli>=2.0.0; python_version < '3.11'" ] description = "golden master/snapshot/approval testing library which puts the values right into your source code" keywords = [] @@ -39,6 +36,12 @@ readme = "README.md" requires-python = ">=3.8" version = "0.18.2" +[project.optional-dependencies] +black = [ + "black>=23.3.0", + "click>=8.1.4" +] + [dependency-groups] dev = [ "hypothesis>=6.75.5", @@ -99,6 +102,7 @@ dependencies = [ "mkdocs-material[imaging]>=9.5.17", "mike", "mkdocstrings[python]>=0.19.0", + "mkdocs-autorefs", "replace-url @ {root:uri}/docs/plugins", "pytest", "black" @@ -130,6 +134,7 @@ matrix.extra-deps.dependencies = [ [tool.hatch.envs.hatch-test] extra-dependencies = [ + "inline-snapshot[black]", "dirty-equals>=0.7.0", "hypothesis>=6.75.5", "mypy>=1.2.0", @@ -141,18 +146,20 @@ extra-dependencies = [ env-vars.TOP = "{root}" [tool.hatch.envs.hatch-test.scripts] -run = "pytest{env:HATCH_TEST_ARGS:} --use-uv {args}" -run-cov = "coverage run -m pytest{env:HATCH_TEST_ARGS:} --use-uv {args}" +run = "pytest{env:HATCH_TEST_ARGS:} {args}" +run-cov = "coverage run -m pytest{env:HATCH_TEST_ARGS:} {args}" cov-combine = "coverage combine" cov-report=["coverage report","coverage html"] [tool.hatch.envs.types] extra-dependencies = [ + "inline-snapshot[black]", "mypy>=1.0.0", "pytest", "hypothesis>=6.75.5", "pydantic", - "attrs" + "attrs", + "typing-extensions" ] [[tool.hatch.envs.types.matrix]] diff --git a/scripts/replace_words.py b/scripts/replace_words.py new file mode 100644 index 00000000..fa346d38 --- /dev/null +++ b/scripts/replace_words.py @@ -0,0 +1,24 @@ +import re +import sys + + +def replace_words(file_path, replacements): + with open(file_path) as file: + content = file.read() + + for old_word, new_word in replacements.items(): + content = re.sub(rf"\b{re.escape(old_word)}\b", new_word, content) + + with open(file_path, "w") as file: + file.write(content) + + +if __name__ == "__main__": + + replacements = { + "http://localhost:8000/inline-snapshot/": "https://15r10nk.github.io/inline-snapshot/latest/", + } + + for file_path in sys.argv[1:]: + print(file_path) + replace_words(file_path, replacements) diff --git a/src/inline_snapshot/_config.py b/src/inline_snapshot/_config.py index 99624c6d..aad23d1f 100644 --- a/src/inline_snapshot/_config.py +++ b/src/inline_snapshot/_config.py @@ -19,6 +19,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) + format_command: Optional[str] = None storage_dir: Optional[Path] = None @@ -27,35 +28,37 @@ class Config: def read_config(path: Path) -> Config: result = Config() + config = {} if path.exists(): - data = loads(path.read_text("utf-8")) try: config = data["tool"]["inline-snapshot"] except KeyError: pass - else: - try: - 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"]} - ) - - if storage_dir := config.get("storage-dir"): - storage_dir = Path(storage_dir) - if not storage_dir.is_absolute(): - # Make it relative to pyproject.toml, and absolute. - storage_dir = path.parent.joinpath(storage_dir).absolute() - result.storage_dir = storage_dir + + try: + 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"]} + ) + + if storage_dir := config.get("storage-dir"): + storage_dir = Path(storage_dir) + if not storage_dir.is_absolute(): + # Make it relative to pyproject.toml, and absolute. + storage_dir = path.parent.joinpath(storage_dir).absolute() + result.storage_dir = storage_dir + + result.format_command = config.get("format-command", None) env_var = "INLINE_SNAPSHOT_DEFAULT_FLAGS" if env_var in os.environ: diff --git a/src/inline_snapshot/_format.py b/src/inline_snapshot/_format.py index a0b8aa17..b3d5b6c8 100644 --- a/src/inline_snapshot/_format.py +++ b/src/inline_snapshot/_format.py @@ -1,11 +1,47 @@ +import subprocess as sp import warnings -from black import main -from click.testing import CliRunner -from inline_snapshot._problems import raise_problem +from rich.markup import escape + +from . import _config +from ._problems import raise_problem + + +def enforce_formatting(): + return _config.config.format_command is not None def format_code(text, filename): + if _config.config.format_command is not None: + format_command = _config.config.format_command.format(filename=filename) + result = sp.run( + format_command, shell=True, input=text.encode("utf-8"), capture_output=True + ) + if result.returncode != 0: + raise_problem( + f"""\ +[b]The format_command '{escape(format_command)}' caused the following error:[/b] +""" + + result.stdout.decode("utf-8") + + result.stderr.decode("utf-8") + ) + return text + return result.stdout.decode("utf-8") + + try: + from black import main + from click.testing import CliRunner + except ImportError: + raise_problem( + f"""\ +[b]inline-snapshot is not able to format your code.[/b] +This issue can be solved by: + * installing {escape('inline-snapshot[black]')} which gives you the same formatting like in older versions + * adding a `format-command` to your pyproject.toml (see [link=https://15r10nk.github.io/inline-snapshot/latest/configuration/#format-command]https://15r10nk.github.io/inline-snapshot/latest/configuration/#format-command[/link] for more information). +""" + ) + return text + with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -17,7 +53,7 @@ def format_code(text, filename): if result.exit_code != 0: raise_problem( """\ -black could not format your code, which might be caused by this issue: +[b]black could not format your code, which might be caused by this issue:[/b] [link=https://github.com/15r10nk/inline-snapshot/issues/138]https://github.com/15r10nk/inline-snapshot/issues/138[/link]\ """ ) diff --git a/src/inline_snapshot/_problems.py b/src/inline_snapshot/_problems.py index c8272ad8..d6a9641c 100644 --- a/src/inline_snapshot/_problems.py +++ b/src/inline_snapshot/_problems.py @@ -14,6 +14,7 @@ def report_problems(console: Console): return console.rule("[red]Problems") for problem in all_problems: - console.print(f"[b]{problem}") + console.print(f"{problem}") + console.print() all_problems = set() diff --git a/src/inline_snapshot/_rewrite_code.py b/src/inline_snapshot/_rewrite_code.py index 0cab4c56..109e4b90 100644 --- a/src/inline_snapshot/_rewrite_code.py +++ b/src/inline_snapshot/_rewrite_code.py @@ -13,8 +13,10 @@ import asttokens.util from asttokens import LineNumbers +from ._format import enforce_formatting from ._format import format_code + if sys.version_info >= (3, 10): from itertools import pairwise else: @@ -158,9 +160,11 @@ def new_code(self) -> str: code = self.filename.read_text("utf-8") - is_formatted = code == format_code(code, self.filename) + format_whole_file = enforce_formatting() or code == format_code( + code, self.filename + ) - if not is_formatted: + if not format_whole_file: logging.info(f"file is not formatted with black: {self.filename}") import black @@ -180,7 +184,7 @@ def new_code(self) -> str: ], ) - if is_formatted: + if format_whole_file: new_code = format_code(new_code, self.filename) return new_code diff --git a/src/inline_snapshot/_source_file.py b/src/inline_snapshot/_source_file.py index ba8a94bc..d3f55eca 100644 --- a/src/inline_snapshot/_source_file.py +++ b/src/inline_snapshot/_source_file.py @@ -2,6 +2,7 @@ from pathlib import Path from executing import Source +from inline_snapshot._format import enforce_formatting from inline_snapshot._format import format_code from inline_snapshot._utils import normalize from inline_snapshot._utils import simple_token @@ -24,7 +25,7 @@ def filename(self): return self._source.filename def _format(self, text): - if self._source is None: + if self._source is None or enforce_formatting(): return text else: return format_code(text, Path(self._source.filename)) diff --git a/src/inline_snapshot/_types.py b/src/inline_snapshot/_types.py index d6501894..50807a76 100644 --- a/src/inline_snapshot/_types.py +++ b/src/inline_snapshot/_types.py @@ -7,10 +7,10 @@ from typing import TYPE_CHECKING from typing import TypeVar -from typing_extensions import TypeAlias - if TYPE_CHECKING: + from typing_extensions import TypeAlias + T = TypeVar("T") Snapshot: TypeAlias = T diff --git a/src/inline_snapshot/_unmanaged.py b/src/inline_snapshot/_unmanaged.py index 5e46b9b5..111d86aa 100644 --- a/src/inline_snapshot/_unmanaged.py +++ b/src/inline_snapshot/_unmanaged.py @@ -17,13 +17,23 @@ def is_dirty_equal(value): def update_allowed(value): - return not (is_dirty_equal(value) or isinstance(value, (Is, Snapshot))) # type: ignore + global unmanaged_types + return not (is_dirty_equal(value) or isinstance(value, tuple(unmanaged_types))) # type: ignore + + +unmanaged_types = [Is, Snapshot] def is_unmanaged(value): return not update_allowed(value) +def declare_unmanaged(typ): + global unmanaged_types + unmanaged_types.append(typ) + return typ + + class Unmanaged: def __init__(self, value): self.value = value diff --git a/src/inline_snapshot/pytest_plugin.py b/src/inline_snapshot/pytest_plugin.py index 0c540b4e..afda98ab 100644 --- a/src/inline_snapshot/pytest_plugin.py +++ b/src/inline_snapshot/pytest_plugin.py @@ -46,7 +46,7 @@ def pytest_addoption(parser, pluginmanager): config_path = Path("pyproject.toml") if config_path.exists(): - config = _config.read_config(Path("pyproject.toml")) + config = _config.read_config(config_path) for name, value in config.shortcuts.items(): value = ",".join(value) group.addoption( diff --git a/src/inline_snapshot/testing/_example.py b/src/inline_snapshot/testing/_example.py index 62f0e82f..3badf584 100644 --- a/src/inline_snapshot/testing/_example.py +++ b/src/inline_snapshot/testing/_example.py @@ -78,6 +78,16 @@ def snapshot_env(): ) +def normalize(text): + text = ansi_escape.sub("", text) + + # fix windows problems + text = text.replace("\u2500", "-") + text = text.replace("\r", "") + text = text.replace(" \n", " ⏎\n") + return text + + class Example: def __init__(self, files: str | dict[str, str]): """ @@ -228,7 +238,7 @@ def run_inline( assert changed_files == current_files if report is not None: - assert report == report_output.getvalue() + assert report == normalize(report_output.getvalue()) return Example(self._read_files(tmp_path)) @@ -236,6 +246,7 @@ def run_pytest( self, args: list[str] = [], *, + term_columns=80, env: dict[str, str] = {}, changed_files: Snapshot[dict[str, str]] | None = None, report: Snapshot[str] | None = None, @@ -265,8 +276,6 @@ def run_pytest( cmd = [sys.executable, "-m", "pytest", *args] - term_columns = 80 - command_env = dict(os.environ) command_env["TERM"] = "unknown" command_env["COLUMNS"] = str( @@ -307,14 +316,7 @@ def run_pytest( report_str = "\n".join(report_list) - report_str = ansi_escape.sub("", report_str) - - # fix windows problems - report_str = report_str.replace("\u2500", "-") - report_str = report_str.replace("\r", "") - report_str = report_str.replace(" \n", " ⏎\n") - - assert report_str == report, repr(report_str) + assert normalize(report_str) == report, repr(report_str) if changed_files is not None: current_files = {} diff --git a/tests/_is_normalized.py b/tests/_is_normalized.py new file mode 100644 index 00000000..fa8bd8d4 --- /dev/null +++ b/tests/_is_normalized.py @@ -0,0 +1,23 @@ +from inline_snapshot._unmanaged import declare_unmanaged + + +@declare_unmanaged +class IsNormalized: + def __init__(self, func, value) -> None: + self._func = func + self._value = value + self._last_value = None + + def __eq__(self, other) -> bool: + self._last_value = self._func(other) + return self._last_value == self._value + + def __repr__(self): + return f"IsNormalized({self._value}, should_be={self._last_value!r})" + + +def normalization(func): + def f(value): + return IsNormalized(func, value) + + return f diff --git a/tests/conftest.py b/tests/conftest.py index 2159aa85..08993d16 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -43,15 +43,6 @@ def check_pypy(request): yield -def pytest_addoption(parser): - parser.addoption( - "--use-uv", - action="store_true", - default=False, - help="install different package versions at test time", - ) - - @pytest.fixture() def check_update(source): def w(source_code, *, flags="", reported_flags=None, number=1): diff --git a/tests/test_config.py b/tests/test_config.py index 98fcb518..8e11ccf8 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -54,3 +54,27 @@ def test_shortcuts(): """, } ).run_pytest(["--strim"], changed_files=trimmed_files) + + +def test_default_shortcuts(): + + Example( + { + **file_to_trim, + "pyproject.toml": """ + """, + } + ).run_pytest( + ["--fix"], + changed_files=snapshot( + { + "test_a.py": """\ +from inline_snapshot import snapshot + +def test_a(): + assert 1 <= snapshot(5) + assert 1 == snapshot(1) +""" + } + ), + ) diff --git a/tests/test_formating.py b/tests/test_formating.py index c8f4c6d6..9b347a7c 100644 --- a/tests/test_formating.py +++ b/tests/test_formating.py @@ -1,9 +1,13 @@ +import re +import sys from types import SimpleNamespace from click.testing import CliRunner from inline_snapshot import snapshot from inline_snapshot.testing import Example +from tests._is_normalized import normalization + def test_black_formatting_error(mocker): mocker.patch.object(CliRunner, "invoke", return_value=SimpleNamespace(exit_code=1)) @@ -33,9 +37,10 @@ def test_something(): ), report=snapshot( """\ -─────────────────────────────────── Problems ─────────────────────────────────── +----------------------------------- Problems ----------------------------------- black could not format your code, which might be caused by this issue: https://github.com/15r10nk/inline-snapshot/issues/138 + """ ), ) @@ -57,3 +62,152 @@ def test_a(): return None """ ).run_pytest(returncode=0) + + +def test_format_command(): + Example( + { + "fmt_cmd.py": """\ +from sys import stdin +import re + +text=stdin.read() +text=re.sub("#.*","",text) +print(text) +""", + "pyproject.toml": f"""\ +[tool.inline-snapshot] +format-command="{sys.executable} fmt_cmd.py {{filename}}" +""", + "test_a.py": """\ +from inline_snapshot import snapshot +# some comment +def test_a(): + assert "5" == snapshot('''3''')# abc +""", + } + ).run_pytest( + ["--inline-snapshot=fix"], + changed_files=snapshot( + { + "test_a.py": """\ +from inline_snapshot import snapshot + +def test_a(): + assert "5" == snapshot('5') + +""" + } + ), + ) + + +def test_format_command_fail(): + + @normalization + def NoPaths(text): + text = re.sub( + "The format_command.*following error:", + lambda m: m[0].replace("\n", ""), + text, + flags=re.MULTILINE | re.DOTALL, + ) + text = re.sub("/[^ ]*/", "/.../", text, flags=re.MULTILINE) + return text + + Example( + { + "fmt_cmd.py": """ +import sys +print("some problem") +sys.exit(1) +""", + "pyproject.toml": f"""\ +[tool.inline-snapshot] +format-command="{sys.executable} fmt_cmd.py {{filename}}" +""", + "test_a.py": """ +from inline_snapshot import snapshot + +def test_a(): + assert "5" == snapshot('''3''') +""", + } + ).run_pytest( + ["--inline-snapshot=fix"], + term_columns=200, + changed_files=snapshot( + { + "test_a.py": """\ + +from inline_snapshot import snapshot + +def test_a(): + assert "5" == snapshot('5') +""" + } + ), + report=NoPaths( + snapshot( + """\ +-------------------------------------------------------------------------------------------- Fix snapshots --------------------------------------------------------------------------------------------- ++--------------------------------------------------------------------------------------------- test_a.py ----------------------------------------------------------------------------------------------+ +| @@ -2,4 +2,4 @@ | +| | +| from inline_snapshot import snapshot | +| | +| def test_a(): | +| - assert "5" == snapshot('''3''') | +| + assert "5" == snapshot('5') | ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +These changes will be applied, because you used --inline-snapshot=fix +----------------------------------------------------------------------------------------------- Problems ----------------------------------------------------------------------------------------------- +The format_command '/.../python3 fmt_cmd.py /.../test_a.py' caused the following error: +some problem\ +""" + ) + ), + ) + + +def test_no_black(mocker): + + mocker.patch.dict(sys.modules, {"black": None}) + + Example( + { + "test_a.py": """ +from inline_snapshot import snapshot + +def test_a(): + assert "5" == snapshot('''3''') +""", + } + ).run_inline( + ["--inline-snapshot=fix"], + changed_files=snapshot( + { + "test_a.py": """\ + +from inline_snapshot import snapshot + +def test_a(): + assert "5" == snapshot('5') +""" + } + ), + report=snapshot( + """\ +----------------------------------- Problems ----------------------------------- +inline-snapshot is not able to format your code. +This issue can be solved by: + * installing inline-snapshot[black] which gives you the same formatting like in +older versions + * adding a `format-command` to your pyproject.toml (see ⏎ +https://15r10nk.github.io/inline-snapshot/latest/configuration/#format-command ⏎ +for more information). + + +""" + ), + ) diff --git a/tests/test_is_normalized.py b/tests/test_is_normalized.py new file mode 100644 index 00000000..dea01ace --- /dev/null +++ b/tests/test_is_normalized.py @@ -0,0 +1,31 @@ +from inline_snapshot import snapshot +from inline_snapshot.testing._example import Example + + +def test_repr(): + Example( + """\ +from inline_snapshot import snapshot +from tests._is_normalized import IsNormalized + +def test_a(): + n=IsNormalized(sorted,snapshot()) + assert [3,5,2] == n + assert repr(n)==snapshot() +""" + ).run_inline( + ["--inline-snapshot=create"], + changed_files=snapshot( + { + "test_something.py": """\ +from inline_snapshot import snapshot +from tests._is_normalized import IsNormalized + +def test_a(): + n=IsNormalized(sorted,snapshot([2, 3, 5])) + assert [3,5,2] == n + assert repr(n)==snapshot("IsNormalized([2, 3, 5], should_be=[2, 3, 5])") +""" + } + ), + )