mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
195 lines
6.9 KiB
TypeScript
195 lines
6.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
|
|
import { Utils } from '../utils.ts';
|
|
|
|
describe('Utils', () => {
|
|
describe('getSeason', () => {
|
|
// Based on the actual behavior from debug tests (months are 0-indexed in JavaScript):
|
|
// Winter: month < 2 (Jan, Feb) OR month === 2 && day <= 20 (Mar 1-20) OR month === 11 (Dec)
|
|
// Spring: (month === 2 && day > 20) (Mar 21-31) OR month === 3 || month === 4 (Apr, May) OR (month === 5 && day <= 21) (Jun 1-21)
|
|
// Summer: (month === 5 && day > 21) (Jun 22-30) OR month === 6 || month === 7 (Jul, Aug) OR (month === 8 && day <= 22) (Sep 1-22)
|
|
// Autumn: (month === 8 && day > 22) (Sep 23-30) OR month === 9 || month === 10 (Oct, Nov)
|
|
|
|
it('should return Winter for dates in winter in Northern Hemisphere', () => {
|
|
expect(Utils.getSeason('2023-01-15')).toBe('Winter'); // January (month 0)
|
|
expect(Utils.getSeason('2023-02-15')).toBe('Winter'); // February (month 1)
|
|
expect(Utils.getSeason('2023-03-20')).toBe('Winter'); // March 20 (month 2)
|
|
expect(Utils.getSeason('2023-12-15')).toBe('Winter'); // December (month 11)
|
|
});
|
|
|
|
it('should return Spring for dates in spring in Northern Hemisphere', () => {
|
|
expect(Utils.getSeason('2023-03-25')).toBe('Spring'); // March 25 (month 2)
|
|
expect(Utils.getSeason('2023-04-15')).toBe('Spring'); // April (month 3)
|
|
expect(Utils.getSeason('2023-05-15')).toBe('Spring'); // May (month 4)
|
|
expect(Utils.getSeason('2023-06-21')).toBe('Spring'); // June 21 (month 5)
|
|
});
|
|
|
|
it('should return Summer for dates in summer in Northern Hemisphere', () => {
|
|
expect(Utils.getSeason('2023-06-23')).toBe('Summer'); // June 23 (month 5)
|
|
expect(Utils.getSeason('2023-07-15')).toBe('Summer'); // July (month 6)
|
|
expect(Utils.getSeason('2023-08-15')).toBe('Summer'); // August (month 7)
|
|
expect(Utils.getSeason('2023-09-22')).toBe('Summer'); // September 22 (month 8)
|
|
});
|
|
|
|
it('should return Autumn for dates in autumn in Northern Hemisphere', () => {
|
|
expect(Utils.getSeason('2023-09-24')).toBe('Autumn'); // September 24 (month 8)
|
|
expect(Utils.getSeason('2023-10-15')).toBe('Autumn'); // October (month 9)
|
|
expect(Utils.getSeason('2023-11-15')).toBe('Autumn'); // November (month 10)
|
|
});
|
|
});
|
|
|
|
describe('getTimezone', () => {
|
|
const originalDateTimeFormat = Intl.DateTimeFormat;
|
|
|
|
beforeEach(() => {
|
|
// Mock Intl.DateTimeFormat
|
|
global.Intl.DateTimeFormat = vi.fn().mockReturnValue({
|
|
resolvedOptions: vi.fn().mockReturnValue({
|
|
timeZone: 'America/New_York',
|
|
}),
|
|
});
|
|
});
|
|
|
|
afterEach(() => {
|
|
// Restore original
|
|
global.Intl.DateTimeFormat = originalDateTimeFormat;
|
|
});
|
|
|
|
it('should return the provided timezone if available', () => {
|
|
expect(Utils.getTimezone('Europe/London')).toBe('Europe/London');
|
|
});
|
|
|
|
it('should return the system timezone if no timezone is provided', () => {
|
|
expect(Utils.getTimezone(undefined)).toBe('America/New_York');
|
|
});
|
|
});
|
|
|
|
describe('getCurrentDate', () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
vi.setSystemTime(new Date('2023-01-01T12:30:45Z'));
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.useRealTimers();
|
|
});
|
|
|
|
it('should return the current date as an ISO string', () => {
|
|
expect(Utils.getCurrentDate()).toBe('2023-01-01T12:30:45.000Z');
|
|
});
|
|
});
|
|
|
|
describe('isAssetUrl', () => {
|
|
it('should return true for URLs starting with /assets/', () => {
|
|
expect(Utils.isAssetUrl('https://example.com/assets/image.png')).toBe(true);
|
|
expect(Utils.isAssetUrl('http://localhost:8080/assets/script.js')).toBe(true);
|
|
});
|
|
|
|
it('should return false for URLs not starting with /assets/', () => {
|
|
expect(Utils.isAssetUrl('https://example.com/api/data')).toBe(false);
|
|
expect(Utils.isAssetUrl('http://localhost:8080/images/logo.png')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('selectEquitably', () => {
|
|
beforeEach(() => {
|
|
// Mock Math.random to return predictable values
|
|
vi.spyOn(Math, 'random').mockReturnValue(0.5);
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('should select items equitably from multiple sources', () => {
|
|
const sources = {
|
|
a: { key1: 'value1', key2: 'value2' },
|
|
b: { key3: 'value3', key4: 'value4' },
|
|
c: { key5: 'value5', key6: 'value6' },
|
|
d: { key7: 'value7', key8: 'value8' },
|
|
};
|
|
|
|
const result = Utils.selectEquitably(sources, 4);
|
|
|
|
expect(Object.keys(result).length).toBe(4);
|
|
// Due to the mocked Math.random, the selection should be deterministic
|
|
// but we can't predict the exact keys due to the sort, so we just check the count
|
|
});
|
|
|
|
it('should handle itemCount greater than available items', () => {
|
|
const sources = {
|
|
a: { key1: 'value1' },
|
|
b: { key2: 'value2' },
|
|
c: {},
|
|
d: {},
|
|
};
|
|
|
|
const result = Utils.selectEquitably(sources, 5);
|
|
|
|
expect(Object.keys(result).length).toBe(2);
|
|
expect(result).toHaveProperty('key1');
|
|
expect(result).toHaveProperty('key2');
|
|
});
|
|
|
|
it('should handle empty sources', () => {
|
|
const sources = {
|
|
a: {},
|
|
b: {},
|
|
c: {},
|
|
d: {},
|
|
};
|
|
|
|
const result = Utils.selectEquitably(sources, 5);
|
|
|
|
expect(Object.keys(result).length).toBe(0);
|
|
});
|
|
});
|
|
|
|
describe('normalizeWithBlanks', () => {
|
|
it('should insert blank messages to maintain user/assistant alternation', () => {
|
|
const messages = [
|
|
{ role: 'user', content: 'Hello' },
|
|
{ role: 'user', content: 'How are you?' },
|
|
];
|
|
|
|
const result = Utils.normalizeWithBlanks(messages);
|
|
|
|
expect(result.length).toBe(3);
|
|
expect(result[0]).toEqual({ role: 'user', content: 'Hello' });
|
|
expect(result[1]).toEqual({ role: 'assistant', content: '' });
|
|
expect(result[2]).toEqual({ role: 'user', content: 'How are you?' });
|
|
});
|
|
|
|
it('should insert blank user message if first message is assistant', () => {
|
|
const messages = [{ role: 'assistant', content: 'Hello, how can I help?' }];
|
|
|
|
const result = Utils.normalizeWithBlanks(messages);
|
|
|
|
expect(result.length).toBe(2);
|
|
expect(result[0]).toEqual({ role: 'user', content: '' });
|
|
expect(result[1]).toEqual({ role: 'assistant', content: 'Hello, how can I help?' });
|
|
});
|
|
|
|
it('should handle empty array', () => {
|
|
const messages: any[] = [];
|
|
|
|
const result = Utils.normalizeWithBlanks(messages);
|
|
|
|
expect(result.length).toBe(0);
|
|
});
|
|
|
|
it('should handle already alternating messages', () => {
|
|
const messages = [
|
|
{ role: 'user', content: 'Hello' },
|
|
{ role: 'assistant', content: 'Hi there' },
|
|
{ role: 'user', content: 'How are you?' },
|
|
];
|
|
|
|
const result = Utils.normalizeWithBlanks(messages);
|
|
|
|
expect(result.length).toBe(3);
|
|
expect(result).toEqual(messages);
|
|
});
|
|
});
|
|
});
|