""" 向量搜索查询单元测试 测试向量搜索应用层的查询定义和验证逻辑。 """ import pytest from src.application.vector_search.queries import ( SearchDocumentsQuery, GetDocumentQuery, ) class TestSearchDocumentsQuery: """SearchDocumentsQuery 单元测试""" def test_create_with_valid_query_text(self): """测试使用有效查询文本创建查询""" # Act query = SearchDocumentsQuery(query_text="machine learning") # Assert assert query.query_text == "machine learning" assert query.top_k == 10 assert query.filters is None assert query.use_hybrid is True assert query.min_score is None def test_create_with_custom_top_k(self): """测试使用自定义 top_k 创建查询""" # Act query = SearchDocumentsQuery( query_text="deep learning", top_k=20 ) # Assert assert query.query_text == "deep learning" assert query.top_k == 20 def test_create_with_filters(self): """测试使用过滤条件创建查询""" # Act query = SearchDocumentsQuery( query_text="neural networks", filters={"category": "AI", "language": "en"} ) # Assert assert query.query_text == "neural networks" assert query.filters == {"category": "AI", "language": "en"} def test_create_with_use_hybrid_false(self): """测试使用 use_hybrid=False 创建查询""" # Act query = SearchDocumentsQuery( query_text="test query", use_hybrid=False ) # Assert assert query.use_hybrid is False def test_create_with_min_score(self): """测试使用最小分数阈值创建查询""" # Act query = SearchDocumentsQuery( query_text="test query", min_score=0.7 ) # Assert assert query.min_score == 0.7 def test_create_with_empty_query_text_raises_error(self): """测试使用空查询文本创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="Search query text cannot be empty"): SearchDocumentsQuery(query_text="") def test_create_with_whitespace_only_query_text_raises_error(self): """测试使用仅空白字符的查询文本创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="Search query text cannot be whitespace only"): SearchDocumentsQuery(query_text=" \n\t ") def test_create_with_non_string_query_text_raises_error(self): """测试使用非字符串查询文本创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="Search query text must be a string"): SearchDocumentsQuery(query_text=123) # type: ignore def test_create_with_zero_top_k_raises_error(self): """测试使用 top_k=0 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="top_k must be positive"): SearchDocumentsQuery( query_text="test query", top_k=0 ) def test_create_with_negative_top_k_raises_error(self): """测试使用负数 top_k 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="top_k must be positive"): SearchDocumentsQuery( query_text="test query", top_k=-5 ) def test_create_with_top_k_exceeding_limit_raises_error(self): """测试使用超过限制的 top_k 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="top_k cannot exceed 1000"): SearchDocumentsQuery( query_text="test query", top_k=1001 ) def test_create_with_non_integer_top_k_raises_error(self): """测试使用非整数 top_k 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="top_k must be an integer"): SearchDocumentsQuery( query_text="test query", top_k=10.5 # type: ignore ) def test_create_with_non_dict_filters_raises_error(self): """测试使用非字典过滤条件创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="filters must be a dictionary or None"): SearchDocumentsQuery( query_text="test query", filters="invalid" # type: ignore ) def test_create_with_non_boolean_use_hybrid_raises_error(self): """测试使用非布尔值 use_hybrid 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="use_hybrid must be a boolean"): SearchDocumentsQuery( query_text="test query", use_hybrid="yes" # type: ignore ) def test_create_with_min_score_below_zero_raises_error(self): """测试使用小于 0 的 min_score 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="min_score must be between 0.0 and 1.0"): SearchDocumentsQuery( query_text="test query", min_score=-0.1 ) def test_create_with_min_score_above_one_raises_error(self): """测试使用大于 1 的 min_score 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="min_score must be between 0.0 and 1.0"): SearchDocumentsQuery( query_text="test query", min_score=1.5 ) def test_create_with_non_numeric_min_score_raises_error(self): """测试使用非数值 min_score 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="min_score must be a number or None"): SearchDocumentsQuery( query_text="test query", min_score="0.7" # type: ignore ) def test_has_filters_returns_true_when_filters_provided(self): """测试当提供过滤条件时 has_filters 返回 True""" # Arrange query = SearchDocumentsQuery( query_text="test query", filters={"category": "AI"} ) # Act & Assert assert query.has_filters() is True def test_has_filters_returns_false_when_filters_not_provided(self): """测试当不提供过滤条件时 has_filters 返回 False""" # Arrange query = SearchDocumentsQuery(query_text="test query") # Act & Assert assert query.has_filters() is False def test_has_filters_returns_false_when_filters_empty(self): """测试当过滤条件为空字典时 has_filters 返回 False""" # Arrange query = SearchDocumentsQuery( query_text="test query", filters={} ) # Act & Assert assert query.has_filters() is False def test_has_min_score_returns_true_when_min_score_provided(self): """测试当提供最小分数时 has_min_score 返回 True""" # Arrange query = SearchDocumentsQuery( query_text="test query", min_score=0.7 ) # Act & Assert assert query.has_min_score() is True def test_has_min_score_returns_false_when_min_score_not_provided(self): """测试当不提供最小分数时 has_min_score 返回 False""" # Arrange query = SearchDocumentsQuery(query_text="test query") # Act & Assert assert query.has_min_score() is False def test_get_filter_value_returns_value_when_key_exists(self): """测试当键存在时 get_filter_value 返回值""" # Arrange query = SearchDocumentsQuery( query_text="test query", filters={"category": "AI", "language": "en"} ) # Act & Assert assert query.get_filter_value("category") == "AI" assert query.get_filter_value("language") == "en" def test_get_filter_value_returns_default_when_key_not_exists(self): """测试当键不存在时 get_filter_value 返回默认值""" # Arrange query = SearchDocumentsQuery( query_text="test query", filters={"category": "AI"} ) # Act & Assert assert query.get_filter_value("language", "unknown") == "unknown" def test_get_filter_value_returns_default_when_filters_none(self): """测试当过滤条件为 None 时 get_filter_value 返回默认值""" # Arrange query = SearchDocumentsQuery(query_text="test query") # Act & Assert assert query.get_filter_value("category", "default") == "default" class TestGetDocumentQuery: """GetDocumentQuery 单元测试""" def test_create_with_valid_document_id(self): """测试使用有效文档 ID 创建查询""" # Act query = GetDocumentQuery(document_id="doc_123") # Assert assert query.document_id == "doc_123" assert query.include_embedding is False def test_create_with_include_embedding_true(self): """测试使用 include_embedding=True 创建查询""" # Act query = GetDocumentQuery( document_id="doc_123", include_embedding=True ) # Assert assert query.document_id == "doc_123" assert query.include_embedding is True def test_create_with_empty_document_id_raises_error(self): """测试使用空文档 ID 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="Document ID cannot be empty"): GetDocumentQuery(document_id="") def test_create_with_non_string_document_id_raises_error(self): """测试使用非字符串文档 ID 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="Document ID must be a string"): GetDocumentQuery(document_id=123) # type: ignore def test_create_with_non_boolean_include_embedding_raises_error(self): """测试使用非布尔值 include_embedding 创建查询会抛出错误""" # Act & Assert with pytest.raises(ValueError, match="include_embedding must be a boolean"): GetDocumentQuery( document_id="doc_123", include_embedding="yes" # type: ignore )