/** * usage-log.test.ts * * parseOpenAiUsage is the single point where every non-Ollama provider's token counts get * picked up (openai-compat serves Gemini/LM Studio/OpenAI, openai-codex serves Codex). It * returning null silently means a provider vanishes from the cost-comparison log entirely — * which is exactly the bug this module was extracted to fix on 2026-07-29, and the kind that * produces no error, just a quietly wrong conclusion months later. */ import { test, describe } from 'node:test'; import assert from 'node:assert/strict'; import { parseOpenAiUsage } from '../src/providers/usage-log'; describe('parseOpenAiUsage', () => { test('표준 OpenAI usage 필드를 읽는다', () => { assert.deepEqual( parseOpenAiUsage({ prompt_tokens: 137, completion_tokens: 42 }), { promptTokens: 137, completionTokens: 42 }, ); }); test('camelCase 변형도 받는다', () => { assert.deepEqual( parseOpenAiUsage({ promptTokens: 10, completionTokens: 20 }), { promptTokens: 10, completionTokens: 20 }, ); }); test('한쪽만 있어도 기록한다 — 절반이라도 남기는 게 0건보다 낫다', () => { assert.deepEqual(parseOpenAiUsage({ prompt_tokens: 500 }), { promptTokens: 500, completionTokens: 0 }); assert.deepEqual(parseOpenAiUsage({ completion_tokens: 7 }), { promptTokens: 0, completionTokens: 7 }); }); test('usage가 없거나 값이 없으면 null — 0/0짜리 가짜 행을 남기지 않는다', () => { assert.equal(parseOpenAiUsage(undefined), null); assert.equal(parseOpenAiUsage(null), null); assert.equal(parseOpenAiUsage({}), null); assert.equal(parseOpenAiUsage({ prompt_tokens: 0, completion_tokens: 0 }), null); assert.equal(parseOpenAiUsage('nope' as any), null); }); test('숫자가 아닌 값은 0으로 떨어뜨린다 (NaN이 로그에 새지 않게)', () => { assert.equal(parseOpenAiUsage({ prompt_tokens: 'abc', completion_tokens: 'def' }), null); assert.deepEqual( parseOpenAiUsage({ prompt_tokens: 'abc', completion_tokens: 5 }), { promptTokens: 0, completionTokens: 5 }, ); }); });