@zerospacegg/vynthra
Version:
Discord bot for ZeroSpace.gg data
279 lines (258 loc) • 6.05 kB
text/typescript
// Test setup file for node:test
// This file is automatically loaded before each test
import { beforeEach, afterEach, mock } from "node:test";
// Global test setup
beforeEach(() => {
// Reset all mocks before each test
// Reset environment variables
delete process.env.DISCORD_TOKEN;
delete process.env.DISCORD_CLIENT_ID;
delete process.env.DISCORD_GUILD_ID;
// Patch process.versions.node for Discord.js/undici compatibility
if (process.versions && !process.versions.node) {
Object.defineProperty(process.versions, "node", {
value: "20.0.0",
configurable: true,
});
}
});
afterEach(() => {
// Clean up after each test
mock.restoreAll();
});
// Helper function to create mock bot config
export function createMockBotConfig(overrides = {}) {
return {
token: "mock-discord-token",
clientId: "mock-client-id",
guildId: "mock-guild-id",
...overrides,
};
}
// Helper function to create mock interaction
export function createMockInteraction(overrides = {}): any {
const mockInteraction = {
isChatInputCommand: () => true,
commandName: "test-command",
options: {
getSubcommand: () => "stats",
getString: (name: string, required?: boolean) => {
if (name === "query") return "test query";
if (name === "username") return "testuser";
return null;
},
getBoolean: () => false,
},
user: {
tag: "TestUser#5678",
},
reply: mock.fn(async () => undefined),
deferReply: mock.fn(async () => undefined),
editReply: mock.fn(async () => undefined),
followUp: mock.fn(async () => undefined),
replied: false,
deferred: false,
};
return {
...mockInteraction,
...overrides,
};
}
// Helper function to create mock Discord client
export function createMockClient(): any {
const mockCollection = () => ({
set: mock.fn(),
get: mock.fn(),
has: mock.fn(),
delete: mock.fn(),
clear: mock.fn(),
size: 0,
values: () => [],
keys: () => [],
entries: () => [],
forEach: mock.fn(),
});
return {
commands: mockCollection(),
login: mock.fn(async () => "token"),
destroy: mock.fn(),
once: mock.fn(),
on: mock.fn(),
user: {
tag: "TestBot#1234",
},
guilds: {
cache: {
size: 5,
},
},
};
}
// Mock search functions for testing
export function createMockSearchResult(
type: "single" | "multi" | "none",
options: any = {},
) {
switch (type) {
case "single":
return {
type: "single",
entity: {
id: "unit/test/",
slug: "test",
name: "Test Unit",
type: "unit",
faction: "terran",
tier: "T1",
...options.entity,
},
fullEntity: {
id: "unit/test/",
name: "Test Unit",
hp: 100,
damage: 25,
hexiteCost: 50,
fluxCost: 25,
buildTime: 30,
...options.fullEntity,
},
};
case "multi":
return {
type: "multi",
matches: options.matches || [
{
id: "unit/test1/",
slug: "test1",
name: "Test Unit 1",
type: "unit",
},
{
id: "unit/test2/",
slug: "test2",
name: "Test Unit 2",
type: "unit",
},
],
};
case "none":
return {
type: "none",
query: options.query || "nonexistent",
};
default:
throw new Error(`Unknown result type: ${type}`);
}
}
// Mock fuzzy search class
export class MockFzf {
private items: any[];
private options: any;
constructor(items: any[], options?: any) {
this.items = items;
this.options = options || {};
}
find(query: string) {
// Simple mock fuzzy search
const selector = this.options.selector || ((item: any) => String(item));
return this.items
.map((item: any, index: number) => ({
item,
score: selector(item).toLowerCase().includes(query.toLowerCase())
? 0.8
: 0.2,
positions: new Set([0, 1, 2]),
}))
.filter((result: any) => result.score > 0.3)
.sort((a: any, b: any) => b.score - a.score);
}
}
// Global console override to reduce noise in tests
const originalConsole = { ...console };
global.console = {
...console,
log: mock.fn(),
warn: mock.fn(),
error: mock.fn(),
info: mock.fn(),
};
// Restore console for specific tests that need it
export function restoreConsole() {
global.console = originalConsole;
}
export function mockConsole() {
global.console = {
...console,
log: mock.fn(),
warn: mock.fn(),
error: mock.fn(),
info: mock.fn(),
};
}
// Test data helpers
export const testEntities = {
lasher: {
id: "unit/lasher/",
slug: "lasher",
name: "Lasher",
type: "unit" as const,
faction: "terran",
tier: "T1",
shortName: "Lasher",
subtype: "unit",
inGame: true,
},
tank: {
id: "unit/tank/",
slug: "tank",
name: "Tank",
type: "unit" as const,
faction: "terran",
tier: "T2",
shortName: "Tank",
subtype: "unit",
inGame: true,
},
barracks: {
id: "building/barracks/",
slug: "barracks",
name: "Barracks",
type: "building" as const,
faction: "terran",
tier: "T1",
shortName: "Barracks",
subtype: "building",
inGame: true,
},
};
export const testFullEntities = {
lasher: {
id: "unit/lasher/",
name: "Lasher",
hp: 100,
speed: 5,
damage: 25,
hexiteCost: 50,
fluxCost: 25,
buildTime: 30,
tagList: ["mechanical", "ground"],
},
tank: {
id: "unit/tank/",
name: "Tank",
hp: 200,
speed: 3,
damage: 50,
hexiteCost: 100,
fluxCost: 50,
buildTime: 60,
tagList: ["mechanical", "ground", "armored"],
},
barracks: {
id: "building/barracks/",
name: "Barracks",
hp: 500,
hexiteCost: 100,
buildTime: 60,
},
};