Skip to content

Commit

Permalink
Merge pull request #3250 from ai16z-demirix/tests/plugin-cronos
Browse files Browse the repository at this point in the history
feat (chore): plugin-cronos test setup and coverage
  • Loading branch information
shakkernerd authored Feb 5, 2025
2 parents 0e16f97 + 7d8ebe5 commit 89fa5a4
Show file tree
Hide file tree
Showing 5 changed files with 352 additions and 2 deletions.
152 changes: 152 additions & 0 deletions packages/plugin-cronos/__tests__/actions/balance.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { balanceAction } from '../../src/actions/balance';
import {
type IAgentRuntime,
type Memory,
ModelClass,
ModelProviderName,
type State,
type HandlerCallback,
} from '@elizaos/core';
import * as core from '@elizaos/core';

// Mock generateObject
vi.mock('@elizaos/core', async () => {
const actual = await vi.importActual('@elizaos/core');
return {
...actual,
generateObject: vi.fn().mockResolvedValue({
object: {
chain: 'cronos',
address: '0x1234567890123456789012345678901234567890'
}
}),
};
});

// Mock wallet provider
vi.mock('../../src/providers/wallet', () => ({
initCronosWalletProvider: vi.fn().mockReturnValue({
switchChain: vi.fn(),
getWalletClient: vi.fn(),
getAddressBalance: vi.fn().mockResolvedValue('1.0'),
}),
}));

describe('balance action', () => {
const mockRuntime: IAgentRuntime = {
getSetting: vi.fn().mockReturnValue('0x1234567890123456789012345678901234567890123456789012345678901234'),
composeState: vi.fn().mockResolvedValue({}),
updateRecentMessageState: vi.fn().mockResolvedValue({}),
generateText: vi.fn(),
model: {
[ModelClass.SMALL]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
},
[ModelClass.MEDIUM]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
},
[ModelClass.LARGE]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
}
},
modelProvider: ModelProviderName.OPENAI,
};

const mockMessage: Memory = {
content: {
text: 'Check balance for 0x1234567890123456789012345678901234567890 on Cronos',
},
};

const mockCallback: HandlerCallback = vi.fn();

beforeEach(() => {
vi.clearAllMocks();
});

it('should validate successfully', async () => {
const result = await balanceAction.validate(mockRuntime);
expect(result).toBe(true);
});

it('should handle successful balance check', async () => {
const result = await balanceAction.handler(
mockRuntime,
mockMessage,
undefined,
undefined,
mockCallback
);

expect(result).toBe(true);
expect(mockCallback).toHaveBeenCalledWith({
text: 'Balance for 0x1234567890123456789012345678901234567890 on cronos is 1.0 CRO',
content: {
success: true,
balance: '1.0',
chain: 'cronos',
address: '0x1234567890123456789012345678901234567890'
}
});
});

it('should handle balance check with existing state', async () => {
const mockState = {};
const result = await balanceAction.handler(
mockRuntime,
mockMessage,
mockState,
undefined,
mockCallback
);

expect(result).toBe(true);
expect(mockRuntime.updateRecentMessageState).toHaveBeenCalledWith(mockState);
});

it('should handle balance check failure', async () => {
const mockError = new Error('Failed to fetch balance');
const mockProvider = {
switchChain: vi.fn(),
getWalletClient: vi.fn(),
getAddressBalance: vi.fn().mockRejectedValue(mockError),
};

// Reset the mock first
const walletModule = await import('../../src/providers/wallet');
vi.mocked(walletModule.initCronosWalletProvider).mockResolvedValueOnce(mockProvider);

const result = await balanceAction.handler(
mockRuntime,
mockMessage,
undefined,
undefined,
mockCallback
);

expect(result).toBe(false);
expect(mockCallback).toHaveBeenCalledWith({
text: 'Error checking balance: Failed to fetch balance',
content: { error: 'Failed to fetch balance' }
});
});
});
164 changes: 164 additions & 0 deletions packages/plugin-cronos/__tests__/actions/transfer.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { transferAction } from '../../src/actions/transfer';
import {
type IAgentRuntime,
type Memory,
ModelClass,
ModelProviderName,
type State,
type HandlerCallback,
} from '@elizaos/core';
import * as core from '@elizaos/core';
import { parseEther } from 'viem';

// Mock generateObject
vi.mock('@elizaos/core', async () => {
const actual = await vi.importActual('@elizaos/core');
return {
...actual,
generateObject: vi.fn().mockResolvedValue({
object: {
chain: 'cronos',
toAddress: '0x1234567890123456789012345678901234567890',
amount: '1.0'
}
}),
};
});

// Mock wallet provider
vi.mock('../../src/providers/wallet', () => ({
initCronosWalletProvider: vi.fn().mockReturnValue({
switchChain: vi.fn(),
getWalletClient: vi.fn().mockReturnValue({
account: {
address: '0x1234567890123456789012345678901234567890',
},
sendTransaction: vi.fn().mockResolvedValue('0x123'),
}),
}),
}));

describe('transfer action', () => {
const mockRuntime: IAgentRuntime = {
getSetting: vi.fn().mockReturnValue('0x1234567890123456789012345678901234567890123456789012345678901234'),
composeState: vi.fn().mockResolvedValue({}),
updateRecentMessageState: vi.fn().mockResolvedValue({}),
generateText: vi.fn(),
model: {
[ModelClass.SMALL]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
},
[ModelClass.MEDIUM]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
},
[ModelClass.LARGE]: {
name: 'gpt-4',
maxInputTokens: 128000,
maxOutputTokens: 8192,
frequency_penalty: 0.0,
presence_penalty: 0.0,
temperature: 0.6,
stop: [],
}
},
modelProvider: ModelProviderName.OPENAI,
};

const mockMessage: Memory = {
content: {
text: 'Send 1.0 CRO to 0x1234567890123456789012345678901234567890 on Cronos',
},
};

const mockCallback: HandlerCallback = vi.fn();

beforeEach(() => {
vi.clearAllMocks();
});

it('should validate successfully', async () => {
const result = await transferAction.validate(mockRuntime);
expect(result).toBe(true);
});

it('should handle successful transfer', async () => {
const result = await transferAction.handler(
mockRuntime,
mockMessage,
undefined,
undefined,
mockCallback
);

expect(result).toBe(true);
expect(mockCallback).toHaveBeenCalledWith({
text: 'Successfully transferred 1.0 CRO to 0x1234567890123456789012345678901234567890\nTransaction Hash: 0x123',
content: {
success: true,
hash: '0x123',
amount: '1',
recipient: '0x1234567890123456789012345678901234567890',
chain: undefined
}
});
});

it('should handle transfer with existing state', async () => {
const mockState = {};
const result = await transferAction.handler(
mockRuntime,
mockMessage,
mockState,
undefined,
mockCallback
);

expect(result).toBe(true);
expect(mockRuntime.updateRecentMessageState).toHaveBeenCalledWith(mockState);
});


it('should handle transfer failure', async () => {
const mockError = new Error('Transfer failed');
const mockProvider = {
switchChain: vi.fn(),
getWalletClient: vi.fn().mockReturnValue({
account: {
address: '0x1234567890123456789012345678901234567890',
},
sendTransaction: vi.fn().mockRejectedValue(mockError),
}),
};

// Reset the mock first
const walletModule = await import('../../src/providers/wallet');
vi.mocked(walletModule.initCronosWalletProvider).mockResolvedValueOnce(mockProvider);

const result = await transferAction.handler(
mockRuntime,
mockMessage,
undefined,
undefined,
mockCallback
);

expect(result).toBe(false);
expect(mockCallback).toHaveBeenCalledWith({
text: 'Error transferring tokens: Transfer failed: Transfer failed',
content: { error: 'Transfer failed: Transfer failed' }
});
});
});
22 changes: 22 additions & 0 deletions packages/plugin-cronos/__tests__/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { vi } from 'vitest';

// Mock viem functions
vi.mock('viem', () => ({
isAddress: vi.fn().mockReturnValue(true),
formatEther: vi.fn().mockReturnValue('1.0'),
parseEther: vi.fn().mockReturnValue(BigInt(1000000000000000000)), // 1 ETH
}));

// Mock wallet provider
vi.mock('../../src/providers/wallet', () => ({
initCronosWalletProvider: vi.fn().mockReturnValue({
switchChain: vi.fn(),
getWalletClient: vi.fn().mockReturnValue({
account: {
address: '0x1234567890123456789012345678901234567890',
},
sendTransaction: vi.fn().mockResolvedValue('0x123'),
}),
getAddressBalance: vi.fn().mockResolvedValue('1.0'),
}),
}));
6 changes: 4 additions & 2 deletions packages/plugin-cronos/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
},
"devDependencies": {
"@biomejs/biome": "1.9.4",
"tsup": "8.3.5"
"tsup": "8.3.5",
"vitest": "3.0.5"
},
"scripts": {
"build": "tsup --format esm --no-dts",
Expand All @@ -32,7 +33,8 @@
"lint": "biome lint .",
"lint:fix": "biome check --apply .",
"format": "biome format .",
"format:fix": "biome format --write ."
"format:fix": "biome format --write .",
"test": "vitest run"
},
"peerDependencies": {
"whatwg-url": "7.1.0"
Expand Down
10 changes: 10 additions & 0 deletions packages/plugin-cronos/vitest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from 'vitest/config';

export default defineConfig({
test: {
globals: true,
environment: 'node',
setupFiles: ['./__tests__/setup.ts'],
include: ['**/__tests__/**/*.test.ts'],
}
});

0 comments on commit 89fa5a4

Please sign in to comment.