Skip to content

Commit

Permalink
fix: correctly use pytest invocation arguments (#507)
Browse files Browse the repository at this point in the history
  • Loading branch information
iamogbz committed Jun 1, 2021
1 parent 260a396 commit 8b511e5
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 63 deletions.
13 changes: 3 additions & 10 deletions src/syrupy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,10 @@ def pytest_sessionstart(session: Any) -> None:
Initialize snapshot session before tests are collected and ran.
https://docs.pytest.org/en/latest/reference.html#_pytest.hookspec.pytest_sessionstart
"""
config = session.config
config._syrupy = SnapshotSession(
warn_unused_snapshots=config.option.warn_unused_snapshots,
update_snapshots=config.option.update_snapshots,
include_snapshot_details=config.option.include_snapshot_details,
base_dir=config.rootdir,
invocation_args=config.invocation_params.args,
)
session.config._syrupy = SnapshotSession(pytest_session=session)
global _syrupy
_syrupy = config._syrupy
config._syrupy.start()
_syrupy = session.config._syrupy
session.config._syrupy.start()


def pytest_collection_modifyitems(
Expand Down
72 changes: 33 additions & 39 deletions src/syrupy/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
FrozenSet,
Iterator,
List,
Optional,
Set,
Tuple,
)

import attr
Expand All @@ -35,6 +33,8 @@
)

if TYPE_CHECKING:
import argparse

import pytest

from .assertion import SnapshotAssertion
Expand All @@ -51,23 +51,32 @@ class SnapshotReport:
base_dir: str = attr.ib()
collected_items: Set["pytest.Item"] = attr.ib()
selected_items: Dict[str, bool] = attr.ib()
update_snapshots: bool = attr.ib()
warn_unused_snapshots: bool = attr.ib()
include_snapshot_details: bool = attr.ib()
options: "argparse.Namespace" = attr.ib()
assertions: List["SnapshotAssertion"] = attr.ib()
discovered: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
created: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
failed: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
matched: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
updated: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
used: "SnapshotFossils" = attr.ib(factory=SnapshotFossils)
_invocation_args: Tuple[str, ...] = attr.ib(factory=tuple)
_provided_test_paths: Dict[str, List[str]] = attr.ib(factory=dict)
_keyword_expressions: Set["Expression"] = attr.ib(factory=set)
_collected_items_by_nodeid: Dict[str, "pytest.Item"] = attr.ib(
factory=dict, init=False
)

@property
def update_snapshots(self) -> bool:
return bool(self.options.update_snapshots)

@property
def warn_unused_snapshots(self) -> bool:
return bool(self.options.warn_unused_snapshots)

@property
def include_snapshot_details(self) -> bool:
return bool(self.options.include_snapshot_details)

def __attrs_post_init__(self) -> None:
self.__parse_invocation_args()
self._collected_items_by_nodeid = {
Expand Down Expand Up @@ -106,39 +115,24 @@ def __parse_invocation_args(self) -> None:
would result in `"tests/test_file.py"` being stored as the location in a
dictionary with `["TestClass", "test_method"]` being the test node path
"""
arg_groups: List[Tuple[Optional[str], str]] = []
path_as_package = False
maybe_opt_arg = None
for arg in self._invocation_args:
if arg.strip() == "--pyargs":
path_as_package = True
elif arg.startswith("-"):
if "=" in arg:
arg0, arg1 = arg.split("=")
arg_groups.append((arg0.strip(), arg1.strip()))
elif maybe_opt_arg is None:
maybe_opt_arg = arg
continue # do not reset maybe_opt_arg
else:
arg_groups.append((maybe_opt_arg, arg.strip()))

maybe_opt_arg = None

for maybe_opt_arg, arg_value in arg_groups:
if maybe_opt_arg == "-k": # or maybe_opt_arg == "-m":
self._keyword_expressions.add(Expression.compose(arg_value))
elif maybe_opt_arg is None:
parts = arg_value.split(PYTEST_NODE_SEP)
package_or_filepath = parts[0].strip()
filepath = Path(
importlib.import_module(package_or_filepath).__file__
if path_as_package
else package_or_filepath
)
filepath_abs = str(
filepath if filepath.is_absolute() else filepath.absolute()
)
self._provided_test_paths[filepath_abs] = parts[1:]

if self.options.keyword:
self._keyword_expressions.add(Expression.compose(self.options.keyword))
for file_or_dir in self.options.file_or_dir:
parts = file_or_dir.split(PYTEST_NODE_SEP)
package_or_filepath = parts[0].strip()
filepath = Path(package_or_filepath)
if self.options.pyargs:
try:
filepath = Path(
importlib.import_module(package_or_filepath).__file__
)
except Exception:
pass
filepath_abs = str(
filepath if filepath.is_absolute() else filepath.absolute()
)
self._provided_test_paths[filepath_abs] = parts[1:]

@property
def num_created(self) -> int:
Expand Down
25 changes: 14 additions & 11 deletions src/syrupy/session.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
from pathlib import Path
from typing import (
TYPE_CHECKING,
Any,
Dict,
Iterable,
List,
Optional,
Set,
Tuple,
)

import attr
Expand All @@ -23,11 +23,9 @@

@attr.s
class SnapshotSession:
base_dir: str = attr.ib()
update_snapshots: bool = attr.ib()
warn_unused_snapshots: bool = attr.ib()
include_snapshot_details: bool = attr.ib()
_invocation_args: Tuple[str, ...] = attr.ib(factory=tuple)
# pytest.Session
_pytest_session: Any = attr.ib()
# Snapshot report generated on finish
report: Optional["SnapshotReport"] = attr.ib(default=None)
# All the collected test items
_collected_items: Set["pytest.Item"] = attr.ib(factory=set)
Expand All @@ -36,6 +34,14 @@ class SnapshotSession:
_assertions: List["SnapshotAssertion"] = attr.ib(factory=list)
_extensions: Dict[str, "AbstractSyrupyExtension"] = attr.ib(factory=dict)

@property
def update_snapshots(self) -> bool:
return bool(self._pytest_session.config.option.update_snapshots)

@property
def warn_unused_snapshots(self) -> bool:
return bool(self._pytest_session.config.option.warn_unused_snapshots)

def collect_items(self, items: List["pytest.Item"]) -> None:
self._collected_items.update(self.filter_valid_items(items))

Expand All @@ -56,14 +62,11 @@ def ran_item(self, nodeid: str) -> None:
def finish(self) -> int:
exitstatus = 0
self.report = SnapshotReport(
base_dir=self.base_dir,
base_dir=self._pytest_session.config.rootdir,
collected_items=self._collected_items,
selected_items=self._selected_items,
assertions=self._assertions,
update_snapshots=self.update_snapshots,
warn_unused_snapshots=self.warn_unused_snapshots,
include_snapshot_details=self.include_snapshot_details,
invocation_args=self._invocation_args,
options=self._pytest_session.config.option,
)
if self.report.num_unused:
if self.update_snapshots:
Expand Down
6 changes: 3 additions & 3 deletions tests/integration/test_snapshot_option_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ def test_update_targets_only_selected_module_tests_nodes(run_testcases):
snapfile_empty = Path("__snapshots__", "empty_snapfile.ambr")
testdir.makefile(".ambr", **{str(snapfile_empty): ""})
testfile = Path(testdir.tmpdir, "test_used.py")
result = testdir.runpytest(f"{testfile}::test_used", "-v", "--snapshot-update")
result = testdir.runpytest("-v", f"{testfile}::test_used", "--snapshot-update")
result.stdout.re_match_lines((r"3 snapshots passed\."))
assert "unused" not in result.stdout.str()
assert "updated" not in result.stdout.str()
Expand Down Expand Up @@ -357,7 +357,7 @@ def test_used(snapshot, actual):
"""
)
)
result = testdir.runpytest("-v", "--snapshot-update", "test_used.py")
result = testdir.runpytest("-v", "test_used.py", "--snapshot-update")
result.stdout.re_match_lines(
(
r"3 snapshots passed\. 2 unused snapshots deleted\.",
Expand All @@ -381,7 +381,7 @@ def test_used(snapshot):
)
snapfile_empty = Path("__snapshots__", "empty_snapfile.ambr")
testdir.makefile(".ambr", **{str(snapfile_empty): ""})
result = testdir.runpytest("-v", "--snapshot-update", "test_used.py")
result = testdir.runpytest("-v", "test_used.py", "--snapshot-update")
result.stdout.re_match_lines(
(
r"5 unused snapshots deleted\.",
Expand Down

0 comments on commit 8b511e5

Please sign in to comment.