basant307/AI_Governance_Project
048
1/**2 * @license3 * Copyright 2025 Google LLC4 * SPDX-License-Identifier: Apache-2.05 */6 7import { describe, it, expect } from 'vitest';8import { calculateCost } from './costCalculator.js';9 10describe('calculateCost', () => {11 it('calculates cost correctly with both input and output pricing', () => {12 const cost = calculateCost({13 inputTokens: 1_000_000,14 outputTokens: 1_000_000,15 pricing: {16 inputPerMillionTokens: 0.3,17 outputPerMillionTokens: 1.2,18 },19 });20 21 // 1M input tokens * $0.30/M = $0.3022 // 1M output tokens * $1.20/M = $1.2023 // Total = $1.5024 expect(cost).toBe(1.5);25 });26 27 it('returns null when pricing is not defined', () => {28 const cost = calculateCost({29 inputTokens: 1000,30 outputTokens: 500,31 pricing: undefined,32 });33 34 expect(cost).toBeNull();35 });36 37 it('handles only input pricing', () => {38 const cost = calculateCost({39 inputTokens: 1_000_000,40 outputTokens: 1_000_000,41 pricing: {42 inputPerMillionTokens: 0.3,43 },44 });45 46 // 1M input tokens * $0.30/M = $0.3047 // No output pricing, so outputCost = 048 // Total = $0.3049 expect(cost).toBe(0.3);50 });51 52 it('handles only output pricing', () => {53 const cost = calculateCost({54 inputTokens: 1_000_000,55 outputTokens: 1_000_000,56 pricing: {57 outputPerMillionTokens: 1.2,58 },59 });60 61 // No input pricing, so inputCost = 062 // 1M output tokens * $1.20/M = $1.2063 // Total = $1.2064 expect(cost).toBe(1.2);65 });66 67 it('returns null for zero tokens when pricing is defined', () => {68 const cost = calculateCost({69 inputTokens: 0,70 outputTokens: 0,71 pricing: {72 inputPerMillionTokens: 0.3,73 outputPerMillionTokens: 1.2,74 },75 });76 77 expect(cost).toBeNull();78 });79 80 it('handles partial tokens correctly', () => {81 const cost = calculateCost({82 inputTokens: 500_000,83 outputTokens: 250_000,84 pricing: {85 inputPerMillionTokens: 0.3,86 outputPerMillionTokens: 1.2,87 },88 });89 90 // 500K input tokens * $0.30/M = $0.1591 // 250K output tokens * $1.20/M = $0.3092 // Total = $0.4593 expect(cost).toBeCloseTo(0.45);94 });95 96 it('returns null when pricing object is empty', () => {97 const cost = calculateCost({98 inputTokens: 1000,99 outputTokens: 500,100 pricing: {},101 });102 103 expect(cost).toBeNull();104 });105 106 it('returns null when pricing has null/undefined values', () => {107 const cost = calculateCost({108 inputTokens: 1000,109 outputTokens: 500,110 pricing: {111 inputPerMillionTokens: undefined,112 outputPerMillionTokens: undefined,113 },114 });115 116 expect(cost).toBeNull();117 });118 119 it('handles very small token counts', () => {120 const cost = calculateCost({121 inputTokens: 1,122 outputTokens: 1,123 pricing: {124 inputPerMillionTokens: 1.0,125 outputPerMillionTokens: 2.0,126 },127 });128 129 // 1 token * $1.0/M = $0.000001130 // 1 token * $2.0/M = $0.000002131 // Total = $0.000003132 expect(cost).toBeCloseTo(0.000003, 10);133 });134 135 it('handles very large token counts', () => {136 const cost = calculateCost({137 inputTokens: 1_000_000_000, // 1B tokens138 outputTokens: 500_000_000,139 pricing: {140 inputPerMillionTokens: 0.3,141 outputPerMillionTokens: 1.2,142 },143 });144 145 // 1B input tokens * $0.30/M = $300146 // 500M output tokens * $1.20/M = $600147 // Total = $900148 expect(cost).toBe(900);149 });150 151 it('handles zero input tokens with output pricing', () => {152 const cost = calculateCost({153 inputTokens: 0,154 outputTokens: 1_000_000,155 pricing: {156 outputPerMillionTokens: 1.2,157 },158 });159 160 expect(cost).toBe(1.2);161 });162 163 it('handles zero output tokens with input pricing', () => {164 const cost = calculateCost({165 inputTokens: 1_000_000,166 outputTokens: 0,167 pricing: {168 inputPerMillionTokens: 0.3,169 },170 });171 172 expect(cost).toBe(0.3);173 });174 175 it('handles fractional pricing', () => {176 const cost = calculateCost({177 inputTokens: 1_000_000,178 outputTokens: 1_000_000,179 pricing: {180 inputPerMillionTokens: 0.123456,181 outputPerMillionTokens: 0.654321,182 },183 });184 185 expect(cost).toBeCloseTo(0.777777, 6);186 });187 188 it('rounds to 4 decimal places in display format', () => {189 const cost = calculateCost({190 inputTokens: 123_456,191 outputTokens: 789_012,192 pricing: {193 inputPerMillionTokens: 0.3,194 outputPerMillionTokens: 1.2,195 },196 });197 198 // 123,456 * $0.30/M = $0.0370368199 // 789,012 * $1.20/M = $0.9468144200 // Total = $0.9838512201 expect(cost).toBeCloseTo(0.9838512, 7);202 // Verify the toFixed(4) formatting that the UI uses203 expect(cost?.toFixed(4)).toBe('0.9839');204 });205});206 