mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
196 lines
6.9 KiB
TypeScript
196 lines
6.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
import { Utils } from '../utils';
|
|
|
|
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);
|
|
});
|
|
});
|
|
});
|