mirror of
https://github.com/geoffsee/open-gsio.git
synced 2025-09-08 22:56:46 +00:00
add tests for ModelStore and MessagesStore
This commit is contained in:

committed by
Geoff Seemueller

parent
0509583910
commit
0bb4d6e11c
218
src/stores/__tests__/MessagesStore.test.ts
Normal file
218
src/stores/__tests__/MessagesStore.test.ts
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
import { describe, it, expect, beforeEach } from 'vitest';
|
||||||
|
import { MessagesStore } from '../MessagesStore';
|
||||||
|
import Message from '../../models/Message';
|
||||||
|
import { getSnapshot } from 'mobx-state-tree';
|
||||||
|
|
||||||
|
describe('MessagesStore', () => {
|
||||||
|
let messagesStore;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Create a new instance of the store before each test
|
||||||
|
messagesStore = MessagesStore.create();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Initial state', () => {
|
||||||
|
it('should have empty items array initially', () => {
|
||||||
|
expect(messagesStore.items).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('add', () => {
|
||||||
|
it('should add a message to the items array', () => {
|
||||||
|
// Create a message
|
||||||
|
const message = Message.create({
|
||||||
|
content: 'Hello, world!',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add the message to the store
|
||||||
|
messagesStore.add(message);
|
||||||
|
|
||||||
|
// Check that the message was added
|
||||||
|
expect(messagesStore.items.length).toBe(1);
|
||||||
|
expect(messagesStore.items[0].content).toBe('Hello, world!');
|
||||||
|
expect(messagesStore.items[0].role).toBe('user');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should add multiple messages to the items array', () => {
|
||||||
|
// Create messages
|
||||||
|
const message1 = Message.create({
|
||||||
|
content: 'Hello',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message2 = Message.create({
|
||||||
|
content: 'Hi there',
|
||||||
|
role: 'assistant',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add the messages to the store
|
||||||
|
messagesStore.add(message1);
|
||||||
|
messagesStore.add(message2);
|
||||||
|
|
||||||
|
// Check that the messages were added
|
||||||
|
expect(messagesStore.items.length).toBe(2);
|
||||||
|
expect(messagesStore.items[0].content).toBe('Hello');
|
||||||
|
expect(messagesStore.items[0].role).toBe('user');
|
||||||
|
expect(messagesStore.items[1].content).toBe('Hi there');
|
||||||
|
expect(messagesStore.items[1].role).toBe('assistant');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('updateLast', () => {
|
||||||
|
it('should update the content of the last message', () => {
|
||||||
|
// Add a message
|
||||||
|
const message = Message.create({
|
||||||
|
content: 'Hello',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
messagesStore.add(message);
|
||||||
|
|
||||||
|
// Update the last message
|
||||||
|
messagesStore.updateLast('Updated content');
|
||||||
|
|
||||||
|
// Check that the message was updated
|
||||||
|
expect(messagesStore.items[0].content).toBe('Updated content');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if there are no messages', () => {
|
||||||
|
// Try to update the last message when there are no messages
|
||||||
|
messagesStore.updateLast('Updated content');
|
||||||
|
|
||||||
|
// Check that nothing happened
|
||||||
|
expect(messagesStore.items.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('appendLast', () => {
|
||||||
|
it('should append content to the last message', () => {
|
||||||
|
// Add a message
|
||||||
|
const message = Message.create({
|
||||||
|
content: 'Hello',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
messagesStore.add(message);
|
||||||
|
|
||||||
|
// Append to the last message
|
||||||
|
messagesStore.appendLast(', world!');
|
||||||
|
|
||||||
|
// Check that the message was updated
|
||||||
|
expect(messagesStore.items[0].content).toBe('Hello, world!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if there are no messages', () => {
|
||||||
|
// Try to append to the last message when there are no messages
|
||||||
|
messagesStore.appendLast(', world!');
|
||||||
|
|
||||||
|
// Check that nothing happened
|
||||||
|
expect(messagesStore.items.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('removeAfter', () => {
|
||||||
|
it('should remove all messages after the specified index', () => {
|
||||||
|
// Add messages
|
||||||
|
const message1 = Message.create({
|
||||||
|
content: 'Message 1',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message2 = Message.create({
|
||||||
|
content: 'Message 2',
|
||||||
|
role: 'assistant',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message3 = Message.create({
|
||||||
|
content: 'Message 3',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
messagesStore.add(message1);
|
||||||
|
messagesStore.add(message2);
|
||||||
|
messagesStore.add(message3);
|
||||||
|
|
||||||
|
// Remove messages after index 0
|
||||||
|
messagesStore.removeAfter(0);
|
||||||
|
|
||||||
|
// Check that messages were removed
|
||||||
|
expect(messagesStore.items.length).toBe(1);
|
||||||
|
expect(messagesStore.items[0].content).toBe('Message 1');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if index is out of bounds (negative)', () => {
|
||||||
|
// Add messages
|
||||||
|
const message1 = Message.create({
|
||||||
|
content: 'Message 1',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message2 = Message.create({
|
||||||
|
content: 'Message 2',
|
||||||
|
role: 'assistant',
|
||||||
|
});
|
||||||
|
|
||||||
|
messagesStore.add(message1);
|
||||||
|
messagesStore.add(message2);
|
||||||
|
|
||||||
|
// Try to remove messages with negative index
|
||||||
|
messagesStore.removeAfter(-1);
|
||||||
|
|
||||||
|
// Check that nothing happened
|
||||||
|
expect(messagesStore.items.length).toBe(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if index is out of bounds (too large)', () => {
|
||||||
|
// Add messages
|
||||||
|
const message1 = Message.create({
|
||||||
|
content: 'Message 1',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message2 = Message.create({
|
||||||
|
content: 'Message 2',
|
||||||
|
role: 'assistant',
|
||||||
|
});
|
||||||
|
|
||||||
|
messagesStore.add(message1);
|
||||||
|
messagesStore.add(message2);
|
||||||
|
|
||||||
|
// Try to remove messages with index that's too large
|
||||||
|
messagesStore.removeAfter(2);
|
||||||
|
|
||||||
|
// Check that nothing happened
|
||||||
|
expect(messagesStore.items.length).toBe(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('reset', () => {
|
||||||
|
it('should remove all messages', () => {
|
||||||
|
// Add messages
|
||||||
|
const message1 = Message.create({
|
||||||
|
content: 'Message 1',
|
||||||
|
role: 'user',
|
||||||
|
});
|
||||||
|
|
||||||
|
const message2 = Message.create({
|
||||||
|
content: 'Message 2',
|
||||||
|
role: 'assistant',
|
||||||
|
});
|
||||||
|
|
||||||
|
messagesStore.add(message1);
|
||||||
|
messagesStore.add(message2);
|
||||||
|
|
||||||
|
// Reset the store
|
||||||
|
messagesStore.reset();
|
||||||
|
|
||||||
|
// Check that all messages were removed
|
||||||
|
expect(messagesStore.items.length).toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should do nothing if there are no messages', () => {
|
||||||
|
// Reset the store when there are no messages
|
||||||
|
messagesStore.reset();
|
||||||
|
|
||||||
|
// Check that nothing happened
|
||||||
|
expect(messagesStore.items.length).toBe(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
119
src/stores/__tests__/ModelStore.test.ts
Normal file
119
src/stores/__tests__/ModelStore.test.ts
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
|
||||||
|
import { ModelStore } from '../ModelStore';
|
||||||
|
|
||||||
|
describe('ModelStore', () => {
|
||||||
|
let modelStore;
|
||||||
|
|
||||||
|
// Mock localStorage
|
||||||
|
const localStorageMock = {
|
||||||
|
getItem: vi.fn(),
|
||||||
|
setItem: vi.fn(),
|
||||||
|
clear: vi.fn(),
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// Create a new instance of the store before each test
|
||||||
|
modelStore = ModelStore.create();
|
||||||
|
|
||||||
|
// Setup localStorage mock
|
||||||
|
Object.defineProperty(window, 'localStorage', {
|
||||||
|
value: localStorageMock,
|
||||||
|
writable: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Clear all mocks
|
||||||
|
vi.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
// Restore all mocks
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Initial state', () => {
|
||||||
|
it('should have default model set initially', () => {
|
||||||
|
expect(modelStore.model).toBe('meta-llama/llama-4-scout-17b-16e-instruct');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have default image model set initially', () => {
|
||||||
|
expect(modelStore.imageModel).toBe('black-forest-labs/flux-1.1-pro');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have empty supportedModels array initially', () => {
|
||||||
|
expect(modelStore.supportedModels).toEqual([]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setModel', () => {
|
||||||
|
it('should update the model value', () => {
|
||||||
|
modelStore.setModel('new-model');
|
||||||
|
expect(modelStore.model).toBe('new-model');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should save the model to localStorage', () => {
|
||||||
|
modelStore.setModel('new-model');
|
||||||
|
expect(localStorageMock.setItem).toHaveBeenCalledWith('recentModel', 'new-model');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle localStorage errors gracefully', () => {
|
||||||
|
// Make localStorage.setItem throw an error
|
||||||
|
localStorageMock.setItem.mockImplementation(() => {
|
||||||
|
throw new Error('localStorage error');
|
||||||
|
});
|
||||||
|
|
||||||
|
// This should not throw an error
|
||||||
|
expect(() => modelStore.setModel('new-model')).not.toThrow();
|
||||||
|
expect(modelStore.model).toBe('new-model');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setImageModel', () => {
|
||||||
|
it('should update the imageModel value', () => {
|
||||||
|
modelStore.setImageModel('new-image-model');
|
||||||
|
expect(modelStore.imageModel).toBe('new-image-model');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('setSupportedModels', () => {
|
||||||
|
it('should update the supportedModels array', () => {
|
||||||
|
const models = ['model1', 'model2', 'model3'];
|
||||||
|
modelStore.setSupportedModels(models);
|
||||||
|
expect(modelStore.supportedModels).toEqual(models);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not change the current model if it is in the supported models list', () => {
|
||||||
|
// First set a model
|
||||||
|
modelStore.setModel('model2');
|
||||||
|
|
||||||
|
// Then set supported models including the current model
|
||||||
|
const models = ['model1', 'model2', 'model3'];
|
||||||
|
modelStore.setSupportedModels(models);
|
||||||
|
|
||||||
|
// The model should remain the same
|
||||||
|
expect(modelStore.model).toBe('model2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should change the current model if it is not in the supported models list', () => {
|
||||||
|
// First set a model
|
||||||
|
modelStore.setModel('unsupported-model');
|
||||||
|
|
||||||
|
// Then set supported models not including the current model
|
||||||
|
const models = ['model1', 'model2', 'model3'];
|
||||||
|
modelStore.setSupportedModels(models);
|
||||||
|
|
||||||
|
// The model should be changed to the last model in the list
|
||||||
|
expect(modelStore.model).toBe('model3');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle empty supported models list', () => {
|
||||||
|
// First set a model
|
||||||
|
modelStore.setModel('current-model');
|
||||||
|
|
||||||
|
// Then set empty supported models
|
||||||
|
modelStore.setSupportedModels([]);
|
||||||
|
|
||||||
|
// The model should remain the same since there's no alternative
|
||||||
|
expect(modelStore.model).toBe('current-model');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Reference in New Issue
Block a user