Repository: tophat/syrupy

Issue:
having a dot in the file extension causes unexpected behavior
**Describe the bug**

Hello,

Thanks for syrupy! We ran into a small issue when customizing the file extension.

As mentioned in the title, I ran into an issue when trying to use an file extension like `png.zip`. I'm thinking, it's related to having and extra `.` in the file extension.

```console
$ pytest tests/syrupy/extensions/image/test_dot_in_extension.py --snapshot-update
=============================================================== test session starts ================================================================
platform darwin -- Python 3.10.9, pytest-7.2.1, pluggy-1.0.0
benchmark: 4.0.0 (defaults: timer=time.perf_counter disable_gc=False min_rounds=5 min_time=0.000005 max_time=1.0 calibration_precision=10 warmup=False warmup_iterations=100000)
rootdir: /Users/tolga.eren/work/syrupy, configfile: pyproject.toml
plugins: syrupy-4.0.0, xdist-3.1.0, benchmark-4.0.0
collected 1 item                                                                                                                                   

tests/syrupy/extensions/image/test_dot_in_extension.py .                                                                                     [100%]

------------------------------------------------------------- snapshot report summary --------------------------------------------------------------
1 snapshot passed. 1 unused snapshot deleted.

Deleted test_dot_in_file_extension.png (tests/syrupy/extensions/image/__snapshots__/test_dot_in_extension/test_dot_in_file_extension.png.zip)
================================================================ 1 passed in 0.01s =================================================================
```

The unexpected part is here: 
1. Reporting says `1 snapshot passed. 1 unused snapshot deleted.`: There wasn't an unused snapshot and it wasn't deleted
2. If I run the `--snapshot--update` again, now it deletes the snapshot file, which it shoudn't.

**To reproduce**

I've modified one of the existing tests to reproduce:
```python
# tests/syrupy/extensions/image/test_dot_in_extension.py
import base64

import pytest

from syrupy.extensions.single_file import SingleFileSnapshotExtension


class DotInFileExtension(SingleFileSnapshotExtension):
    _file_extension = "png.zip"


actual_png = base64.b64decode(
    b"iVBORw0KGgoAAAANSUhEUgAAADIAAAAyBAMAAADsEZWCAAAAG1BMVEXMzMy"
    b"Wlpaqqqq3t7exsbGcnJy+vr6jo6PFxcUFpPI/AAAACXBIWXMAAA7EAAAOxA"
    b"GVKw4bAAAAQUlEQVQ4jWNgGAWjgP6ASdncAEaiAhaGiACmFhCJLsMaIiDAE"
    b"QEi0WXYEiMCOCJAJIY9KuYGTC0gknpuHwXDGwAA5fsIZw0iYWYAAAAASUVO"
    b"RK5CYII="
)


@pytest.fixture
def snapshot_dot_in_file_extension(snapshot):
    return snapshot.use_extension(DotInFileExtension)


def test_dot_in_file_extension(snapshot_dot_in_file_extension):
    assert actual_png == snapshot_dot_in_file_extension

```

Run `pytest tests/syrupy/extensions/image/test_dot_in_extension.py --snapshot-update` twice to observe the unexpected behavior.

**Expected behavior**
1. Correct reporting as in : `1 snapshot generated.`
2. and not deleting the generated snapshot in the second update run.

**Environment (please complete the following information):**

I've tested in the main branch


Discussion:
noahnu: Ignore the benchmark failure, it's a permissions issue. I'll try take a look at this PR in the next couple days. Rather than loop through stems, I feel like there should be some sort of "basename without user supplied extension" function in the python stdlib.
tolgaeren: > "basename without user supplied extension"

I don't like the loop either. I looked for this but couldn't find it😀 if I can find some time tomorrow, I'll check the stem implementation and get some inspiration from that 😅

Patch:
diff --git a/src/syrupy/extensions/single_file.py b/src/syrupy/extensions/single_file.py
index af53ea4..8e1a7c5 100644
--- a/src/syrupy/extensions/single_file.py
+++ b/src/syrupy/extensions/single_file.py
@@ -80,8 +80,11 @@ class SingleFileSnapshotExtension(AbstractSyrupyExtension):
     def _read_snapshot_collection(
         self, *, snapshot_location: str
     ) -> "SnapshotCollection":
+        file_ext_len = len(self._file_extension) + 1 if self._file_extension else 0
+        filename_wo_ext = snapshot_location[:-file_ext_len]
+
         snapshot_collection = SnapshotCollection(location=snapshot_location)
-        snapshot_collection.add(Snapshot(name=Path(snapshot_location).stem))
+        snapshot_collection.add(Snapshot(name=Path(filename_wo_ext).stem))
         return snapshot_collection
 
     def _read_snapshot_data_from_location(


Test patch:
diff --git a/tests/integration/test_single_file_multiple_extensions.py b/tests/integration/test_single_file_multiple_extensions.py
new file mode 100644
index 0000000..b93f287
--- /dev/null
+++ b/tests/integration/test_single_file_multiple_extensions.py
@@ -0,0 +1,40 @@
+from pathlib import Path
+
+
+def test_multiple_file_extensions(testdir):
+    file_extension = "ext2.ext1"
+
+    testcase = f"""
+    import pytest
+    from syrupy.extensions.single_file import SingleFileSnapshotExtension
+
+    class DotInFileExtension(SingleFileSnapshotExtension):
+        _file_extension = "{file_extension}"
+
+    @pytest.fixture
+    def snapshot(snapshot):
+        return snapshot.use_extension(DotInFileExtension)
+
+    def test_dot_in_filename(snapshot):
+        assert b"expected_data" == snapshot
+    """
+
+    test_file: Path = testdir.makepyfile(test_file=testcase)
+
+    result = testdir.runpytest("-v", "--snapshot-update")
+    result.stdout.re_match_lines((r"1 snapshot generated\."))
+    assert "snapshots unused" not in result.stdout.str()
+    assert result.ret == 0
+
+    snapshot_file = (
+        Path(test_file).parent
+        / "__snapshots__"
+        / "test_file"
+        / f"test_dot_in_filename.{file_extension}"
+    )
+    assert snapshot_file.exists()
+
+    result = testdir.runpytest("-v")
+    result.stdout.re_match_lines((r"1 snapshot passed\."))
+    assert "snapshots unused" not in result.stdout.str()
+    assert result.ret == 0