7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
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
705 lines
22 KiB
Python
705 lines
22 KiB
Python
"""
|
|
Tests for advanced_search_system base classes.
|
|
|
|
Tests cover:
|
|
- Constraint and ConstraintType
|
|
- Candidate class
|
|
- Evidence and EvidenceType
|
|
- BaseFilter abstract class
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock
|
|
|
|
|
|
class TestConstraintType:
|
|
"""Tests for ConstraintType enum."""
|
|
|
|
def test_constraint_type_values(self):
|
|
"""Test all constraint type enum values exist."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
ConstraintType,
|
|
)
|
|
|
|
assert ConstraintType.PROPERTY.value == "property"
|
|
assert ConstraintType.NAME_PATTERN.value == "name_pattern"
|
|
assert ConstraintType.EVENT.value == "event"
|
|
assert ConstraintType.STATISTIC.value == "statistic"
|
|
assert ConstraintType.TEMPORAL.value == "temporal"
|
|
assert ConstraintType.LOCATION.value == "location"
|
|
assert ConstraintType.COMPARISON.value == "comparison"
|
|
assert ConstraintType.EXISTENCE.value == "existence"
|
|
|
|
def test_constraint_type_count(self):
|
|
"""Test that all constraint types are defined."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
ConstraintType,
|
|
)
|
|
|
|
assert len(ConstraintType) == 8
|
|
|
|
|
|
class TestConstraint:
|
|
"""Tests for Constraint dataclass."""
|
|
|
|
def test_constraint_creation_minimal(self):
|
|
"""Test creating constraint with minimal required fields."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test constraint",
|
|
value="test value",
|
|
)
|
|
|
|
assert constraint.id == "c1"
|
|
assert constraint.type == ConstraintType.PROPERTY
|
|
assert constraint.description == "Test constraint"
|
|
assert constraint.value == "test value"
|
|
assert constraint.weight == 1.0
|
|
assert constraint.metadata == {}
|
|
|
|
def test_constraint_creation_full(self):
|
|
"""Test creating constraint with all fields."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
metadata = {"source": "test"}
|
|
constraint = Constraint(
|
|
id="c2",
|
|
type=ConstraintType.TEMPORAL,
|
|
description="Time constraint",
|
|
value="2024",
|
|
weight=0.5,
|
|
metadata=metadata,
|
|
)
|
|
|
|
assert constraint.id == "c2"
|
|
assert constraint.weight == 0.5
|
|
assert constraint.metadata == metadata
|
|
|
|
def test_constraint_post_init_creates_metadata(self):
|
|
"""Test that __post_init__ creates empty metadata dict."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c3",
|
|
type=ConstraintType.LOCATION,
|
|
description="Location",
|
|
value="Colorado",
|
|
)
|
|
|
|
assert constraint.metadata is not None
|
|
assert isinstance(constraint.metadata, dict)
|
|
|
|
def test_constraint_to_search_terms_property(self):
|
|
"""Test to_search_terms for PROPERTY type."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test",
|
|
value="formed during ice age",
|
|
)
|
|
|
|
result = constraint.to_search_terms()
|
|
assert result == "formed during ice age"
|
|
|
|
def test_constraint_to_search_terms_name_pattern(self):
|
|
"""Test to_search_terms for NAME_PATTERN type."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.NAME_PATTERN,
|
|
description="Test",
|
|
value="body part",
|
|
)
|
|
|
|
result = constraint.to_search_terms()
|
|
assert "body part" in result
|
|
assert "name" in result
|
|
assert "trail" in result
|
|
|
|
def test_constraint_to_search_terms_event(self):
|
|
"""Test to_search_terms for EVENT type."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.EVENT,
|
|
description="Test",
|
|
value="rockslide 2020",
|
|
)
|
|
|
|
result = constraint.to_search_terms()
|
|
assert "rockslide 2020" in result
|
|
assert "accident" in result or "incident" in result
|
|
|
|
def test_constraint_to_search_terms_statistic(self):
|
|
"""Test to_search_terms for STATISTIC type."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.STATISTIC,
|
|
description="Test",
|
|
value="84.5x ratio",
|
|
)
|
|
|
|
result = constraint.to_search_terms()
|
|
assert "84.5x ratio" in result
|
|
assert "statistics" in result or "data" in result
|
|
|
|
def test_constraint_to_search_terms_other(self):
|
|
"""Test to_search_terms for other types (e.g., TEMPORAL)."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.TEMPORAL,
|
|
description="Test",
|
|
value="2024",
|
|
)
|
|
|
|
result = constraint.to_search_terms()
|
|
assert result == "2024"
|
|
|
|
def test_constraint_is_critical_name_pattern(self):
|
|
"""Test is_critical returns True for NAME_PATTERN type."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.NAME_PATTERN,
|
|
description="Test",
|
|
value="test",
|
|
weight=0.5, # Low weight but still critical
|
|
)
|
|
|
|
assert constraint.is_critical() is True
|
|
|
|
def test_constraint_is_critical_high_weight(self):
|
|
"""Test is_critical returns True for high weight constraints."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test",
|
|
value="test",
|
|
weight=0.9,
|
|
)
|
|
|
|
assert constraint.is_critical() is True
|
|
|
|
def test_constraint_is_critical_low_weight(self):
|
|
"""Test is_critical returns False for low weight non-NAME_PATTERN."""
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
|
|
constraint = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test",
|
|
value="test",
|
|
weight=0.5,
|
|
)
|
|
|
|
assert constraint.is_critical() is False
|
|
|
|
|
|
class TestEvidenceType:
|
|
"""Tests for EvidenceType enum."""
|
|
|
|
def test_evidence_type_values(self):
|
|
"""Test all evidence type enum values exist."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
EvidenceType,
|
|
)
|
|
|
|
assert EvidenceType.DIRECT_STATEMENT.value == "direct_statement"
|
|
assert EvidenceType.OFFICIAL_RECORD.value == "official_record"
|
|
assert EvidenceType.RESEARCH_FINDING.value == "research_finding"
|
|
assert EvidenceType.NEWS_REPORT.value == "news_report"
|
|
assert EvidenceType.STATISTICAL_DATA.value == "statistical_data"
|
|
assert EvidenceType.INFERENCE.value == "inference"
|
|
assert EvidenceType.CORRELATION.value == "correlation"
|
|
assert EvidenceType.SPECULATION.value == "speculation"
|
|
|
|
def test_evidence_type_base_confidence(self):
|
|
"""Test base confidence values for evidence types."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
EvidenceType,
|
|
)
|
|
|
|
assert EvidenceType.DIRECT_STATEMENT.base_confidence == 0.95
|
|
assert EvidenceType.OFFICIAL_RECORD.base_confidence == 0.90
|
|
assert EvidenceType.RESEARCH_FINDING.base_confidence == 0.85
|
|
assert EvidenceType.STATISTICAL_DATA.base_confidence == 0.85
|
|
assert EvidenceType.NEWS_REPORT.base_confidence == 0.75
|
|
assert EvidenceType.INFERENCE.base_confidence == 0.50
|
|
assert EvidenceType.CORRELATION.base_confidence == 0.30
|
|
assert EvidenceType.SPECULATION.base_confidence == 0.10
|
|
|
|
|
|
class TestEvidence:
|
|
"""Tests for Evidence dataclass."""
|
|
|
|
def test_evidence_creation_minimal(self):
|
|
"""Test creating evidence with minimal fields."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
evidence = Evidence(
|
|
claim="Test claim",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="https://example.com",
|
|
)
|
|
|
|
assert evidence.claim == "Test claim"
|
|
assert evidence.type == EvidenceType.NEWS_REPORT
|
|
assert evidence.source == "https://example.com"
|
|
# Post-init should set confidence based on type
|
|
assert evidence.confidence == 0.75
|
|
|
|
def test_evidence_creation_with_confidence(self):
|
|
"""Test creating evidence with explicit confidence."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
evidence = Evidence(
|
|
claim="Test claim",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="https://example.com",
|
|
confidence=0.9,
|
|
)
|
|
|
|
# Should keep provided confidence, not override
|
|
assert evidence.confidence == 0.9
|
|
|
|
def test_evidence_creation_full(self):
|
|
"""Test creating evidence with all fields."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
evidence = Evidence(
|
|
claim="Test claim",
|
|
type=EvidenceType.OFFICIAL_RECORD,
|
|
source="https://official.gov",
|
|
confidence=0.95,
|
|
reasoning="Found in official database",
|
|
raw_text="The official record states...",
|
|
metadata={"page": 1},
|
|
)
|
|
|
|
assert evidence.claim == "Test claim"
|
|
assert evidence.reasoning == "Found in official database"
|
|
assert evidence.raw_text == "The official record states..."
|
|
assert evidence.metadata == {"page": 1}
|
|
|
|
def test_evidence_timestamp_auto_generated(self):
|
|
"""Test that timestamp is automatically generated."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
evidence = Evidence(
|
|
claim="Test",
|
|
type=EvidenceType.INFERENCE,
|
|
source="test",
|
|
)
|
|
|
|
assert evidence.timestamp is not None
|
|
assert len(evidence.timestamp) > 0
|
|
|
|
def test_evidence_post_init_sets_confidence(self):
|
|
"""Test __post_init__ sets confidence based on type when 0."""
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
evidence = Evidence(
|
|
claim="Test",
|
|
type=EvidenceType.DIRECT_STATEMENT,
|
|
source="test",
|
|
confidence=0.0, # Will be replaced
|
|
)
|
|
|
|
assert evidence.confidence == 0.95
|
|
|
|
|
|
class TestCandidate:
|
|
"""Tests for Candidate dataclass."""
|
|
|
|
def test_candidate_creation_minimal(self):
|
|
"""Test creating candidate with minimal fields."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
|
|
candidate = Candidate(name="Test Candidate")
|
|
|
|
assert candidate.name == "Test Candidate"
|
|
assert candidate.evidence == {}
|
|
assert candidate.score == 0.0
|
|
assert candidate.metadata == {}
|
|
|
|
def test_candidate_add_evidence(self):
|
|
"""Test adding evidence to a candidate."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
evidence = Evidence(
|
|
claim="Test claim",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="https://example.com",
|
|
)
|
|
|
|
candidate.add_evidence("constraint_1", evidence)
|
|
|
|
assert "constraint_1" in candidate.evidence
|
|
assert candidate.evidence["constraint_1"] == evidence
|
|
|
|
def test_candidate_calculate_score_empty(self):
|
|
"""Test score calculation with no constraints."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
score = candidate.calculate_score([])
|
|
|
|
assert score == 0.0
|
|
|
|
def test_candidate_calculate_score_with_evidence(self):
|
|
"""Test score calculation with evidence."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
|
|
# Create constraints
|
|
c1 = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test 1",
|
|
value="test",
|
|
weight=1.0,
|
|
)
|
|
c2 = Constraint(
|
|
id="c2",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test 2",
|
|
value="test",
|
|
weight=1.0,
|
|
)
|
|
|
|
# Add evidence with 0.8 confidence
|
|
evidence = Evidence(
|
|
claim="Test",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="test",
|
|
confidence=0.8,
|
|
)
|
|
candidate.add_evidence("c1", evidence)
|
|
|
|
score = candidate.calculate_score([c1, c2])
|
|
|
|
# Score = (0.8 * 1.0) / (1.0 + 1.0) = 0.4
|
|
assert score == 0.4
|
|
assert candidate.score == 0.4
|
|
|
|
def test_candidate_calculate_score_weighted(self):
|
|
"""Test score calculation with weighted constraints."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
|
|
# Create constraints with different weights
|
|
c1 = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Critical",
|
|
value="test",
|
|
weight=2.0,
|
|
)
|
|
c2 = Constraint(
|
|
id="c2",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Minor",
|
|
value="test",
|
|
weight=0.5,
|
|
)
|
|
|
|
# Add evidence for c1 only
|
|
evidence = Evidence(
|
|
claim="Test",
|
|
type=EvidenceType.DIRECT_STATEMENT,
|
|
source="test",
|
|
confidence=1.0,
|
|
)
|
|
candidate.add_evidence("c1", evidence)
|
|
|
|
score = candidate.calculate_score([c1, c2])
|
|
|
|
# Score = (1.0 * 2.0) / (2.0 + 0.5) = 2.0 / 2.5 = 0.8
|
|
assert score == 0.8
|
|
|
|
def test_candidate_get_unverified_constraints(self):
|
|
"""Test getting unverified constraints."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.constraints.base_constraint import (
|
|
Constraint,
|
|
ConstraintType,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
|
|
c1 = Constraint(
|
|
id="c1",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test 1",
|
|
value="test",
|
|
)
|
|
c2 = Constraint(
|
|
id="c2",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test 2",
|
|
value="test",
|
|
)
|
|
c3 = Constraint(
|
|
id="c3",
|
|
type=ConstraintType.PROPERTY,
|
|
description="Test 3",
|
|
value="test",
|
|
)
|
|
|
|
# Add evidence for c1 only
|
|
evidence = Evidence(
|
|
claim="Test",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="test",
|
|
)
|
|
candidate.add_evidence("c1", evidence)
|
|
|
|
unverified = candidate.get_unverified_constraints([c1, c2, c3])
|
|
|
|
assert len(unverified) == 2
|
|
assert c2 in unverified
|
|
assert c3 in unverified
|
|
assert c1 not in unverified
|
|
|
|
def test_candidate_get_weak_evidence(self):
|
|
"""Test getting constraints with weak evidence."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
|
|
# Add strong evidence
|
|
strong = Evidence(
|
|
claim="Strong",
|
|
type=EvidenceType.DIRECT_STATEMENT,
|
|
source="test",
|
|
confidence=0.9,
|
|
)
|
|
candidate.add_evidence("c1", strong)
|
|
|
|
# Add weak evidence
|
|
weak = Evidence(
|
|
claim="Weak",
|
|
type=EvidenceType.SPECULATION,
|
|
source="test",
|
|
confidence=0.3,
|
|
)
|
|
candidate.add_evidence("c2", weak)
|
|
|
|
weak_constraints = candidate.get_weak_evidence(threshold=0.5)
|
|
|
|
assert len(weak_constraints) == 1
|
|
assert "c2" in weak_constraints
|
|
assert "c1" not in weak_constraints
|
|
|
|
def test_candidate_get_weak_evidence_custom_threshold(self):
|
|
"""Test getting weak evidence with custom threshold."""
|
|
from local_deep_research.advanced_search_system.candidates.base_candidate import (
|
|
Candidate,
|
|
)
|
|
from local_deep_research.advanced_search_system.evidence.base_evidence import (
|
|
Evidence,
|
|
EvidenceType,
|
|
)
|
|
|
|
candidate = Candidate(name="Test")
|
|
|
|
evidence = Evidence(
|
|
claim="Medium",
|
|
type=EvidenceType.NEWS_REPORT,
|
|
source="test",
|
|
confidence=0.7,
|
|
)
|
|
candidate.add_evidence("c1", evidence)
|
|
|
|
# With default threshold of 0.5, should not be weak
|
|
weak_default = candidate.get_weak_evidence()
|
|
assert "c1" not in weak_default
|
|
|
|
# With higher threshold, should be weak
|
|
weak_high = candidate.get_weak_evidence(threshold=0.8)
|
|
assert "c1" in weak_high
|
|
|
|
|
|
class TestBaseFilter:
|
|
"""Tests for BaseFilter abstract class."""
|
|
|
|
def test_base_filter_is_abstract(self):
|
|
"""Test that BaseFilter is abstract and cannot be instantiated."""
|
|
from local_deep_research.advanced_search_system.filters.base_filter import (
|
|
BaseFilter,
|
|
)
|
|
|
|
with pytest.raises(TypeError):
|
|
BaseFilter()
|
|
|
|
def test_base_filter_with_model(self):
|
|
"""Test BaseFilter subclass with model."""
|
|
from local_deep_research.advanced_search_system.filters.base_filter import (
|
|
BaseFilter,
|
|
)
|
|
|
|
class ConcreteFilter(BaseFilter):
|
|
def filter_results(self, results, query, **kwargs):
|
|
return results
|
|
|
|
mock_model = Mock()
|
|
filter_instance = ConcreteFilter(model=mock_model)
|
|
|
|
assert filter_instance.model == mock_model
|
|
|
|
def test_base_filter_without_model(self):
|
|
"""Test BaseFilter subclass without model."""
|
|
from local_deep_research.advanced_search_system.filters.base_filter import (
|
|
BaseFilter,
|
|
)
|
|
|
|
class ConcreteFilter(BaseFilter):
|
|
def filter_results(self, results, query, **kwargs):
|
|
return results
|
|
|
|
filter_instance = ConcreteFilter()
|
|
assert filter_instance.model is None
|
|
|
|
def test_base_filter_filter_results_abstract(self):
|
|
"""Test that filter_results must be implemented."""
|
|
from local_deep_research.advanced_search_system.filters.base_filter import (
|
|
BaseFilter,
|
|
)
|
|
|
|
class IncompleteFilter(BaseFilter):
|
|
pass
|
|
|
|
with pytest.raises(TypeError):
|
|
IncompleteFilter()
|
|
|
|
def test_base_filter_concrete_implementation(self):
|
|
"""Test a concrete filter implementation."""
|
|
from local_deep_research.advanced_search_system.filters.base_filter import (
|
|
BaseFilter,
|
|
)
|
|
|
|
class RelevanceFilter(BaseFilter):
|
|
def filter_results(self, results, query, **kwargs):
|
|
threshold = kwargs.get("threshold", 0.5)
|
|
return [r for r in results if r.get("score", 0) >= threshold]
|
|
|
|
filter_instance = RelevanceFilter()
|
|
results = [
|
|
{"title": "A", "score": 0.9},
|
|
{"title": "B", "score": 0.3},
|
|
{"title": "C", "score": 0.7},
|
|
]
|
|
|
|
filtered = filter_instance.filter_results(results, "test query")
|
|
|
|
assert len(filtered) == 2
|
|
assert {"title": "A", "score": 0.9} in filtered
|
|
assert {"title": "C", "score": 0.7} in filtered
|