mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00

Update README deployment steps and add deploy:secrets script to package.json update local inference script and README update lockfile reconfigure package scripts for development update test execution pass server tests Update README with revised Bun commands and workspace details remove pnpm package manager designator create bun server
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.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);
|
|
});
|
|
});
|
|
});
|