add tests for ModelStore and MessagesStore

This commit is contained in:
geoffsee
2025-05-30 22:43:41 -04:00
committed by Geoff Seemueller
parent 0509583910
commit 0bb4d6e11c
2 changed files with 337 additions and 0 deletions

View 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);
});
});
});

View 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');
});
});
});