Skip to main content
Glama
structure.repo.test.ts8.02 kB
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import * as fs from 'fs'; import { initDB } from '../../src/storage/db'; import { migrate } from '../../src/storage/migrations'; import { StructureRepository } from '../../src/storage/repos/structure.repo'; import { WorldRepository } from '../../src/storage/repos/world.repo'; import { Structure, StructureType } from '../../src/schema/structure'; import { World } from '../../src/schema/world'; import { FIXED_TIMESTAMP } from '../fixtures'; const TEST_DB_PATH = 'test-structure-repo.db'; describe('StructureRepository', () => { let db: ReturnType<typeof initDB>; let repo: StructureRepository; let worldRepo: WorldRepository; beforeEach(() => { if (fs.existsSync(TEST_DB_PATH)) { fs.unlinkSync(TEST_DB_PATH); } db = initDB(TEST_DB_PATH); migrate(db); repo = new StructureRepository(db); worldRepo = new WorldRepository(db); const world: World = { id: 'world-1', name: 'Test World', seed: 'seed-1', width: 100, height: 100, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; worldRepo.create(world); }); afterEach(() => { db.close(); if (fs.existsSync(TEST_DB_PATH)) { fs.unlinkSync(TEST_DB_PATH); } }); it('should create and retrieve a structure', () => { const structure: Structure = { id: 'struct-1', worldId: 'world-1', name: 'Castle Black', type: StructureType.CASTLE, x: 50, y: 50, population: 100, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; repo.create(structure); const retrieved = repo.findByWorldId('world-1'); expect(retrieved).toHaveLength(1); expect(retrieved[0]).toEqual(structure); }); it('should find structures by worldId', () => { const s1: Structure = { id: 's1', worldId: 'world-1', name: 'Town 1', type: StructureType.TOWN, x: 10, y: 10, population: 500, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; const s2: Structure = { id: 's2', worldId: 'world-1', name: 'Village 1', type: StructureType.VILLAGE, x: 20, y: 20, population: 50, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; repo.create(s1); repo.create(s2); const structures = repo.findByWorldId('world-1'); expect(structures).toHaveLength(2); expect(structures).toContainEqual(s1); expect(structures).toContainEqual(s2); }); describe('createBatch', () => { it('should create multiple structures in a single transaction', () => { const structures: Structure[] = [ { id: 'b1', worldId: 'world-1', name: 'City 1', type: StructureType.CITY, x: 10, y: 10, population: 10000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 'b2', worldId: 'world-1', name: 'Town 1', type: StructureType.TOWN, x: 20, y: 20, population: 2000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 'b3', worldId: 'world-1', name: 'Village 1', type: StructureType.VILLAGE, x: 30, y: 30, population: 100, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 'b4', worldId: 'world-1', name: 'Dungeon 1', type: StructureType.DUNGEON, x: 40, y: 40, population: 0, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, ]; const count = repo.createBatch(structures); expect(count).toBe(4); const retrieved = repo.findByWorldId('world-1'); expect(retrieved).toHaveLength(4); }); it('should return 0 for empty array', () => { const count = repo.createBatch([]); expect(count).toBe(0); }); }); describe('findById', () => { it('should find a structure by id', () => { const structure: Structure = { id: 'find-me', worldId: 'world-1', name: 'Findable Castle', type: StructureType.CASTLE, x: 50, y: 50, population: 500, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; repo.create(structure); const found = repo.findById('find-me'); expect(found).not.toBeNull(); expect(found?.name).toBe('Findable Castle'); }); it('should return null for non-existent id', () => { const found = repo.findById('nonexistent'); expect(found).toBeNull(); }); }); describe('findByCoordinates', () => { it('should find structure at coordinates', () => { const structure: Structure = { id: 'coord-struct', worldId: 'world-1', name: 'Located Town', type: StructureType.TOWN, x: 75, y: 25, population: 1000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP, }; repo.create(structure); const found = repo.findByCoordinates('world-1', 75, 25); expect(found).not.toBeNull(); expect(found?.name).toBe('Located Town'); }); it('should return null for empty coordinates', () => { const found = repo.findByCoordinates('world-1', 99, 99); expect(found).toBeNull(); }); }); describe('findByType', () => { it('should find structures by type', () => { const structures: Structure[] = [ { id: 't1', worldId: 'world-1', name: 'Town A', type: StructureType.TOWN, x: 10, y: 10, population: 1000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 't2', worldId: 'world-1', name: 'Town B', type: StructureType.TOWN, x: 20, y: 20, population: 2000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 't3', worldId: 'world-1', name: 'City A', type: StructureType.CITY, x: 30, y: 30, population: 10000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, ]; repo.createBatch(structures); const towns = repo.findByType('world-1', StructureType.TOWN); expect(towns).toHaveLength(2); expect(towns.every(s => s.type === StructureType.TOWN)).toBe(true); const cities = repo.findByType('world-1', StructureType.CITY); expect(cities).toHaveLength(1); }); }); describe('deleteByWorldId', () => { it('should delete all structures for a world', () => { const structures: Structure[] = [ { id: 'd1', worldId: 'world-1', name: 'Town A', type: StructureType.TOWN, x: 10, y: 10, population: 1000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, { id: 'd2', worldId: 'world-1', name: 'Town B', type: StructureType.TOWN, x: 20, y: 20, population: 2000, createdAt: FIXED_TIMESTAMP, updatedAt: FIXED_TIMESTAMP }, ]; repo.createBatch(structures); expect(repo.findByWorldId('world-1')).toHaveLength(2); const deleted = repo.deleteByWorldId('world-1'); expect(deleted).toBe(2); expect(repo.findByWorldId('world-1')).toHaveLength(0); }); it('should return 0 when no structures exist', () => { const deleted = repo.deleteByWorldId('nonexistent-world'); expect(deleted).toBe(0); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Mnehmos/rpg-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server