"""Tests for pipeline.ai_provider_wrapper — no monkeypatching, no mocks.""" import pipeline.ai_provider_wrapper as w from tests.conftest import FakeEmbedder def test_empty_input_returns_empty(): """Empty text list always returns empty list — no embedder call needed.""" result = w.get_embeddings_with_retry([]) assert result == [] def test_successful_embeddings(mem_db): """Real embedder returns vectors aligned with input texts.""" embedder = FakeEmbedder() result = w.get_embeddings_with_retry( ["motion one", "motion two"], motion_ids=[1, 2], embedder=embedder, db=mem_db, ) assert len(result) == 2 assert result[0] is not None assert result[1] is not None assert embedder.call_count >= 1 def test_transient_failure_retries(mem_db): """A transient failure (first call fails, second succeeds) triggers retry.""" class TransientEmbedder: def __init__(self): self.call_count = 0 def __call__(self, texts, model=None, batch_size=50): self.call_count += 1 if self.call_count == 1: raise RuntimeError("Transient network error") return [[0.5] * 8 for _ in texts] embedder = TransientEmbedder() result = w.get_embeddings_with_retry( ["motion text"], motion_ids=[42], embedder=embedder, db=mem_db, retries=3, ) # After retry, should succeed assert result[0] is not None assert embedder.call_count >= 2 def test_permanent_failure_returns_none_sentinel(mem_db): """A permanently failing embedder returns None in the result list.""" always_fails = FakeEmbedder(fail_indices={0}) result = w.get_embeddings_with_retry( ["failing motion"], motion_ids=[99], embedder=always_fails, db=mem_db, retries=2, ) # Result entry is None for the failed item assert result == [None]