File size: 6,504 Bytes
9332ccf | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | /**
* @license
* Copyright 2025 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import {
formatDuration,
formatBytes,
formatTimeAgo,
stripReferenceContent,
formatResetTime,
} from './formatters.js';
describe('formatters', () => {
describe('formatResetTime', () => {
const NOW = new Date('2025-01-01T12:00:00Z');
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(NOW);
});
afterEach(() => {
vi.useRealTimers();
});
it('should format full time correctly', () => {
const resetTime = new Date(NOW.getTime() + 90 * 60 * 1000).toISOString(); // 1h 30m
const result = formatResetTime(resetTime);
expect(result).toMatch(/1 hour 30 minutes at \d{1,2}:\d{2} [AP]M/);
});
it('should format terse time correctly', () => {
const resetTime = new Date(NOW.getTime() + 90 * 60 * 1000).toISOString(); // 1h 30m
expect(formatResetTime(resetTime, 'terse')).toBe('1h 30m');
});
it('should format column time correctly', () => {
const resetTime = new Date(NOW.getTime() + 90 * 60 * 1000).toISOString(); // 1h 30m
const result = formatResetTime(resetTime, 'column');
expect(result).toMatch(/\d{1,2}:\d{2} [AP]M \(1h 30m\)/);
});
it('should handle zero or negative diff by returning empty string', () => {
const resetTime = new Date(NOW.getTime() - 1000).toISOString();
expect(formatResetTime(resetTime)).toBe('');
});
});
describe('formatBytes', () => {
it('should format bytes into KB', () => {
expect(formatBytes(12345)).toBe('12.1 KB');
});
it('should format bytes into MB', () => {
expect(formatBytes(12345678)).toBe('11.8 MB');
});
it('should format bytes into GB', () => {
expect(formatBytes(12345678901)).toBe('11.50 GB');
});
});
describe('formatDuration', () => {
it('should format milliseconds less than a second', () => {
expect(formatDuration(500)).toBe('500ms');
});
it('should format a duration of 0', () => {
expect(formatDuration(0)).toBe('0s');
});
it('should format an exact number of seconds', () => {
expect(formatDuration(5000)).toBe('5.0s');
});
it('should format a duration in seconds with one decimal place', () => {
expect(formatDuration(12345)).toBe('12.3s');
});
it('should format an exact number of minutes', () => {
expect(formatDuration(120000)).toBe('2m');
});
it('should format a duration in minutes and seconds', () => {
expect(formatDuration(123000)).toBe('2m 3s');
});
it('should format an exact number of hours', () => {
expect(formatDuration(3600000)).toBe('1h');
});
it('should format a duration in hours and seconds', () => {
expect(formatDuration(3605000)).toBe('1h 5s');
});
it('should format a duration in hours, minutes, and seconds', () => {
expect(formatDuration(3723000)).toBe('1h 2m 3s');
});
it('should handle large durations', () => {
expect(formatDuration(86400000 + 3600000 + 120000 + 1000)).toBe(
'25h 2m 1s',
);
});
it('should handle negative durations', () => {
expect(formatDuration(-100)).toBe('0s');
});
});
describe('formatTimeAgo', () => {
const NOW = new Date('2025-01-01T12:00:00Z');
beforeEach(() => {
vi.useFakeTimers();
vi.setSystemTime(NOW);
});
afterEach(() => {
vi.useRealTimers();
});
it('should return "just now" for dates less than a minute ago', () => {
const past = new Date(NOW.getTime() - 30 * 1000);
expect(formatTimeAgo(past)).toBe('just now');
});
it('should return minutes ago', () => {
const past = new Date(NOW.getTime() - 5 * 60 * 1000);
expect(formatTimeAgo(past)).toBe('5m ago');
});
it('should return hours ago', () => {
const past = new Date(NOW.getTime() - 3 * 60 * 60 * 1000);
expect(formatTimeAgo(past)).toBe('3h ago');
});
it('should return days ago', () => {
const past = new Date(NOW.getTime() - 2 * 24 * 60 * 60 * 1000);
expect(formatTimeAgo(past)).toBe('48h ago');
});
it('should handle string dates', () => {
const past = '2025-01-01T11:00:00Z'; // 1 hour ago
expect(formatTimeAgo(past)).toBe('1h ago');
});
it('should handle number timestamps', () => {
const past = NOW.getTime() - 10 * 60 * 1000; // 10 minutes ago
expect(formatTimeAgo(past)).toBe('10m ago');
});
it('should handle invalid timestamps', () => {
const past = 'hello';
expect(formatTimeAgo(past)).toBe('invalid date');
});
});
describe('stripReferenceContent', () => {
it('should return the original text if no markers are present', () => {
const text = 'Hello world';
expect(stripReferenceContent(text)).toBe(text);
});
it('should strip content between markers', () => {
const text =
'Prompt @file.txt\n--- Content from referenced files ---\nFile content here\n--- End of content ---';
expect(stripReferenceContent(text)).toBe('Prompt @file.txt');
});
it('should strip content and keep text after the markers', () => {
const text =
'Before\n--- Content from referenced files ---\nMiddle\n--- End of content ---\nAfter';
expect(stripReferenceContent(text)).toBe('Before\nAfter');
});
it('should handle missing end marker gracefully', () => {
const text = 'Before\n--- Content from referenced files ---\nMiddle';
expect(stripReferenceContent(text)).toBe(text);
});
it('should handle end marker before start marker gracefully', () => {
const text =
'--- End of content ---\n--- Content from referenced files ---';
expect(stripReferenceContent(text)).toBe(text);
});
it('should strip even if markers are on the same line (though unlikely)', () => {
const text =
'A--- Content from referenced files ---B--- End of content ---C';
expect(stripReferenceContent(text)).toBe('AC');
});
it('should strip multiple blocks correctly and preserve text in between', () => {
const text =
'Start\n--- Content from referenced files ---\nBlock1\n--- End of content ---\nMiddle\n--- Content from referenced files ---\nBlock2\n--- End of content ---\nEnd';
expect(stripReferenceContent(text)).toBe('Start\nMiddle\nEnd');
});
});
});
|