Skip to content

Commit

Permalink
Make the savefixture command work without a Scrapy project.
Browse files Browse the repository at this point in the history
  • Loading branch information
wRAR committed Mar 6, 2024
1 parent 29ee200 commit 191ff4a
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 2 deletions.
5 changes: 5 additions & 0 deletions scrapy_poet/commands.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import datetime
import logging
import sys
from pathlib import Path
from typing import Optional, Type

Expand Down Expand Up @@ -109,6 +110,10 @@ def run(self, args, opts):
type_name = args[0]
url = args[1]

if "" not in sys.path:

Check warning on line 113 in scrapy_poet/commands.py

View check run for this annotation

Codecov / codecov/patch

scrapy_poet/commands.py#L113

Added line #L113 was not covered by tests
# when running without a Scrapy project the current dir may not be in sys.path,
# but the user may expect modules in the current dir to be available
sys.path.insert(0, "")

Check warning on line 116 in scrapy_poet/commands.py

View check run for this annotation

Codecov / codecov/patch

scrapy_poet/commands.py#L116

Added line #L116 was not covered by tests
cls = load_object(type_name)
if not issubclass(cls, ItemPage):
raise UsageError(f"Error: {type_name} is not a descendant of ItemPage")
Expand Down
43 changes: 41 additions & 2 deletions tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
pytest_plugins = ["pytester"]


def call_scrapy_command(cwd: str, *args: str) -> None:
def call_scrapy_command(cwd: str, *args: str, run_module: bool = True) -> None:
with tempfile.TemporaryFile() as out:
args = (sys.executable, "-m", "scrapy.cmdline") + args
if run_module:
args = (sys.executable, "-m", "scrapy.cmdline") + args
else:
args = ("scrapy",) + args
status = subprocess.call(args, stdout=out, stderr=out, cwd=cwd)
out.seek(0)
assert status == 0, out.read().decode()
Expand Down Expand Up @@ -328,3 +331,39 @@ async def to_item(self):
os.chdir(cwd)
result = pytester.runpytest_subprocess()
result.assert_outcomes(passed=4)


def test_savefixture_without_project(pytester) -> None:
cwd = Path(pytester.path)
type_name = "po.BTSBookPage"
(cwd / "po.py").write_text(
"""
from web_poet import WebPage
class BTSBookPage(WebPage):
async def to_item(self):
return {
'url': self.url,
'name': self.css("h1.name::text").get(),
}
"""
)
with MockServer(CustomResource, pythonpath=_get_pythonpath()) as server:
call_scrapy_command(
str(cwd),
"savefixture",
type_name,
f"{server.root_url}",
run_module=False, # python -m adds '' to sys.path, making the test always pass
)
fixtures_dir = cwd / "fixtures"
fixture_dir = fixtures_dir / type_name / "test-1"
fixture = Fixture(fixture_dir)
assert fixture.is_valid()
assert fixture.meta_path.exists()
item = json.loads(fixture.output_path.read_bytes())
assert item["name"] == "Chocolate"
result = pytester.runpytest_subprocess()
result.assert_outcomes(passed=4)

0 comments on commit 191ff4a

Please sign in to comment.