diff --git a/src/syrupy/report.py b/src/syrupy/report.py index e6424507..09b3991f 100644 --- a/src/syrupy/report.py +++ b/src/syrupy/report.py @@ -299,7 +299,14 @@ def lines(self) -> Iterator[str]: for snapshot_fossil in self.unused: filepath = snapshot_fossil.location snapshots = (snapshot.name for snapshot in snapshot_fossil) - path_to_file = str(Path(filepath).relative_to(self.base_dir)) + + try: + path_to_file = str(Path(filepath).relative_to(self.base_dir)) + except ValueError: + # this is just used for display, so better to fallback to + # something vaguely reasonable (the full path) than give up + path_to_file = filepath + unused_snapshots = ", ".join(map(bold, sorted(snapshots))) yield warning_style(gettext(base_message)) + " {} ({})".format( unused_snapshots, path_to_file diff --git a/tests/integration/test_snapshot_outside_directory.py b/tests/integration/test_snapshot_outside_directory.py new file mode 100644 index 00000000..b241c6f0 --- /dev/null +++ b/tests/integration/test_snapshot_outside_directory.py @@ -0,0 +1,81 @@ +import pytest + + +@pytest.fixture +def testcases(testdir, tmp_path): + dirname = tmp_path.joinpath("__snapshots__") + testdir.makeconftest( + f""" + import pytest + + from syrupy.extensions.amber import AmberSnapshotExtension + + class CustomSnapshotExtension(AmberSnapshotExtension): + @property + def _dirname(self): + return {str(dirname)!r} + + @pytest.fixture + def snapshot(snapshot): + return snapshot.use_extension(CustomSnapshotExtension) + """ + ) + return { + "zero": ( + """ + def test_do_it(snapshot): + pass + """ + ), + "one": ( + """ + def test_do_it(snapshot): + assert snapshot == 'passed1' + """ + ), + "two": ( + """ + def test_do_it(snapshot): + assert snapshot == 'passed1' + assert snapshot == 'passed2' + """ + ), + } + + +@pytest.fixture +def generate_snapshots(testdir, testcases): + testdir.makepyfile(test_file=testcases["two"]) + result = testdir.runpytest("-v", "--snapshot-update") + return result, testdir, testcases + + +def test_generated_snapshots(generate_snapshots): + result = generate_snapshots[0] + result.stdout.re_match_lines((r"2 snapshots generated\.")) + assert "snapshots unused" not in result.stdout.str() + assert result.ret == 0 + + +def test_unmatched_snapshots(generate_snapshots): + _, testdir, testcases = generate_snapshots + testdir.makepyfile(test_file=testcases["one"]) + result = testdir.runpytest("-v") + result.stdout.re_match_lines((r"1 snapshot passed. 1 snapshot unused\.")) + assert result.ret == 1 + + +def test_updated_snapshots_partial_delete(generate_snapshots): + _, testdir, testcases = generate_snapshots + testdir.makepyfile(test_file=testcases["one"]) + result = testdir.runpytest("-v", "--snapshot-update") + result.stdout.re_match_lines(r"1 snapshot passed. 1 unused snapshot deleted\.") + assert result.ret == 0 + + +def test_updated_snapshots_full_delete(generate_snapshots): + _, testdir, testcases = generate_snapshots + testdir.makepyfile(test_file=testcases["zero"]) + result = testdir.runpytest("-v", "--snapshot-update") + result.stdout.re_match_lines(r"2 unused snapshots deleted\.") + assert result.ret == 0