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

527 lines
16 KiB
Python

"""
Tests for advanced_search_system/constraints/constraint_analyzer.py
Tests cover:
- ConstraintAnalyzer initialization
- extract_constraints method
- _parse_constraint_type method
- _parse_weight method
"""
from unittest.mock import Mock
class TestConstraintAnalyzerInit:
"""Tests for ConstraintAnalyzer initialization."""
def test_stores_model(self):
"""Test that model is stored."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
analyzer = ConstraintAnalyzer(mock_model)
assert analyzer.model is mock_model
class TestParseConstraintType:
"""Tests for ConstraintAnalyzer._parse_constraint_type method."""
def test_parses_property(self):
"""Test parsing property type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("property")
assert result == ConstraintType.PROPERTY
def test_parses_name_pattern(self):
"""Test parsing name_pattern type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("name_pattern")
assert result == ConstraintType.NAME_PATTERN
def test_parses_event(self):
"""Test parsing event type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("event")
assert result == ConstraintType.EVENT
def test_parses_statistic(self):
"""Test parsing statistic type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("statistic")
assert result == ConstraintType.STATISTIC
def test_parses_temporal(self):
"""Test parsing temporal type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("temporal")
assert result == ConstraintType.TEMPORAL
def test_parses_location(self):
"""Test parsing location type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("location")
assert result == ConstraintType.LOCATION
def test_parses_comparison(self):
"""Test parsing comparison type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("comparison")
assert result == ConstraintType.COMPARISON
def test_parses_existence(self):
"""Test parsing existence type."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("existence")
assert result == ConstraintType.EXISTENCE
def test_case_insensitive(self):
"""Test that parsing is case-insensitive."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
assert (
analyzer._parse_constraint_type("PROPERTY")
== ConstraintType.PROPERTY
)
assert (
analyzer._parse_constraint_type("Property")
== ConstraintType.PROPERTY
)
assert (
analyzer._parse_constraint_type("TEMPORAL")
== ConstraintType.TEMPORAL
)
def test_unknown_type_defaults_to_property(self):
"""Test that unknown type defaults to PROPERTY."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_constraint_type("unknown_type")
assert result == ConstraintType.PROPERTY
class TestParseWeight:
"""Tests for ConstraintAnalyzer._parse_weight method."""
def test_parses_int(self):
"""Test parsing integer weight."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight(1)
assert result == 1.0
def test_parses_float(self):
"""Test parsing float weight."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight(0.75)
assert result == 0.75
def test_parses_numeric_string(self):
"""Test parsing numeric string weight."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight("0.8")
assert result == 0.8
def test_parses_string_with_text_annotation(self):
"""Test parsing string with text annotation."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight("0.9 (high importance)")
assert result == 0.9
def test_extracts_first_number_from_string(self):
"""Test extracting first number from string."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight("Weight: 0.7 out of 1.0")
assert result == 0.7
def test_invalid_string_defaults_to_one(self):
"""Test that invalid string defaults to 1.0."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight("no numbers here")
assert result == 1.0
def test_empty_string_defaults_to_one(self):
"""Test that empty string defaults to 1.0."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
analyzer = ConstraintAnalyzer(Mock())
result = analyzer._parse_weight("")
assert result == 1.0
class TestExtractConstraints:
"""Tests for ConstraintAnalyzer.extract_constraints method."""
def test_extracts_single_constraint(self):
"""Test extracting a single constraint."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: The person is an actor
Value: must be an actor
Weight: 0.8
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Who is the actor?")
assert len(constraints) == 1
assert constraints[0].description == "The person is an actor"
assert constraints[0].value == "must be an actor"
assert constraints[0].weight == 0.8
def test_extracts_multiple_constraints(self):
"""Test extracting multiple constraints."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: First constraint
Value: first value
Weight: 0.9
CONSTRAINT_2:
Type: temporal
Description: Second constraint
Value: second value
Weight: 0.7
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test query")
assert len(constraints) == 2
assert constraints[0].description == "First constraint"
assert constraints[1].description == "Second constraint"
def test_generates_unique_ids(self):
"""Test that constraints get unique IDs."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: First
Value: first
Weight: 1.0
CONSTRAINT_2:
Type: property
Description: Second
Value: second
Weight: 1.0
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert constraints[0].id == "c1"
assert constraints[1].id == "c2"
def test_handles_missing_weight(self):
"""Test handling constraint without weight."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: No weight specified
Value: some value
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert len(constraints) == 1
assert constraints[0].weight == 1.0 # Default
def test_skips_incomplete_constraints(self):
"""Test that incomplete constraints are skipped."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: Missing value
CONSTRAINT_2:
Type: property
Description: Complete constraint
Value: has value
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
# Only the complete constraint should be included
assert len(constraints) == 1
assert constraints[0].description == "Complete constraint"
def test_handles_think_tags_in_response(self):
"""Test that think tags are removed from response."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""<think>Let me analyze this query...</think>
CONSTRAINT_1:
Type: property
Description: Test constraint
Value: test value
Weight: 0.5
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert len(constraints) == 1
assert constraints[0].description == "Test constraint"
def test_handles_empty_response(self):
"""Test handling empty model response."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(content="")
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert constraints == []
def test_parses_constraint_type_correctly(self):
"""Test that constraint types are parsed correctly."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
from local_deep_research.advanced_search_system.constraints.base_constraint import (
ConstraintType,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: temporal
Description: Time constraint
Value: in 2024
Weight: 0.8
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert constraints[0].type == ConstraintType.TEMPORAL
def test_handles_extra_whitespace(self):
"""Test handling of extra whitespace in response."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: Test with spaces
Value: value with spaces
Weight: 0.7
"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert len(constraints) == 1
assert constraints[0].description == "Test with spaces"
def test_processes_last_constraint(self):
"""Test that the last constraint is processed (not forgotten)."""
from local_deep_research.advanced_search_system.constraints.constraint_analyzer import (
ConstraintAnalyzer,
)
mock_model = Mock()
# No trailing CONSTRAINT_ marker, so last one must be processed
mock_model.invoke.return_value = Mock(
content="""
CONSTRAINT_1:
Type: property
Description: First constraint
Value: first
CONSTRAINT_2:
Type: property
Description: Last constraint
Value: last"""
)
analyzer = ConstraintAnalyzer(mock_model)
constraints = analyzer.extract_constraints("Test")
assert len(constraints) == 2
assert constraints[1].description == "Last constraint"