Files
wehub-resource-sync 7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

273 lines
9.8 KiB
Python

"""
Edge-case tests for loader_registry module.
Focuses on:
- get_loader_for_path returning None when constructor raises
- Special loader kwargs (TSV tab delimiter, TXT autodetect, notebook outputs, Evernote)
- Optional loader flag gating (HAS_ODT/EPUB/RTF/RST/ORG/IMAGE_LOADER)
- Path handling (string conversion, uppercase extension)
"""
from pathlib import Path
from unittest.mock import MagicMock, patch
import pytest
# ---------------------------------------------------------------------------
# get_loader_for_path -- constructor raises returns None
# ---------------------------------------------------------------------------
class TestGetLoaderForPathConstructorException:
"""When the loader class constructor raises, get_loader_for_path returns None."""
def test_runtime_error_in_constructor_returns_none(self):
"""A RuntimeError during loader instantiation yields None."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
class _BoomLoader:
def __init__(self, *args, **kwargs):
raise RuntimeError("boom")
with patch.dict(
LOADER_REGISTRY,
{".txt": {"loader_class": _BoomLoader, "loader_kwargs": {}}},
):
result = get_loader_for_path("/fake/path/file.txt")
assert result is None
def test_type_error_in_constructor_returns_none(self):
"""A TypeError during loader instantiation yields None."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
class _BadSigLoader:
def __init__(self):
pass
with patch.dict(
LOADER_REGISTRY,
{".csv": {"loader_class": _BadSigLoader, "loader_kwargs": {}}},
):
result = get_loader_for_path("/fake/data.csv")
assert result is None
def test_value_error_in_constructor_returns_none(self):
"""A ValueError during loader instantiation yields None."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
class _ValErrLoader:
def __init__(self, *args, **kwargs):
raise ValueError("invalid arg")
with patch.dict(
LOADER_REGISTRY,
{".md": {"loader_class": _ValErrLoader, "loader_kwargs": {}}},
):
result = get_loader_for_path("/fake/readme.md")
assert result is None
# ---------------------------------------------------------------------------
# Special loader kwargs
# ---------------------------------------------------------------------------
class TestSpecialLoaderKwargs:
"""Verify that specific extensions carry the correct special kwargs."""
def test_tsv_has_tab_delimiter(self):
"""TSV entry uses CSVLoader with tab delimiter."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
)
entry = LOADER_REGISTRY[".tsv"]
assert entry["loader_kwargs"]["csv_args"]["delimiter"] == "\t"
def test_txt_has_autodetect_encoding(self):
"""TXT entry specifies autodetect_encoding=True."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
)
kwargs = LOADER_REGISTRY[".txt"]["loader_kwargs"]
assert kwargs["autodetect_encoding"] is True
assert kwargs["encoding"] == "utf-8"
def test_notebook_include_outputs(self):
"""Notebook entry has include_outputs=True and remove_newline=True."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
)
kwargs = LOADER_REGISTRY[".ipynb"]["loader_kwargs"]
assert kwargs["include_outputs"] is True
assert kwargs["remove_newline"] is True
def test_evernote_not_single_document(self):
"""Evernote entry has load_single_document=False."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
)
kwargs = LOADER_REGISTRY[".enex"]["loader_kwargs"]
assert kwargs["load_single_document"] is False
# ---------------------------------------------------------------------------
# Optional loader flag gating (module-level HAS_* flags)
# ---------------------------------------------------------------------------
class TestOptionalLoaderFlagGating:
"""Test that HAS_* flags control whether optional extensions are registered."""
def test_odt_absent_when_flag_false(self):
"""When HAS_ODT_LOADER is False, .odt must not be in the registry."""
import local_deep_research.document_loaders.loader_registry as mod
if not mod.HAS_ODT_LOADER:
assert ".odt" not in mod.LOADER_REGISTRY
else:
pytest.skip("HAS_ODT_LOADER is True in this environment")
def test_odt_present_when_flag_true(self):
"""When HAS_ODT_LOADER is True, .odt must be in the registry."""
import local_deep_research.document_loaders.loader_registry as mod
if mod.HAS_ODT_LOADER:
assert ".odt" in mod.LOADER_REGISTRY
assert (
mod.LOADER_REGISTRY[".odt"]["loader_class"].__name__
== "UnstructuredODTLoader"
)
else:
pytest.skip("HAS_ODT_LOADER is False in this environment")
def test_epub_gated_by_flag(self):
"""EPUB registration matches HAS_EPUB_LOADER flag."""
import local_deep_research.document_loaders.loader_registry as mod
assert (".epub" in mod.LOADER_REGISTRY) == mod.HAS_EPUB_LOADER
def test_rtf_gated_by_flag(self):
"""RTF registration matches HAS_RTF_LOADER flag."""
import local_deep_research.document_loaders.loader_registry as mod
assert (".rtf" in mod.LOADER_REGISTRY) == mod.HAS_RTF_LOADER
def test_rst_gated_by_flag(self):
"""RST registration matches HAS_RST_LOADER flag."""
import local_deep_research.document_loaders.loader_registry as mod
assert (".rst" in mod.LOADER_REGISTRY) == mod.HAS_RST_LOADER
def test_org_gated_by_flag(self):
"""Org-mode registration matches HAS_ORG_LOADER flag."""
import local_deep_research.document_loaders.loader_registry as mod
assert (".org" in mod.LOADER_REGISTRY) == mod.HAS_ORG_LOADER
def test_image_extensions_gated_by_flag(self):
"""Image extensions are present iff the loader class AND the OCR
runtime dependency (pytesseract + tesseract binary) are available."""
import local_deep_research.document_loaders.loader_registry as mod
image_exts = [
".png",
".jpg",
".jpeg",
".tiff",
".tif",
".bmp",
".heic",
]
expected = mod.HAS_IMAGE_LOADER and mod.HAS_OCR_DEP
for ext in image_exts:
assert (ext in mod.LOADER_REGISTRY) == expected, (
f"{ext} registration does not match "
f"HAS_IMAGE_LOADER={mod.HAS_IMAGE_LOADER} "
f"HAS_OCR_DEP={mod.HAS_OCR_DEP}"
)
# ---------------------------------------------------------------------------
# Path handling -- string conversion and uppercase extension
# ---------------------------------------------------------------------------
class TestPathHandling:
"""Test that get_loader_for_path handles various path forms correctly."""
def test_string_path_is_converted_to_pathlib(self):
"""A plain string path should work identically to a Path object."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
mock_loader_instance = MagicMock()
mock_class = MagicMock(return_value=mock_loader_instance)
with patch.dict(
LOADER_REGISTRY,
{
".txt": {
"loader_class": mock_class,
"loader_kwargs": {"encoding": "utf-8"},
}
},
):
result = get_loader_for_path("/some/dir/notes.txt")
assert result is mock_loader_instance
mock_class.assert_called_once_with(
"/some/dir/notes.txt", encoding="utf-8"
)
def test_uppercase_extension_resolves_correctly(self):
"""A file with .CSV extension should still resolve via .lower()."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
mock_loader_instance = MagicMock()
mock_class = MagicMock(return_value=mock_loader_instance)
with patch.dict(
LOADER_REGISTRY,
{".csv": {"loader_class": mock_class, "loader_kwargs": {}}},
):
result = get_loader_for_path("/data/REPORT.CSV")
assert result is mock_loader_instance
mock_class.assert_called_once_with("/data/REPORT.CSV")
def test_path_object_suffix_extracted(self):
"""Path object suffix is used for extension lookup, not the full name."""
from local_deep_research.document_loaders.loader_registry import (
LOADER_REGISTRY,
get_loader_for_path,
)
mock_loader_instance = MagicMock()
mock_class = MagicMock(return_value=mock_loader_instance)
with patch.dict(
LOADER_REGISTRY,
{".json": {"loader_class": mock_class, "loader_kwargs": {}}},
):
result = get_loader_for_path(Path("/tmp/config.backup.json"))
assert result is mock_loader_instance
call_args = mock_class.call_args
assert call_args[0][0].endswith("config.backup.json")