Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

127 lines
4.7 KiB
Go

package review
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"github.com/zzet/gortex/internal/llm"
)
// TestCostFromUsage_TokenSplitAndUSD asserts the breakdown carries the
// exact token split and a USD figure computed from the price card.
func TestCostFromUsage_TokenSplitAndUSD(t *testing.T) {
usage := llm.TokenUsage{InputTokens: 1234, OutputTokens: 456, CacheReadTokens: 2000, CacheWriteTokens: 300}
price := llm.ProviderPricing{Input: 3.0, Output: 15.0} // USD per 1M tokens
cb := CostFromUsage(usage, price, 4210)
require.Equal(t, 1234, cb.InputTokens)
require.Equal(t, 456, cb.OutputTokens)
require.Equal(t, 2000, cb.CacheReadTokens)
require.Equal(t, 300, cb.CacheWriteTokens)
require.Equal(t, int64(4210), cb.ElapsedMs)
require.True(t, cb.Estimated, "a non-zero usage is a grounded estimate")
// 1234 * 3.0/1e6 + 456 * 15.0/1e6
wantUSD := (1234*3.0 + 456*15.0) / 1_000_000.0
require.InDelta(t, wantUSD, cb.USD, 1e-12)
require.Greater(t, cb.USD, 0.0, "a priced custom provider yields a nonzero USD")
}
// TestCostFromUsage_ZeroUsageNotEstimated asserts a no-usage provider
// still yields a (zero) cost block flagged Estimated:false.
func TestCostFromUsage_ZeroUsageNotEstimated(t *testing.T) {
cb := CostFromUsage(llm.TokenUsage{}, llm.ProviderPricing{Input: 3.0, Output: 15.0}, 1000)
require.False(t, cb.Estimated)
require.Equal(t, 0.0, cb.USD)
require.Equal(t, int64(1000), cb.ElapsedMs)
}
// TestAttributeFindingTokens_SumsToTotal asserts output tokens are split
// across findings proportionally and conserve the total (±rounding folded
// into the last finding).
func TestAttributeFindingTokens_SumsToTotal(t *testing.T) {
findings := []Finding{
{Message: "short", Body: "tiny body"},
{Message: "a much longer finding message", Body: "a considerably longer body with more tokens to weigh"},
{Message: "mid", Body: "medium body here"},
}
total := llm.TokenUsage{OutputTokens: 1000}
AttributeFindingTokens(findings, total)
sum := 0
for _, f := range findings {
require.GreaterOrEqual(t, f.GenTokens, 0)
sum += f.GenTokens
}
require.Equal(t, total.OutputTokens, sum, "per-finding shares must sum to the output total")
// The longest finding must get at least as many tokens as the shortest.
require.GreaterOrEqual(t, findings[1].GenTokens, findings[0].GenTokens)
}
func TestAttributeFindingTokens_NoOpOnEmpty(t *testing.T) {
// Nothing to attribute — must not panic and must leave GenTokens zero.
AttributeFindingTokens(nil, llm.TokenUsage{OutputTokens: 100})
f := []Finding{{Message: "x"}}
AttributeFindingTokens(f, llm.TokenUsage{OutputTokens: 0})
require.Equal(t, 0, f[0].GenTokens)
}
// TestRunWithUsage_SurfacesCostBreakdown asserts a review driven through
// the usage-aware seam attaches a CostBreakdown to the report, with the
// summed usage, USD from the price card, and per-finding GenTokens.
func TestRunWithUsage_SurfacesCostBreakdown(t *testing.T) {
reply := `[
{"file":"app/svc.go","snippet":"return p.Balance","message":"possible nil dereference of p","severity":"critical","category":"correctness"}
]`
usage := llm.TokenUsage{InputTokens: 800, OutputTokens: 200, CacheReadTokens: 100}
gen := func(_ context.Context, _ string, _ int) (string, llm.TokenUsage, error) {
return reply, usage, nil
}
price := llm.ProviderPricing{Input: 3.0, Output: 15.0}
report, err := RunWithUsage(context.Background(), nil, gen, price, Options{
RepoRoot: "/tmp/repo",
Diff: sampleDiff,
Rules: testResolver(t),
UseLLM: true,
})
require.NoError(t, err)
require.NotNil(t, report)
require.NotNil(t, report.Cost, "a usage-aware seam must surface a cost block")
require.Equal(t, 800, report.Cost.InputTokens)
require.Equal(t, 200, report.Cost.OutputTokens)
require.Equal(t, 100, report.Cost.CacheReadTokens)
require.True(t, report.Cost.Estimated)
require.Greater(t, report.Cost.USD, 0.0)
// The LLM finding carries an attributed token share.
var sawLLM bool
for _, f := range report.Findings {
if f.Source == "llm" {
sawLLM = true
require.Greater(t, f.GenTokens, 0, "an LLM finding must carry attributed gen tokens")
}
}
require.True(t, sawLLM, "the LLM finding must survive into the report")
}
// TestRunWithUsage_NilSeamZeroCost asserts a nil seam still produces a
// report with a zero, Estimated:false cost block (deterministic-only).
func TestRunWithUsage_NilSeamZeroCost(t *testing.T) {
report, err := RunWithUsage(context.Background(), nil, nil, llm.ProviderPricing{}, Options{
RepoRoot: "/tmp/repo",
Diff: sampleDiff,
Rules: testResolver(t),
UseLLM: true,
})
require.NoError(t, err)
require.NotNil(t, report.Cost)
require.False(t, report.Cost.Estimated)
require.Equal(t, 0.0, report.Cost.USD)
}