@seedts/testing
Version: 
Testing utilities for SeedTS - Snapshot testing, deterministic seeding, and test helpers
198 lines • 6.02 kB
JavaScript
;
/**
 * Test helper utilities for SeedTS
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.executeSeedsAsMap = executeSeedsAsMap;
exports.assertSeedSuccess = assertSeedSuccess;
exports.assertAllSeedsSuccess = assertAllSeedsSuccess;
exports.getSeedByName = getSeedByName;
exports.assertSeedCount = assertSeedCount;
exports.assertSeedData = assertSeedData;
exports.assertSeedDuration = assertSeedDuration;
exports.createValidator = createValidator;
exports.waitFor = waitFor;
exports.deepEqual = deepEqual;
/**
 * Execute seeds and return results by name for easy access
 *
 * @param executor Executor instance
 * @returns Map of seed results by name
 *
 * @example
 * ```typescript
 * const executor = new Executor([UsersSeed, PostsSeed]);
 * const results = await executeSeedsAsMap(executor);
 *
 * expect(results.get('users')).toBeDefined();
 * expect(results.get('users')?.count).toBe(10);
 * ```
 */
async function executeSeedsAsMap(executor) {
    const results = await executor.execute();
    const map = new Map();
    for (const result of results) {
        map.set(result.name, result);
    }
    return map;
}
/**
 * Assert that a seed executed successfully
 *
 * @param result Seed result
 * @throws Error if seed failed
 *
 * @example
 * ```typescript
 * const results = await executor.execute();
 * assertSeedSuccess(results[0]);
 * ```
 */
function assertSeedSuccess(result) {
    if (!result) {
        throw new Error('Seed result is undefined');
    }
    if (!result.success || result.error) {
        throw new Error(`Seed "${result.name}" failed: ${result.error?.message || 'Unknown error'}`);
    }
    if (result.recordCount === 0) {
        throw new Error(`Seed "${result.name}" produced 0 records`);
    }
}
/**
 * Assert that all seeds executed successfully
 *
 * @param results Array of seed results
 * @throws Error if any seed failed
 */
function assertAllSeedsSuccess(results) {
    const failures = results.filter(r => !r.success || r.error);
    if (failures.length > 0) {
        const errors = failures.map(f => `  - ${f.name}: ${f.error?.message || 'Unknown error'}`).join('\n');
        throw new Error(`${failures.length} seed(s) failed:\n${errors}`);
    }
}
/**
 * Get seed result by name
 *
 * @param results Array of seed results
 * @param name Seed name
 * @returns Seed result or undefined
 */
function getSeedByName(results, name) {
    return results.find(r => r.name === name);
}
/**
 * Assert that seed result exists and has expected count
 *
 * @param result Seed result
 * @param expectedCount Expected record count
 * @throws Error if count doesn't match
 */
function assertSeedCount(result, expectedCount) {
    assertSeedSuccess(result);
    if (result.recordCount !== expectedCount) {
        throw new Error(`Seed "${result.name}" expected ${expectedCount} records but got ${result.recordCount}`);
    }
}
/**
 * Assert that seed data matches predicate
 *
 * @param data Seed data array
 * @param seedName Seed name (for error messages)
 * @param predicate Function to test each record
 * @throws Error if any record fails predicate
 */
function assertSeedData(data, seedName, predicate, message) {
    const failedRecords = data.filter((record, index) => {
        try {
            return !predicate(record);
        }
        catch (error) {
            throw new Error(`Predicate error at index ${index}: ${error instanceof Error ? error.message : 'Unknown error'}`);
        }
    });
    if (failedRecords.length > 0) {
        throw new Error(message ||
            `${failedRecords.length} record(s) in seed "${seedName}" failed validation`);
    }
}
/**
 * Assert that seed completed within expected duration
 *
 * @param result Seed result
 * @param maxDuration Maximum duration in milliseconds
 * @throws Error if duration exceeds limit
 */
function assertSeedDuration(result, maxDuration) {
    if (result.duration > maxDuration) {
        throw new Error(`Seed "${result.name}" took ${result.duration}ms, expected < ${maxDuration}ms`);
    }
}
/**
 * Create a test data validator
 *
 * @example
 * ```typescript
 * const validateUser = createValidator<User>({
 *   email: (v) => typeof v === 'string' && v.includes('@'),
 *   age: (v) => typeof v === 'number' && v >= 0 && v <= 150,
 *   name: (v) => typeof v === 'string' && v.length > 0
 * });
 *
 * assertSeedData(usersResult, validateUser);
 * ```
 */
function createValidator(rules) {
    return (record) => {
        for (const [key, validator] of Object.entries(rules)) {
            if (validator && !validator(record[key])) {
                throw new Error(`Validation failed for field "${key}"`);
            }
        }
        return true;
    };
}
/**
 * Wait for a condition to be true with timeout
 *
 * @param condition Function that returns true when condition is met
 * @param timeout Timeout in milliseconds (default: 5000)
 * @param interval Check interval in milliseconds (default: 100)
 * @throws Error if timeout reached
 */
async function waitFor(condition, timeout = 5000, interval = 100) {
    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`);
}
/**
 * Compare two objects deeply for equality
 *
 * @param a First object
 * @param b Second object
 * @returns True if objects are deeply equal
 */
function deepEqual(a, b) {
    if (a === b)
        return true;
    if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) {
        return false;
    }
    const keysA = Object.keys(a);
    const keysB = Object.keys(b);
    if (keysA.length !== keysB.length)
        return false;
    for (const key of keysA) {
        if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
            return false;
        }
    }
    return true;
}
//# sourceMappingURL=helpers.js.map