From ef14fd4b5da03abcaaf900cfe6220034ae24b96d Mon Sep 17 00:00:00 2001 From: yusyus Date: Sun, 22 Feb 2026 22:32:31 +0300 Subject: [PATCH] style: auto-format 12 files with ruff format (CI formatting check) Co-Authored-By: Claude Sonnet 4.6 --- src/skill_seekers/cli/enhance_command.py | 9 +++-- src/skill_seekers/cli/llms_txt_parser.py | 1 + src/skill_seekers/cli/unified_scraper.py | 31 +++++++++------ tests/test_analyze_command.py | 12 ++---- tests/test_enhance_command.py | 30 ++++++++++++++ tests/test_enhance_skill_local.py | 16 +++++--- tests/test_install_skill_e2e.py | 16 ++++++-- tests/test_mcp_workflow_tools.py | 4 +- tests/test_pdf_scraper.py | 4 +- tests/test_swift_detection.py | 6 ++- tests/test_unified.py | 14 +++---- tests/test_unified_scraper_orchestration.py | 44 ++++++++++++--------- 12 files changed, 124 insertions(+), 63 deletions(-) diff --git a/src/skill_seekers/cli/enhance_command.py b/src/skill_seekers/cli/enhance_command.py index d82d894..a9e29b7 100644 --- a/src/skill_seekers/cli/enhance_command.py +++ b/src/skill_seekers/cli/enhance_command.py @@ -28,6 +28,7 @@ from pathlib import Path # Helpers # --------------------------------------------------------------------------- + def _is_root() -> bool: """Return True if the current process is running as root (UID 0).""" try: @@ -39,10 +40,7 @@ def _is_root() -> bool: def _get_api_keys() -> dict[str, str | None]: """Collect API keys from environment.""" return { - "claude": ( - os.environ.get("ANTHROPIC_API_KEY") - or os.environ.get("ANTHROPIC_AUTH_TOKEN") - ), + "claude": (os.environ.get("ANTHROPIC_API_KEY") or os.environ.get("ANTHROPIC_AUTH_TOKEN")), "gemini": os.environ.get("GOOGLE_API_KEY"), "openai": os.environ.get("OPENAI_API_KEY"), } @@ -95,6 +93,7 @@ def _pick_mode(args) -> tuple[str, str | None]: # API mode runner # --------------------------------------------------------------------------- + def _run_api_mode(args, target: str) -> int: """Delegate to enhance_skill.py (platform adaptor path).""" from skill_seekers.cli.enhance_skill import main as enhance_api_main @@ -137,6 +136,7 @@ def _run_api_mode(args, target: str) -> int: # LOCAL mode runner # --------------------------------------------------------------------------- + def _run_local_mode(args) -> int: """Delegate to LocalSkillEnhancer from enhance_skill_local.py.""" from skill_seekers.cli.enhance_skill_local import LocalSkillEnhancer @@ -167,6 +167,7 @@ def _run_local_mode(args) -> int: # Main entry point # --------------------------------------------------------------------------- + def main() -> int: import argparse diff --git a/src/skill_seekers/cli/llms_txt_parser.py b/src/skill_seekers/cli/llms_txt_parser.py index 229951f..6f70b26 100644 --- a/src/skill_seekers/cli/llms_txt_parser.py +++ b/src/skill_seekers/cli/llms_txt_parser.py @@ -97,6 +97,7 @@ class LlmsTxtParser: # causes httpx to raise "Invalid IPv6 URL" when the URL is fetched. if "[" in url or "]" in url: from urllib.parse import urlparse, urlunparse + parsed = urlparse(url) # Only encode brackets in the path/query/fragment, not in the host encoded_path = parsed.path.replace("[", "%5B").replace("]", "%5D") diff --git a/src/skill_seekers/cli/unified_scraper.py b/src/skill_seekers/cli/unified_scraper.py index d8c1af3..df59b14 100644 --- a/src/skill_seekers/cli/unified_scraper.py +++ b/src/skill_seekers/cli/unified_scraper.py @@ -563,8 +563,14 @@ class UnifiedScraper: # AI enhancement settings (CLI --enhance-level overrides per-source config) cli_args = getattr(self, "_cli_args", None) - cli_enhance_level = getattr(cli_args, "enhance_level", None) if cli_args is not None else None - enhance_level = cli_enhance_level if cli_enhance_level is not None else source.get("enhance_level", 0) + cli_enhance_level = ( + getattr(cli_args, "enhance_level", None) if cli_args is not None else None + ) + enhance_level = ( + cli_enhance_level + if cli_enhance_level is not None + else source.get("enhance_level", 0) + ) # Run codebase analysis logger.info(f" Analysis depth: {analysis_depth}") @@ -991,11 +997,15 @@ class UnifiedScraper: from skill_seekers.cli.workflow_runner import run_workflows # Build effective args: use CLI args when provided, otherwise empty namespace - effective_args = args if args is not None else argparse.Namespace( - enhance_workflow=None, - enhance_stage=None, - var=None, - workflow_dry_run=False, + effective_args = ( + args + if args is not None + else argparse.Namespace( + enhance_workflow=None, + enhance_stage=None, + var=None, + workflow_dry_run=False, + ) ) # Merge JSON workflow config into effective_args (JSON appended after CLI) @@ -1008,10 +1018,9 @@ class UnifiedScraper: list(effective_args.enhance_stage or []) + json_stages ) if json_vars: - effective_args.var = ( - list(effective_args.var or []) - + [f"{k}={v}" for k, v in json_vars.items()] - ) + effective_args.var = list(effective_args.var or []) + [ + f"{k}={v}" for k, v in json_vars.items() + ] unified_context = { "name": self.config.get("name", ""), diff --git a/tests/test_analyze_command.py b/tests/test_analyze_command.py index 4a12b36..93bd739 100644 --- a/tests/test_analyze_command.py +++ b/tests/test_analyze_command.py @@ -219,23 +219,17 @@ class TestAnalyzeWorkflowFlags(unittest.TestCase): def test_var_accepted_as_list(self): """Test --var is accepted with action=append (dest is 'var').""" - args = self.parser.parse_args( - ["analyze", "--directory", ".", "--var", "focus=performance"] - ) + args = self.parser.parse_args(["analyze", "--directory", ".", "--var", "focus=performance"]) self.assertEqual(args.var, ["focus=performance"]) def test_workflow_dry_run_flag(self): """Test --workflow-dry-run sets the flag.""" - args = self.parser.parse_args( - ["analyze", "--directory", ".", "--workflow-dry-run"] - ) + args = self.parser.parse_args(["analyze", "--directory", ".", "--workflow-dry-run"]) self.assertTrue(args.workflow_dry_run) def test_api_key_stored_correctly(self): """Test --api-key is stored in args.""" - args = self.parser.parse_args( - ["analyze", "--directory", ".", "--api-key", "sk-ant-test"] - ) + args = self.parser.parse_args(["analyze", "--directory", ".", "--api-key", "sk-ant-test"]) self.assertEqual(args.api_key, "sk-ant-test") def test_dry_run_stored_correctly(self): diff --git a/tests/test_enhance_command.py b/tests/test_enhance_command.py index 44c5e1d..7e22f57 100644 --- a/tests/test_enhance_command.py +++ b/tests/test_enhance_command.py @@ -10,6 +10,7 @@ import pytest # Helpers # --------------------------------------------------------------------------- + def _make_args(**kwargs): """Build a fake Namespace with sensible defaults.""" defaults = { @@ -40,29 +41,37 @@ def _make_skill_dir(tmp_path): # _is_root # --------------------------------------------------------------------------- + class TestIsRoot: def test_returns_bool(self): from skill_seekers.cli.enhance_command import _is_root + assert isinstance(_is_root(), bool) def test_not_root_when_monkeypatched(self, monkeypatch): import os + monkeypatch.setattr(os, "getuid", lambda: 1000) from skill_seekers.cli.enhance_command import _is_root + assert _is_root() is False def test_root_when_uid_zero(self, monkeypatch): import os + monkeypatch.setattr(os, "getuid", lambda: 0) from skill_seekers.cli.enhance_command import _is_root + assert _is_root() is True def test_windows_no_getuid(self, monkeypatch): """On Windows (no os.getuid), _is_root should return False.""" import os + if hasattr(os, "getuid"): monkeypatch.delattr(os, "getuid") from skill_seekers.cli.enhance_command import _is_root + assert _is_root() is False @@ -70,6 +79,7 @@ class TestIsRoot: # _pick_mode — explicit --target flag # --------------------------------------------------------------------------- + class TestPickModeExplicitTarget: def test_target_gemini_forces_api(self, monkeypatch): monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False) @@ -77,6 +87,7 @@ class TestPickModeExplicitTarget: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + args = _make_args(target="gemini") mode, target = _pick_mode(args) assert mode == "api" @@ -86,6 +97,7 @@ class TestPickModeExplicitTarget: monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + args = _make_args(target="openai") mode, target = _pick_mode(args) assert mode == "api" @@ -95,6 +107,7 @@ class TestPickModeExplicitTarget: monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + args = _make_args(target="claude") mode, target = _pick_mode(args) assert mode == "api" @@ -105,6 +118,7 @@ class TestPickModeExplicitTarget: # _pick_mode — auto-detection from env vars # --------------------------------------------------------------------------- + class TestPickModeAutoDetect: def test_anthropic_key_selects_claude(self, monkeypatch): monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-ant-test") @@ -112,6 +126,7 @@ class TestPickModeAutoDetect: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "api" assert target == "claude" @@ -123,6 +138,7 @@ class TestPickModeAutoDetect: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "api" assert target == "gemini" @@ -134,6 +150,7 @@ class TestPickModeAutoDetect: monkeypatch.setenv("OPENAI_API_KEY", "sk-proj-test") from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "api" assert target == "openai" @@ -145,6 +162,7 @@ class TestPickModeAutoDetect: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "local" assert target is None @@ -156,6 +174,7 @@ class TestPickModeAutoDetect: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "api" assert target == "claude" @@ -165,6 +184,7 @@ class TestPickModeAutoDetect: # _pick_mode — config default_agent # --------------------------------------------------------------------------- + class TestPickModeConfigAgent: def _patch_config(self, monkeypatch, agent: str | None): """Patch get_config_manager to return a stub with get_default_agent().""" @@ -180,6 +200,7 @@ class TestPickModeConfigAgent: monkeypatch.setenv("GOOGLE_API_KEY", "AIza-test") from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "api" assert target == "gemini" @@ -193,6 +214,7 @@ class TestPickModeConfigAgent: monkeypatch.delenv("OPENAI_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + mode, target = _pick_mode(_make_args()) assert mode == "local" @@ -202,6 +224,7 @@ class TestPickModeConfigAgent: monkeypatch.delenv("ANTHROPIC_API_KEY", raising=False) from skill_seekers.cli.enhance_command import _pick_mode + args = _make_args(target="openai") mode, target = _pick_mode(args) assert mode == "api" @@ -212,6 +235,7 @@ class TestPickModeConfigAgent: # CLI argument parsing # --------------------------------------------------------------------------- + class TestEnhanceArgumentParsing: """Test that the enhance parser exposes all expected arguments.""" @@ -257,6 +281,7 @@ class TestEnhanceArgumentParsing: # main() CLI integration — dry-run + root detection # --------------------------------------------------------------------------- + class TestEnhanceCommandMain: def test_dry_run_no_ai_call(self, tmp_path): skill_dir = _make_skill_dir(tmp_path) @@ -264,6 +289,7 @@ class TestEnhanceCommandMain: sys.argv = ["enhance_command.py", str(skill_dir), "--dry-run"] try: from skill_seekers.cli.enhance_command import main + rc = main() assert rc == 0 finally: @@ -274,6 +300,7 @@ class TestEnhanceCommandMain: sys.argv = ["enhance_command.py", str(tmp_path / "nonexistent")] try: from skill_seekers.cli.enhance_command import main + rc = main() assert rc == 1 finally: @@ -293,6 +320,7 @@ class TestEnhanceCommandMain: sys.argv = ["enhance_command.py", str(skill_dir)] try: from skill_seekers.cli.enhance_command import main + rc = main() assert rc == 1 finally: @@ -316,6 +344,7 @@ class TestEnhanceCommandMain: sys.argv = ["enhance_command.py", str(skill_dir)] try: from skill_seekers.cli.enhance_command import main + rc = main() assert rc == 0 finally: @@ -326,6 +355,7 @@ class TestEnhanceCommandMain: # Config manager — get_default_agent # --------------------------------------------------------------------------- + class TestConfigManagerDefaultAgent: def test_get_default_agent_none_by_default(self, tmp_path, monkeypatch): from skill_seekers.cli.config_manager import ConfigManager diff --git a/tests/test_enhance_skill_local.py b/tests/test_enhance_skill_local.py index 4e940d3..557dd25 100644 --- a/tests/test_enhance_skill_local.py +++ b/tests/test_enhance_skill_local.py @@ -2,7 +2,11 @@ from unittest.mock import MagicMock, patch import pytest -from skill_seekers.cli.enhance_skill_local import AGENT_PRESETS, LocalSkillEnhancer, detect_terminal_app +from skill_seekers.cli.enhance_skill_local import ( + AGENT_PRESETS, + LocalSkillEnhancer, + detect_terminal_app, +) def _make_skill_dir(tmp_path): @@ -441,7 +445,9 @@ class TestRunHeadless: skill_dir = self._make_skill_with_md(tmp_path) enhancer = LocalSkillEnhancer(skill_dir, agent="claude") - with patch.object(enhancer, "_run_agent_command", return_value=(None, "Command not found: claude")): + with patch.object( + enhancer, "_run_agent_command", return_value=(None, "Command not found: claude") + ): result = enhancer._run_headless(str(tmp_path / "prompt.txt"), timeout=10) assert result is False @@ -484,10 +490,9 @@ class TestRunHeadless: def _fake_run(prompt_file, timeout, include_permissions_flag, quiet=False): # noqa: ARG001 # Simulate agent updating SKILL.md with more content import time + time.sleep(0.01) - (skill_dir / "SKILL.md").write_text( - "# Enhanced\n" + "A" * 500, encoding="utf-8" - ) + (skill_dir / "SKILL.md").write_text("# Enhanced\n" + "A" * 500, encoding="utf-8") return mock_result, None with patch.object(enhancer, "_run_agent_command", side_effect=_fake_run): @@ -564,6 +569,7 @@ class TestRunBackground: # Give background thread a moment import time + time.sleep(0.1) # Status file should exist (written by the worker) diff --git a/tests/test_install_skill_e2e.py b/tests/test_install_skill_e2e.py index c437d4c..1fe5f9f 100644 --- a/tests/test_install_skill_e2e.py +++ b/tests/test_install_skill_e2e.py @@ -103,7 +103,9 @@ class TestInstallSkillE2E: # Mock the subprocess calls for scraping and enhancement with ( patch("skill_seekers.mcp.tools.scraping_tools.scrape_docs_tool") as mock_scrape, - patch("skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming") as mock_enhance, + patch( + "skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming" + ) as mock_enhance, patch("skill_seekers.mcp.tools.packaging_tools.package_skill_tool") as mock_package, ): # Mock scrape_docs to return success @@ -166,7 +168,9 @@ class TestInstallSkillE2E: with ( patch("skill_seekers.mcp.tools.source_tools.fetch_config_tool") as mock_fetch, patch("skill_seekers.mcp.tools.scraping_tools.scrape_docs_tool") as mock_scrape, - patch("skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming") as mock_enhance, + patch( + "skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming" + ) as mock_enhance, patch("skill_seekers.mcp.tools.packaging_tools.package_skill_tool") as mock_package, patch("builtins.open", create=True) as mock_file_open, patch("os.environ.get") as mock_env, @@ -283,7 +287,9 @@ class TestInstallSkillE2E: with ( patch("skill_seekers.mcp.tools.scraping_tools.scrape_docs_tool") as mock_scrape, - patch("skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming") as mock_enhance, + patch( + "skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming" + ) as mock_enhance, ): # Mock successful scrape mock_scrape.return_value = [ @@ -483,7 +489,9 @@ class TestInstallSkillE2E_RealFiles: # Only mock enhancement and upload (let scraping run for real) with ( - patch("skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming") as mock_enhance, + patch( + "skill_seekers.mcp.tools.packaging_tools.run_subprocess_with_streaming" + ) as mock_enhance, patch("skill_seekers.mcp.tools.packaging_tools.upload_skill_tool") as mock_upload, patch("os.environ.get") as mock_env, ): diff --git a/tests/test_mcp_workflow_tools.py b/tests/test_mcp_workflow_tools.py index 6c43541..20ad80f 100644 --- a/tests/test_mcp_workflow_tools.py +++ b/tests/test_mcp_workflow_tools.py @@ -423,7 +423,9 @@ class TestDeleteWorkflowTool: assert "Error" in _text(result) assert "bundled" in _text(result) - def test_not_found_user_workflow_returns_error(self, user_dir, bundled_names_empty, monkeypatch): + def test_not_found_user_workflow_returns_error( + self, user_dir, bundled_names_empty, monkeypatch + ): monkeypatch.setattr( "skill_seekers.mcp.tools.workflow_tools._read_bundled", lambda _name: None, diff --git a/tests/test_pdf_scraper.py b/tests/test_pdf_scraper.py index 0727b59..46b1403 100644 --- a/tests/test_pdf_scraper.py +++ b/tests/test_pdf_scraper.py @@ -543,9 +543,7 @@ class TestPDFCLIArguments(unittest.TestCase): def test_enhance_workflow_accepted(self): """Test --enhance-workflow is accepted and stores a list.""" - args = self.parser.parse_args( - ["pdf", "--pdf", "test.pdf", "--enhance-workflow", "minimal"] - ) + args = self.parser.parse_args(["pdf", "--pdf", "test.pdf", "--enhance-workflow", "minimal"]) self.assertEqual(args.enhance_workflow, ["minimal"]) def test_workflow_dry_run_accepted(self): diff --git a/tests/test_swift_detection.py b/tests/test_swift_detection.py index d6eee66..aec9522 100644 --- a/tests/test_swift_detection.py +++ b/tests/test_swift_detection.py @@ -1342,7 +1342,11 @@ class TestSwiftErrorHandling: # Mock empty SWIFT_PATTERNS during import with patch.dict( "sys.modules", - {"skill_seekers.cli.swift_patterns": type("MockModule", (), {"SWIFT_PATTERNS": {}})}, + { + "skill_seekers.cli.swift_patterns": type( + "MockModule", (), {"SWIFT_PATTERNS": {}} + ) + }, ): from skill_seekers.cli.language_detector import LanguageDetector diff --git a/tests/test_unified.py b/tests/test_unified.py index b5cd4d7..16b849f 100644 --- a/tests/test_unified.py +++ b/tests/test_unified.py @@ -593,16 +593,12 @@ class TestUnifiedCLIArguments: def test_api_key_stored_correctly(self, parser): """Test --api-key KEY is stored in args.""" - args = parser.parse_args( - ["unified", "--config", "my.json", "--api-key", "sk-ant-test"] - ) + args = parser.parse_args(["unified", "--config", "my.json", "--api-key", "sk-ant-test"]) assert args.api_key == "sk-ant-test" def test_enhance_level_stored_correctly(self, parser): """Test --enhance-level 2 is stored in args.""" - args = parser.parse_args( - ["unified", "--config", "my.json", "--enhance-level", "2"] - ) + args = parser.parse_args(["unified", "--config", "my.json", "--enhance-level", "2"]) assert args.enhance_level == 2 def test_enhance_level_default_is_none(self, parser): @@ -670,6 +666,7 @@ class TestWorkflowJsonConfig: "skill_seekers.cli.workflow_runner.run_workflows", fake_run_workflows, raising=False ) import skill_seekers.cli.unified_scraper as us_module + monkeypatch.setattr(us_module, "run_workflows", fake_run_workflows, raising=False) scraper = self._make_scraper(tmp_path, {"workflows": ["security-focus", "minimal"]}) @@ -725,7 +722,10 @@ class TestWorkflowJsonConfig: json_stages = config.get("workflow_stages", []) if json_stages: effective_args.enhance_stage = list(effective_args.enhance_stage or []) + json_stages - assert effective_args.enhance_stage == ["sec:Analyze security", "cleanup:Remove boilerplate"] + assert effective_args.enhance_stage == [ + "sec:Analyze security", + "cleanup:Remove boilerplate", + ] def test_json_workflow_vars_converted_to_kv_strings(self, tmp_path): """JSON 'workflow_vars' dict is converted to 'key=value' strings.""" diff --git a/tests/test_unified_scraper_orchestration.py b/tests/test_unified_scraper_orchestration.py index 8dc22d1..e6d431f 100644 --- a/tests/test_unified_scraper_orchestration.py +++ b/tests/test_unified_scraper_orchestration.py @@ -82,10 +82,20 @@ class TestScrapeAllSourcesRouting: calls = {"documentation": 0, "github": 0, "pdf": 0, "local": 0} - monkeypatch.setattr(scraper, "_scrape_documentation", lambda _s: calls.__setitem__("documentation", calls["documentation"] + 1)) - monkeypatch.setattr(scraper, "_scrape_github", lambda _s: calls.__setitem__("github", calls["github"] + 1)) - monkeypatch.setattr(scraper, "_scrape_pdf", lambda _s: calls.__setitem__("pdf", calls["pdf"] + 1)) - monkeypatch.setattr(scraper, "_scrape_local", lambda _s: calls.__setitem__("local", calls["local"] + 1)) + monkeypatch.setattr( + scraper, + "_scrape_documentation", + lambda _s: calls.__setitem__("documentation", calls["documentation"] + 1), + ) + monkeypatch.setattr( + scraper, "_scrape_github", lambda _s: calls.__setitem__("github", calls["github"] + 1) + ) + monkeypatch.setattr( + scraper, "_scrape_pdf", lambda _s: calls.__setitem__("pdf", calls["pdf"] + 1) + ) + monkeypatch.setattr( + scraper, "_scrape_local", lambda _s: calls.__setitem__("local", calls["local"] + 1) + ) scraper.scrape_all_sources() return calls @@ -100,31 +110,23 @@ class TestScrapeAllSourcesRouting: assert calls["local"] == 0 def test_github_source_routes_to_scrape_github(self, monkeypatch): - calls = self._run_with_sources( - [{"type": "github", "repo": "user/repo"}], monkeypatch - ) + calls = self._run_with_sources([{"type": "github", "repo": "user/repo"}], monkeypatch) assert calls["github"] == 1 assert calls["documentation"] == 0 def test_pdf_source_routes_to_scrape_pdf(self, monkeypatch): - calls = self._run_with_sources( - [{"type": "pdf", "path": "/tmp/doc.pdf"}], monkeypatch - ) + calls = self._run_with_sources([{"type": "pdf", "path": "/tmp/doc.pdf"}], monkeypatch) assert calls["pdf"] == 1 assert calls["documentation"] == 0 def test_local_source_routes_to_scrape_local(self, monkeypatch): - calls = self._run_with_sources( - [{"type": "local", "path": "/tmp/project"}], monkeypatch - ) + calls = self._run_with_sources([{"type": "local", "path": "/tmp/project"}], monkeypatch) assert calls["local"] == 1 assert calls["documentation"] == 0 def test_unknown_source_type_is_skipped(self, monkeypatch): """Unknown types are logged as warnings but do not crash or call any scraper.""" - calls = self._run_with_sources( - [{"type": "unsupported_xyz"}], monkeypatch - ) + calls = self._run_with_sources([{"type": "unsupported_xyz"}], monkeypatch) assert all(v == 0 for v in calls.values()) def test_multiple_sources_each_scraper_called_once(self, monkeypatch): @@ -214,7 +216,10 @@ class TestScrapeDocumentation: with ( patch("skill_seekers.cli.unified_scraper.subprocess.run") as mock_run, - patch("skill_seekers.cli.unified_scraper.json.dump", side_effect=lambda obj, _f, **_kw: written_configs.append(obj)), + patch( + "skill_seekers.cli.unified_scraper.json.dump", + side_effect=lambda obj, _f, **_kw: written_configs.append(obj), + ), ): mock_run.return_value = MagicMock(returncode=1, stdout="", stderr="") scraper._scrape_documentation(source) @@ -234,7 +239,10 @@ class TestScrapeDocumentation: with ( patch("skill_seekers.cli.unified_scraper.subprocess.run") as mock_run, - patch("skill_seekers.cli.unified_scraper.json.dump", side_effect=lambda obj, _f, **_kw: written_configs.append(obj)), + patch( + "skill_seekers.cli.unified_scraper.json.dump", + side_effect=lambda obj, _f, **_kw: written_configs.append(obj), + ), ): mock_run.return_value = MagicMock(returncode=1, stdout="", stderr="") scraper._scrape_documentation(source)