Skip to content

Commit

Permalink
Merge pull request #1 from ai16z-demirix/feature/tests
Browse files Browse the repository at this point in the history
Tests setup for starters
  • Loading branch information
ai16z-demirix authored Nov 16, 2024
2 parents 4b1caa0 + 5014a2c commit f0a3276
Show file tree
Hide file tree
Showing 13 changed files with 1,193 additions and 7 deletions.
35 changes: 35 additions & 0 deletions packages/core/README-TESTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Core Package Tests

This package contains a test suite for evaluating functionalities using **Jest**.

## Prerequisites

1. **pnpm**: Ensure you have `pnpm` installed. If not, you can install it globally using:
```bash
npm install -g pnpm
```

2. **Environment Variables**: Set up a `.env` file in the project root (eliza) with the necessary environment variables. Copy .env.example file and add required variables.

## Setup

1. Navigate to the `packages/core` directory:
```bash
cd packages/core
```

2. Install dependencies:
```bash
pnpm install
```

## Running Tests

Run all tests using:
```bash
pnpm test
```

The test results will be displayed in the terminal.

---
1 change: 0 additions & 1 deletion packages/core/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ export default {
testEnvironment: "node",
rootDir: "./src",
testMatch: ["**/*.test.ts"],
setupFilesAfterEnv: ["<rootDir>/test_resources/testSetup.ts"],
testTimeout: 120000,
globals: {
__DEV__: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/embedding.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmbeddingModel, FlagEmbedding } from "fastembed";
import { FlagEmbedding } from "fastembed";
import path from "path";
import { fileURLToPath } from "url";
import { models } from "./models.ts";
Expand Down
239 changes: 239 additions & 0 deletions packages/core/src/tests/database.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
/* eslint-disable no-dupe-class-members */
import { DatabaseAdapter } from '../database.ts'; // Adjust the import based on your project structure
import { Memory, Actor, Account, Goal, GoalStatus, Participant, Relationship, UUID } from '../types'; // Adjust based on your types location

class MockDatabaseAdapter extends DatabaseAdapter {
getMemoryById(_id: UUID): Promise<Memory | null> {
throw new Error('Method not implemented.');
}
log(_params: { body: { [key: string]: unknown; }; userId: UUID; roomId: UUID; type: string; }): Promise<void> {
throw new Error('Method not implemented.');
}
getActorDetails(_params: { roomId: UUID; }): Promise<Actor[]> {
throw new Error('Method not implemented.');
}
searchMemoriesByEmbedding(_embedding: number[], _params: { match_threshold?: number; count?: number; roomId?: UUID; agentId?: UUID; unique?: boolean; tableName: string; }): Promise<Memory[]> {
throw new Error('Method not implemented.');
}
createMemory(_memory: Memory, _tableName: string, _unique?: boolean): Promise<void> {
throw new Error('Method not implemented.');
}
removeMemory(_memoryId: UUID, _tableName: string): Promise<void> {
throw new Error('Method not implemented.');
}
removeAllMemories(_roomId: UUID, _tableName: string): Promise<void> {
throw new Error('Method not implemented.');
}
countMemories(_roomId: UUID, _unique?: boolean, _tableName?: string): Promise<number> {
throw new Error('Method not implemented.');
}
getGoals(_params: { roomId: UUID; userId?: UUID | null; onlyInProgress?: boolean; count?: number; }): Promise<Goal[]> {
throw new Error('Method not implemented.');
}
updateGoal(_goal: Goal): Promise<void> {
throw new Error('Method not implemented.');
}
createGoal(_goal: Goal): Promise<void> {
throw new Error('Method not implemented.');
}
removeGoal(_goalId: UUID): Promise<void> {
throw new Error('Method not implemented.');
}
removeAllGoals(_roomId: UUID): Promise<void> {
throw new Error('Method not implemented.');
}
getRoom(_roomId: UUID): Promise<UUID | null> {
throw new Error('Method not implemented.');
}
createRoom(_roomId?: UUID): Promise<UUID> {
throw new Error('Method not implemented.');
}
removeRoom(_roomId: UUID): Promise<void> {
throw new Error('Method not implemented.');
}
getRoomsForParticipant(_userId: UUID): Promise<UUID[]> {
throw new Error('Method not implemented.');
}
getRoomsForParticipants(_userIds: UUID[]): Promise<UUID[]> {
throw new Error('Method not implemented.');
}
addParticipant(_userId: UUID, _roomId: UUID): Promise<boolean> {
throw new Error('Method not implemented.');
}
removeParticipant(_userId: UUID, _roomId: UUID): Promise<boolean> {
throw new Error('Method not implemented.');
}
getParticipantsForAccount(userId: UUID): Promise<Participant[]>;
getParticipantsForAccount(userId: UUID): Promise<Participant[]>;
getParticipantsForAccount(_userId: unknown): Promise<import("../types").Participant[]> {
throw new Error('Method not implemented.');
}
getParticipantsForRoom(_roomId: UUID): Promise<UUID[]> {
throw new Error('Method not implemented.');
}
getParticipantUserState(_roomId: UUID, _userId: UUID): Promise<'FOLLOWED' | 'MUTED' | null> {
throw new Error('Method not implemented.');
}
setParticipantUserState(_roomId: UUID, _userId: UUID, _state: 'FOLLOWED' | 'MUTED' | null): Promise<void> {
throw new Error('Method not implemented.');
}
createRelationship(_params: { userA: UUID; userB: UUID; }): Promise<boolean> {
throw new Error('Method not implemented.');
}
getRelationship(_params: { userA: UUID; userB: UUID; }): Promise<Relationship | null> {
throw new Error('Method not implemented.');
}
getRelationships(_params: { userId: UUID; }): Promise<Relationship[]> {
throw new Error('Method not implemented.');
}
db: any = {};

// Mock method for getting memories by room IDs
async getMemoriesByRoomIds(params: { roomIds: `${string}-${string}-${string}-${string}-${string}`[]; agentId?: `${string}-${string}-${string}-${string}-${string}`; tableName: string }): Promise<Memory[]> {
return [{
id: 'memory-id' as UUID,
content: 'Test Memory',
roomId: params.roomIds[0],
userId: 'user-id' as UUID,
agentId: params.agentId ?? 'agent-id' as UUID
}] as unknown as Memory[];
}

// Mock method for getting cached embeddings
async getCachedEmbeddings(_params: { query_table_name: string; query_threshold: number; query_input: string; query_field_name: string; query_field_sub_name: string; query_match_count: number }): Promise<any[]> {
return [{
embedding: [0.1, 0.2, 0.3],
levenshtein_distance: 0.4
}];
}

// Mock method for searching memories
async searchMemories(params: { tableName: string; roomId: `${string}-${string}-${string}-${string}-${string}`; embedding: number[]; match_threshold: number; match_count: number; unique: boolean }): Promise<Memory[]> {
return [{
id: 'memory-id' as UUID,
content: 'Test Memory',
roomId: params.roomId,
userId: 'user-id' as UUID,
agentId: 'agent-id' as UUID
}] as unknown as Memory[];
}

// Mock method for getting account by ID
async getAccountById(userId: UUID): Promise<Account | null> {
return { id: userId, username: 'testuser', name: 'Test Account' } as Account;
}

// Other methods stay the same...
async createAccount(_account: Account): Promise<boolean> {
return true;
}

async getMemories(params: { roomId: UUID; count?: number; unique?: boolean; tableName: string }): Promise<Memory[]> {
return [{
id: 'memory-id' as UUID,
content: 'Test Memory',
roomId: params.roomId,
userId: 'user-id' as UUID,
agentId: 'agent-id' as UUID
}] as unknown as Memory[];
}

async getActors(_params: { roomId: UUID }): Promise<Actor[]> {
return [{
id: 'actor-id' as UUID,
name: 'Test Actor',
username: 'testactor',
roomId: 'room-id' as UUID // Ensure roomId is provided
}] as unknown as Actor[];
}

async updateGoalStatus(_params: { goalId: UUID, status: GoalStatus }): Promise<void> {
return Promise.resolve();
}

async getGoalById(goalId: UUID): Promise<Goal | null> {
return {
id: goalId,
status: GoalStatus.IN_PROGRESS,
roomId: 'room-id' as UUID,
userId: 'user-id' as UUID,
name: 'Test Goal',
objectives: []
} as Goal;
}
}

// Now, let’s fix the test suite.

describe('DatabaseAdapter Tests', () => {
let adapter: MockDatabaseAdapter;
const roomId = 'room-id' as UUID;

beforeEach(() => {
adapter = new MockDatabaseAdapter();
});

it('should return memories by room ID', async () => {
const memories = await adapter.getMemoriesByRoomIds({
roomIds: ['room-id' as `${string}-${string}-${string}-${string}-${string}`],
tableName: 'test_table'
});
expect(memories).toHaveLength(1);
expect(memories[0].roomId).toBe('room-id');
});

it('should return cached embeddings', async () => {
const embeddings = await adapter.getCachedEmbeddings({
query_table_name: 'test_table',
query_threshold: 0.5,
query_input: 'test query',
query_field_name: 'field',
query_field_sub_name: 'subfield',
query_match_count: 5
});
expect(embeddings).toHaveLength(1);
expect(embeddings[0].embedding).toEqual([0.1, 0.2, 0.3]);
});

it('should search memories based on embedding', async () => {
const memories = await adapter.searchMemories({
tableName: 'test_table',
roomId: 'room-id' as `${string}-${string}-${string}-${string}-${string}`,
embedding: [0.1, 0.2, 0.3],
match_threshold: 0.5,
match_count: 3,
unique: true
});
expect(memories).toHaveLength(1);
expect(memories[0].roomId).toBe('room-id');
});

it('should get an account by user ID', async () => {
const account = await adapter.getAccountById('test-user-id' as UUID);
expect(account).not.toBeNull();
expect(account.username).toBe('testuser');
});

it('should create a new account', async () => {
const newAccount: Account = { id: 'new-user-id' as UUID, username: 'newuser', name: 'New Account' };
const result = await adapter.createAccount(newAccount);
expect(result).toBe(true);
});

it('should update the goal status', async () => {
const goalId = 'goal-id' as UUID;
await expect(adapter.updateGoalStatus({ goalId, status: GoalStatus.IN_PROGRESS })).resolves.toBeUndefined();
});

it('should return actors by room ID', async () => {
const actors = await adapter.getActors({ roomId });
expect(actors).toHaveLength(1);
});

it('should get a goal by ID', async () => {
const goalId = 'goal-id' as UUID;
const goal = await adapter.getGoalById(goalId);
expect(goal).not.toBeNull();
expect(goal?.status).toBe(GoalStatus.IN_PROGRESS);
});
});
48 changes: 48 additions & 0 deletions packages/core/src/tests/defaultCharacters.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { defaultCharacter } from '../defaultCharacter';
import { ModelProviderName } from '../types';

describe('defaultCharacter', () => {
it('should have the correct name', () => {
expect(defaultCharacter.name).toBe('Eliza');
});

it('should have an empty plugins array', () => {
expect(defaultCharacter.plugins).toEqual([]);
});

it('should have an empty clients array', () => {
expect(defaultCharacter.clients).toEqual([]);
});

it('should have the correct modelProvider', () => {
expect(defaultCharacter.modelProvider).toBe(ModelProviderName.OPENAI);
});

it('should have the correct voice model', () => {
expect(defaultCharacter.settings.voice.model).toBe('en_US-hfc_female-medium');
});

it('should have a system description', () => {
expect(defaultCharacter.system).toBe('Roleplay and generate interesting on behalf of Eliza.');
});

it('should have a bio array with at least one entry', () => {
expect(defaultCharacter.bio.length).toBeGreaterThan(0);
});

it('should have a lore array with at least one entry', () => {
expect(defaultCharacter.lore.length).toBeGreaterThan(0);
});

it('should have messageExamples array with at least one example', () => {
expect(defaultCharacter.messageExamples.length).toBeGreaterThan(0);
});

it('should have a topics array with at least one broad topic', () => {
expect(defaultCharacter.topics).toContain('metaphysics');
});

it('should have style settings with "all" array', () => {
expect(defaultCharacter.style.all.length).toBeGreaterThan(0);
});
});
Loading

0 comments on commit f0a3276

Please sign in to comment.