Repository: tophat/syrupy

Issue:
Unused snapshots when running on filename (test_a.py) that's the prefix of another (test_abc.py)
**Describe the bug**

I have a project that has filenames where the non-`.py` part happens to be a prefix of another (e.g. `test_a.py` vs. `test_abc.py`). When running `test_a.py` in isolation, syrupy picks up the snapshots from `test_abc.py` and either warns/errors about them or deletes them (depending on if `--snapshot-update`) is specified.

(Thanks for syrupy!)

**To reproduce**

```python
# test_a.py
def test_foo(snapshot): assert snapshot == "a"
```
```python
# test_abc.py
def test_bar(snapshot): assert snapshot == "abc"
```
```
# requirements.txt
attrs==21.4.0
colored==1.4.3
iniconfig==1.1.1
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.8
pytest==7.1.1
syrupy==1.7.4
tomli==2.0.1
```

With the above code, if I run `pytest test_a.py`, the snapshot from `test_abc.py` is flagged as unused:

```
================================= test session starts =================================
platform darwin -- Python 3.9.10, pytest-7.1.1, pluggy-1.0.0
rootdir: .../syrupy-file-prefix
plugins: syrupy-1.7.4
collected 1 item                                                                      

test_a.py .                                                                     [100%]

------------------------------- snapshot report summary -------------------------------
1 snapshot passed. 1 snapshot unused.

Unused test_bar (__snapshots__/test_abc.ambr)
Re-run pytest with --snapshot-update to delete unused snapshots.
================================== 1 passed in 0.01s ==================================
```

Fully packaged:

```shell
# set up virtualenv/deps/files
python --version  # Python 3.9.10
python -m venv venv
. venv/bin/activate
pip install attrs==21.4.0 colored==1.4.3 iniconfig==1.1.1 packaging==21.3 pluggy==1.0.0 py==1.11.0 pyparsing==3.0.8 pytest==7.1.1 syrupy==1.7.4 tomli==2.0.1

echo 'def test_foo(snapshot): assert snapshot == "a"' > test_a.py
echo 'def test_bar(snapshot): assert snapshot == "abc"' > test_abc.py

# create snapshots
pytest --snapshot-update  # 2 snapshots generated.
pytest  # 2 snapshots passed.

# running test_abc.py: all okay
pytest test_abc.py --snapshot-details  # 1 snapshot passed.

# running test_a.py: unused snapshots (BUG)
pytest test_a.py --snapshot-details  # Unused test_bar (__snapshots__/test_abc.ambr)
pytest test_a.py --snapshot-details --snapshot-update  # Deleted test_bar (__snapshots__/test_abc.ambr)
```

**Expected behavior**

When running pytest against a single/subset of files, snapshots from other files shouldn't be considered unused.

**Screenshots**

<!-- If applicable, add screenshots to help explain your problem. -->

**Environment (please complete the following information):**

- OS: macOS 12.3
- Syrupy Version: 1.7.4
- Python Version: 3.9.10

**Additional context**

N/A

Discussion:

Patch:
diff --git a/src/syrupy/location.py b/src/syrupy/location.py
index 31207e7..ca4aa26 100644
--- a/src/syrupy/location.py
+++ b/src/syrupy/location.py
@@ -114,4 +114,7 @@ class PyTestLocation:
         return self.__parse(self.snapshot_name) == self.__parse(snapshot_name)
 
     def matches_snapshot_location(self, snapshot_location: str) -> bool:
-        return self.filename in snapshot_location
+        loc = Path(snapshot_location)
+        # "test_file" should match_"test_file.ext" or "test_file/whatever.ext", but not
+        # "test_file_suffix.ext"
+        return self.filename == loc.stem or self.filename == loc.parent.name


Test patch:
diff --git a/tests/integration/test_snapshot_similar_names_default.py b/tests/integration/test_snapshot_similar_names_default.py
index abc06a6..5ba1e18 100644
--- a/tests/integration/test_snapshot_similar_names_default.py
+++ b/tests/integration/test_snapshot_similar_names_default.py
@@ -16,29 +16,37 @@ def testcases():
                 assert snapshot == 'b'
             """
         ),
+        "a_suffix": (
+            """
+            def test_a_suffix(snapshot):
+                assert snapshot == 'a_suffix'
+            """
+        ),
     }
 
 
 @pytest.fixture
 def run_testcases(testdir, testcases):
     pyfile_content = "\n\n".join(testcases.values())
-    testdir.makepyfile(test_1=pyfile_content, test_2=pyfile_content)
+    testdir.makepyfile(
+        test_1=pyfile_content, test_2=pyfile_content, test_1_with_suffix=pyfile_content
+    )
     result = testdir.runpytest("-v", "--snapshot-update")
-    result.stdout.re_match_lines((r"4 snapshots generated\."))
+    result.stdout.re_match_lines((r"9 snapshots generated\."))
     return testdir, testcases
 
 
 def test_run_all(run_testcases):
     testdir, testcases = run_testcases
     result = testdir.runpytest("-v")
-    result.stdout.re_match_lines("4 snapshots passed")
+    result.stdout.re_match_lines("9 snapshots passed")
     assert result.ret == 0
 
 
 def test_run_single_file(run_testcases):
     testdir, testcases = run_testcases
     result = testdir.runpytest("-v", "test_1.py")
-    result.stdout.re_match_lines("2 snapshots passed")
+    result.stdout.re_match_lines("3 snapshots passed")
     assert result.ret == 0
 
 
@@ -54,7 +62,7 @@ def test_run_all_but_one(run_testcases):
     result = testdir.runpytest(
         "-v", "--snapshot-details", "test_1.py", "test_2.py::test_a"
     )
-    result.stdout.re_match_lines("3 snapshots passed")
+    result.stdout.re_match_lines("4 snapshots passed")
     assert result.ret == 0
 
 
diff --git a/tests/integration/test_snapshot_similar_names_file_extension.py b/tests/integration/test_snapshot_similar_names_file_extension.py
index 19d1131..458d407 100644
--- a/tests/integration/test_snapshot_similar_names_file_extension.py
+++ b/tests/integration/test_snapshot_similar_names_file_extension.py
@@ -16,20 +16,28 @@ def testcases():
                 assert snapshot == b"b"
             """
         ),
+        "a_suffix": (
+            """
+            def test_a_suffix(snapshot):
+                assert snapshot == b"a_suffix"
+            """
+        ),
     }
 
 
 @pytest.fixture
 def run_testcases(testdir, testcases):
     pyfile_content = "\n\n".join(testcases.values())
-    testdir.makepyfile(test_1=pyfile_content, test_2=pyfile_content)
+    testdir.makepyfile(
+        test_1=pyfile_content, test_2=pyfile_content, test_1_suffix=pyfile_content
+    )
     result = testdir.runpytest(
         "-v",
         "--snapshot-update",
         "--snapshot-default-extension",
         "syrupy.extensions.single_file.SingleFileSnapshotExtension",
     )
-    result.stdout.re_match_lines((r"4 snapshots generated\."))
+    result.stdout.re_match_lines((r"9 snapshots generated\."))
     return testdir, testcases
 
 
@@ -40,7 +48,7 @@ def test_run_all(run_testcases):
         "--snapshot-default-extension",
         "syrupy.extensions.single_file.SingleFileSnapshotExtension",
     )
-    result.stdout.re_match_lines("4 snapshots passed")
+    result.stdout.re_match_lines("9 snapshots passed")
     assert result.ret == 0
 
 
@@ -52,7 +60,7 @@ def test_run_single_file(run_testcases):
         "syrupy.extensions.single_file.SingleFileSnapshotExtension",
         "test_1.py",
     )
-    result.stdout.re_match_lines("2 snapshots passed")
+    result.stdout.re_match_lines("3 snapshots passed")
     assert result.ret == 0
 
 
@@ -78,7 +86,7 @@ def test_run_all_but_one(run_testcases):
         "test_1.py",
         "test_2.py::test_a",
     )
-    result.stdout.re_match_lines("3 snapshots passed")
+    result.stdout.re_match_lines("4 snapshots passed")
     assert result.ret == 0
 
 
diff --git a/tests/syrupy/test_location.py b/tests/syrupy/test_location.py
index 7162559..6da7f9a 100644
--- a/tests/syrupy/test_location.py
+++ b/tests/syrupy/test_location.py
@@ -67,7 +67,15 @@ def test_location_properties(
             "/tests/module/test_file.py::TestClass::method_name",
             "method_name",
             ("test_file.snap", "__snapshots__/test_file", "test_file/1.snap"),
-            ("test.snap", "__others__/test/file.snap"),
+            (
+                "test.snap",
+                "__others__/test/file.snap",
+                "test_file_extra.snap",
+                "__snapshots__/test_file_extra",
+                "test_file_extra/1.snap",
+                "test_file/extra/1.snap",
+                "__snapshots__/test_file/extra/even/more/1.snap",
+            ),
             (
                 "TestClass.method_name",
                 "TestClass.method_name[1]",
@@ -79,7 +87,15 @@ def test_location_properties(
             "/tests/module/test_file.py::TestClass::method_name[1]",
             "method_name",
             ("test_file.snap", "__snapshots__/test_file", "test_file/1.snap"),
-            ("test.snap", "__others__/test/file.snap"),
+            (
+                "test.snap",
+                "__others__/test/file.snap",
+                "test_file_extra.snap",
+                "__snapshots__/test_file_extra",
+                "test_file_extra/1.snap",
+                "test_file/extra/1.snap",
+                "__snapshots__/test_file/extra/even/more/1.snap",
+            ),
             (
                 "TestClass.method_name",
                 "TestClass.method_name[1]",