test-utils.ts•4.55 kB
/**
 * Test utility functions
 */
import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
/**
 * Create a temporary test directory with optional files
 */
export function createTestWorkspace(files?: Record<string, string>): {
    path: string;
    cleanup: () => void;
} {
    const path = mkdtempSync(join(tmpdir(), 'in-memoria-workspace-'));
    // Create files if provided
    if (files) {
        for (const [filePath, content] of Object.entries(files)) {
            const fullPath = join(path, filePath);
            const dir = fullPath.substring(0, fullPath.lastIndexOf('/'));
            // Create parent directories
            mkdirSync(dir, { recursive: true });
            // Write file
            writeFileSync(fullPath, content, 'utf-8');
        }
    }
    return {
        path,
        cleanup: () => {
            try {
                rmSync(path, { recursive: true, force: true });
            } catch (error) {
                console.warn(`Failed to cleanup test workspace: ${path}`, error);
            }
        },
    };
}
/**
 * Create sample code files for testing
 */
export const sampleCode = {
    typescript: {
        simpleClass: `
export class UserService {
  private users: User[] = [];
  
  async createUser(userData: CreateUserRequest): Promise<User> {
    const user = new User(userData);
    this.users.push(user);
    return user;
  }
  
  async getUserById(id: string): Promise<User | null> {
    return this.users.find(u => u.id === id) || null;
  }
}
interface User {
  id: string;
  name: string;
  email: string;
}
interface CreateUserRequest {
  name: string;
  email: string;
}
`,
        reactComponent: `
import React, { useState, useEffect } from 'react';
interface Props {
  userId: string;
}
export const UserProfile: React.FC<Props> = ({ userId }) => {
  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetchUser(userId);
  }, [userId]);
  
  const fetchUser = async (id: string) => {
    const response = await fetch(\`/api/users/\${id}\`);
    const data = await response.json();
    setUser(data);
    setLoading(false);
  };
  
  if (loading) return <div>Loading...</div>;
  if (!user) return <div>User not found</div>;
  
  return (
    <div className="user-profile">
      <h1>{user.name}</h1>
      <p>{user.email}</p>
    </div>
  );
};
`,
    },
    javascript: {
        simpleFunction: `
export function calculateTotal(items) {
  return items.reduce((sum, item) => sum + item.price, 0);
}
export function formatCurrency(amount) {
  return new Intl.NumberFormat('en-US', {
    style: 'currency',
    currency: 'USD'
  }).format(amount);
}
`,
    },
    python: {
        simpleClass: `
class DataProcessor:
    def __init__(self, data):
        self.data = data
        self.processed = False
    
    def process(self):
        if not self.processed:
            self.data = [item * 2 for item in self.data]
            self.processed = True
        return self.data
    
    def reset(self):
        self.processed = False
`,
    },
};
/**
 * Wait for a condition to be true
 */
export async function waitFor(
    condition: () => boolean | Promise<boolean>,
    timeout: number = 5000,
    interval: number = 100
): Promise<void> {
    const startTime = Date.now();
    while (Date.now() - startTime < timeout) {
        if (await condition()) {
            return;
        }
        await new Promise(resolve => setTimeout(resolve, interval));
    }
    throw new Error(`Timeout waiting for condition after ${timeout}ms`);
}
/**
 * Create a mock database path for testing
 */
export function createTestDbPath(name: string = 'test'): string {
    const tempDir = mkdtempSync(join(tmpdir(), 'in-memoria-db-'));
    return join(tempDir, `${name}.db`);
}
/**
 * Sleep for a specified duration
 */
export function sleep(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
}
/**
 * Retry a function multiple times
 */
export async function retry<T>(
    fn: () => Promise<T>,
    maxAttempts: number = 3,
    delayMs: number = 1000
): Promise<T> {
    let lastError: Error | unknown;
    for (let attempt = 1; attempt <= maxAttempts; attempt++) {
        try {
            return await fn();
        } catch (error) {
            lastError = error;
            if (attempt < maxAttempts) {
                await sleep(delayMs);
            }
        }
    }
    throw lastError;
}