using Deal.Ai.Llm; namespace Deal.Ai.Tests.Ai; /// /// Unit-тесты оценки токенов /// public sealed class TokenEstimatorTests { /// /// Usage провайдера проходит без изменений, включая total ≠ сумме /// [Fact] public void Resolve_WithProviderUsage_PassesThrough() { var provider = new ProviderUsage(PromptTokens: 11, CompletionTokens: 5, TotalTokens: 16); LlmUsage usage = TokenEstimator.Resolve(provider, "system", "text"); Assert.Equal(11, usage.PromptTokens); Assert.Equal(5, usage.CompletionTokens); Assert.Equal(16, usage.TotalTokens); } /// /// Нет usage провайдера — оценка по символам /// [Fact] public void Resolve_WithoutProviderUsage_EstimatesByChars() { // prompt-текст = 8 символов → 2 токена; completion-текст = 13 символов → ceil(13/4) = 4. LlmUsage usage = TokenEstimator.Resolve(null, "12345678", """{"pass": true}"""); Assert.Equal(2, usage.PromptTokens); Assert.Equal(4, usage.CompletionTokens); Assert.Equal(6, usage.TotalTokens); } /// /// Округление вверх /// [Fact] public void Resolve_WithoutProviderUsage_RoundsUp() { LlmUsage fourChars = TokenEstimator.Resolve(null, "abcd", string.Empty); LlmUsage fiveChars = TokenEstimator.Resolve(null, "abcde", string.Empty); Assert.Equal(1, fourChars.PromptTokens); Assert.Equal(2, fiveChars.PromptTokens); } /// /// Пустые тексты дают нулевую оценку /// [Fact] public void Resolve_EmptyTexts_ReturnsZeroTokens() { LlmUsage usage = TokenEstimator.Resolve(null, string.Empty, string.Empty); Assert.Equal(0, usage.PromptTokens); Assert.Equal(0, usage.CompletionTokens); Assert.Equal(0, usage.TotalTokens); } }