spanwright
Version:
CLI tool to generate Cloud Spanner E2E testing framework projects with Go database tools and Playwright browser automation
575 lines • 33.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const readline = __importStar(require("readline"));
const configuration_1 = require("../configuration");
const constants_1 = require("../constants");
const errors_1 = require("../errors");
const validation_1 = require("../validation");
// Mock the validation module
vitest_1.vi.mock('../validation', () => ({
validateDatabaseCount: vitest_1.vi.fn(),
validateSchemaPath: vitest_1.vi.fn(),
sanitizeInput: vitest_1.vi.fn((input) => input.trim()),
}));
// Mock readline module
vitest_1.vi.mock('readline', () => ({
createInterface: vitest_1.vi.fn(),
}));
(0, vitest_1.describe)('Configuration Module', () => {
let mockConsoleLog;
(0, vitest_1.beforeEach)(() => {
vitest_1.vi.clearAllMocks();
// Mock console methods after clearing
mockConsoleLog = vitest_1.vi.spyOn(console, 'log').mockImplementation(() => { });
// Reset environment variables
delete process.env[constants_1.ENV_VARS.DB_COUNT];
delete process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME];
delete process.env[constants_1.ENV_VARS.PRIMARY_SCHEMA_PATH];
delete process.env[constants_1.ENV_VARS.SECONDARY_DB_NAME];
delete process.env[constants_1.ENV_VARS.SECONDARY_SCHEMA_PATH];
});
(0, vitest_1.afterEach)(() => {
vitest_1.vi.restoreAllMocks();
});
(0, vitest_1.describe)('getConfiguration', () => {
(0, vitest_1.it)('should call getNonInteractiveConfiguration when isNonInteractive is true', async () => {
// Setup environment variables for non-interactive mode
process.env[constants_1.ENV_VARS.DB_COUNT] = '1';
process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME] = 'test-db';
process.env[constants_1.ENV_VARS.PRIMARY_SCHEMA_PATH] = '/path/to/schema';
// Mock validation to pass
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result).toEqual({
count: '1',
primaryDbName: 'test-db',
primarySchemaPath: '/path/to/schema',
secondaryDbName: undefined,
secondarySchemaPath: undefined,
});
(0, vitest_1.expect)(validation_1.validateDatabaseCount).toHaveBeenCalledWith('1');
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith('🤖 Non-interactive mode: Creating project with 1 database(s)');
});
(0, vitest_1.it)('should call getInteractiveConfiguration when isNonInteractive is false', async () => {
// Mock readline interface
const mockQuestion = vitest_1.vi.fn();
const mockClose = vitest_1.vi.fn();
const mockReadlineInterface = {
question: mockQuestion,
close: mockClose,
};
vitest_1.vi.mocked(readline.createInterface).mockReturnValue(mockReadlineInterface);
// Mock user inputs
mockQuestion
.mockImplementationOnce((query, callback) => {
callback('1');
})
.mockImplementationOnce((query, callback) => {
callback('test-db');
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/schema');
});
// Mock validation to pass
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(result).toEqual({
count: '1',
primaryDbName: 'test-db',
primarySchemaPath: '/path/to/schema',
});
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
});
(0, vitest_1.describe)('getNonInteractiveConfiguration', () => {
(0, vitest_1.it)('should use environment variables when provided', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '2';
process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME] = 'custom-primary';
process.env[constants_1.ENV_VARS.PRIMARY_SCHEMA_PATH] = '/custom/primary/schema';
process.env[constants_1.ENV_VARS.SECONDARY_DB_NAME] = 'custom-secondary';
process.env[constants_1.ENV_VARS.SECONDARY_SCHEMA_PATH] = '/custom/secondary/schema';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result).toEqual({
count: '2',
primaryDbName: 'custom-primary',
primarySchemaPath: '/custom/primary/schema',
secondaryDbName: 'custom-secondary',
secondarySchemaPath: '/custom/secondary/schema',
});
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith('🤖 Non-interactive mode: Creating project with 2 database(s)');
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith(' Primary DB: custom-primary (/custom/primary/schema)');
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith(' Secondary DB: custom-secondary (/custom/secondary/schema)');
});
(0, vitest_1.it)('should use default values when environment variables are not set', async () => {
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result).toEqual({
count: constants_1.DEFAULTS.DB_COUNT,
primaryDbName: constants_1.DEFAULTS.PRIMARY_DB_NAME,
primarySchemaPath: constants_1.DEFAULTS.PRIMARY_SCHEMA_PATH,
secondaryDbName: undefined,
secondarySchemaPath: undefined,
});
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith(`🤖 Non-interactive mode: Creating project with ${constants_1.DEFAULTS.DB_COUNT} database(s)`);
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith(` Primary DB: ${constants_1.DEFAULTS.PRIMARY_DB_NAME} (${constants_1.DEFAULTS.PRIMARY_SCHEMA_PATH})`);
});
(0, vitest_1.it)('should handle single database configuration', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '1';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result.count).toBe('1');
(0, vitest_1.expect)(result.secondaryDbName).toBeUndefined();
(0, vitest_1.expect)(result.secondarySchemaPath).toBeUndefined();
(0, vitest_1.expect)(mockConsoleLog).not.toHaveBeenCalledWith(vitest_1.expect.stringContaining('Secondary DB:'));
});
(0, vitest_1.it)('should handle dual database configuration', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '2';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result.count).toBe('2');
(0, vitest_1.expect)(result.secondaryDbName).toBe(constants_1.DEFAULTS.SECONDARY_DB_NAME);
(0, vitest_1.expect)(result.secondarySchemaPath).toBe(constants_1.DEFAULTS.SECONDARY_SCHEMA_PATH);
(0, vitest_1.expect)(mockConsoleLog).toHaveBeenCalledWith(vitest_1.expect.stringContaining('Secondary DB:'));
});
(0, vitest_1.it)('should throw ConfigurationError for invalid database count', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '3';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => {
throw new Error('Invalid count');
});
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(true)).rejects.toThrow(errors_1.ConfigurationError);
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(true)).rejects.toThrow(constants_1.MESSAGES.ERRORS.ENV_DB_COUNT_INVALID);
});
(0, vitest_1.it)('should validate database count', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '1';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(validation_1.validateDatabaseCount).toHaveBeenCalledWith('1');
});
});
(0, vitest_1.describe)('getInteractiveConfiguration', () => {
let mockQuestion;
let mockClose;
let mockReadlineInterface;
(0, vitest_1.beforeEach)(() => {
mockQuestion = vitest_1.vi.fn();
mockClose = vitest_1.vi.fn();
mockReadlineInterface = {
question: mockQuestion,
close: mockClose,
};
vitest_1.vi.mocked(readline.createInterface).mockReturnValue(mockReadlineInterface);
});
(0, vitest_1.it)('should handle single database configuration', async () => {
mockQuestion
.mockImplementationOnce((query, callback) => {
callback('1');
})
.mockImplementationOnce((query, callback) => {
callback('my-primary-db');
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/primary/schema');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(result).toEqual({
count: '1',
primaryDbName: 'my-primary-db',
primarySchemaPath: '/path/to/primary/schema',
});
(0, vitest_1.expect)(mockQuestion).toHaveBeenCalledTimes(3);
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
(0, vitest_1.it)('should handle dual database configuration', async () => {
mockQuestion
.mockImplementationOnce((query, callback) => {
callback('2');
})
.mockImplementationOnce((query, callback) => {
callback('my-primary-db');
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/primary/schema');
})
.mockImplementationOnce((query, callback) => {
callback('my-secondary-db');
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/secondary/schema');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(result).toEqual({
count: '2',
primaryDbName: 'my-primary-db',
primarySchemaPath: '/path/to/primary/schema',
secondaryDbName: 'my-secondary-db',
secondarySchemaPath: '/path/to/secondary/schema',
});
(0, vitest_1.expect)(mockQuestion).toHaveBeenCalledTimes(5);
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
(0, vitest_1.it)('should use default values for empty database names', async () => {
mockQuestion
.mockImplementationOnce((query, callback) => {
callback('2');
})
.mockImplementationOnce((query, callback) => {
callback(''); // Empty primary db name
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/primary/schema');
})
.mockImplementationOnce((query, callback) => {
callback(''); // Empty secondary db name
})
.mockImplementationOnce((query, callback) => {
callback('/path/to/secondary/schema');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(result.primaryDbName).toBe(constants_1.DEFAULTS.PRIMARY_DB_NAME);
(0, vitest_1.expect)(result.secondaryDbName).toBe(constants_1.DEFAULTS.SECONDARY_DB_NAME);
});
(0, vitest_1.it)('should throw ValidationError for invalid database count', async () => {
mockQuestion.mockImplementationOnce((query, callback) => {
callback('3');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => {
throw new errors_1.ValidationError('Invalid count', 'dbCount');
});
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(false)).rejects.toThrow(errors_1.ValidationError);
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
}, 10000);
(0, vitest_1.it)('should re-throw non-ValidationError exceptions', async () => {
mockQuestion
.mockImplementationOnce((query, callback) => {
callback('1');
})
.mockImplementationOnce((query, callback) => {
callback('my-db');
})
.mockImplementationOnce((query, callback) => {
callback('/some/path');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => {
throw new Error('Unexpected error');
});
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(false)).rejects.toThrow('Unexpected error');
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
(0, vitest_1.it)('should sanitize all user inputs', async () => {
mockQuestion
.mockImplementationOnce((query, callback) => {
callback(' 1 ');
})
.mockImplementationOnce((query, callback) => {
callback(' my-db ');
})
.mockImplementationOnce((query, callback) => {
callback(' /path/to/schema ');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.sanitizeInput).mockImplementation((input) => input.trim());
await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(validation_1.sanitizeInput).toHaveBeenCalledWith(' 1 ');
(0, vitest_1.expect)(validation_1.sanitizeInput).toHaveBeenCalledWith(' my-db ');
(0, vitest_1.expect)(validation_1.sanitizeInput).toHaveBeenCalledWith(' /path/to/schema ');
});
(0, vitest_1.it)('should always close readline interface even on error', async () => {
mockQuestion.mockImplementationOnce((query, callback) => {
callback('1');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => {
throw new Error('Validation failed');
});
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(false)).rejects.toThrow();
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
});
(0, vitest_1.describe)('generateEnvironmentContent', () => {
(0, vitest_1.it)('should generate environment content for single database configuration', () => {
const config = {
count: '1',
primaryDbName: 'test-primary',
primarySchemaPath: '/path/to/primary/schema',
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('DB_COUNT=1');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_ID=test-primary');
(0, vitest_1.expect)(result).toContain('PRIMARY_DATABASE_ID=test-primary');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_SCHEMA_PATH=/path/to/primary/schema');
(0, vitest_1.expect)(result).toContain('PRIMARY_SCHEMA_PATH=/path/to/primary/schema');
// Should not contain secondary database configuration
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DATABASE_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_SCHEMA_PATH');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_SCHEMA_PATH');
// Should contain default project settings
(0, vitest_1.expect)(result).toContain(`PROJECT_ID=${constants_1.DEFAULTS.PROJECT_ID}`);
(0, vitest_1.expect)(result).toContain(`INSTANCE_ID=${constants_1.DEFAULTS.INSTANCE_ID}`);
// Should contain default Docker settings
(0, vitest_1.expect)(result).toContain(`DOCKER_IMAGE=${constants_1.DEFAULTS.DOCKER_IMAGE}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_CONTAINER_NAME=${constants_1.DEFAULTS.CONTAINER_NAME}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_SPANNER_PORT=${constants_1.DEFAULTS.SPANNER_PORT}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_ADMIN_PORT=${constants_1.DEFAULTS.ADMIN_PORT}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_STARTUP_WAIT=${constants_1.DEFAULTS.STARTUP_WAIT}`);
});
(0, vitest_1.it)('should generate environment content for dual database configuration', () => {
const config = {
count: '2',
primaryDbName: 'test-primary',
primarySchemaPath: '/path/to/primary/schema',
secondaryDbName: 'test-secondary',
secondarySchemaPath: '/path/to/secondary/schema',
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('DB_COUNT=2');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_ID=test-primary');
(0, vitest_1.expect)(result).toContain('PRIMARY_DATABASE_ID=test-primary');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_SCHEMA_PATH=/path/to/primary/schema');
(0, vitest_1.expect)(result).toContain('PRIMARY_SCHEMA_PATH=/path/to/primary/schema');
// Should contain secondary database configuration
(0, vitest_1.expect)(result).toContain('SECONDARY_DB_ID=test-secondary');
(0, vitest_1.expect)(result).toContain('SECONDARY_DATABASE_ID=test-secondary');
(0, vitest_1.expect)(result).toContain('SECONDARY_DB_SCHEMA_PATH=/path/to/secondary/schema');
(0, vitest_1.expect)(result).toContain('SECONDARY_SCHEMA_PATH=/path/to/secondary/schema');
// Should contain default project settings
(0, vitest_1.expect)(result).toContain(`PROJECT_ID=${constants_1.DEFAULTS.PROJECT_ID}`);
(0, vitest_1.expect)(result).toContain(`INSTANCE_ID=${constants_1.DEFAULTS.INSTANCE_ID}`);
// Should contain default Docker settings
(0, vitest_1.expect)(result).toContain(`DOCKER_IMAGE=${constants_1.DEFAULTS.DOCKER_IMAGE}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_CONTAINER_NAME=${constants_1.DEFAULTS.CONTAINER_NAME}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_SPANNER_PORT=${constants_1.DEFAULTS.SPANNER_PORT}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_ADMIN_PORT=${constants_1.DEFAULTS.ADMIN_PORT}`);
(0, vitest_1.expect)(result).toContain(`DOCKER_STARTUP_WAIT=${constants_1.DEFAULTS.STARTUP_WAIT}`);
});
(0, vitest_1.it)('should not include secondary database configuration when count is 2 but secondary values are missing', () => {
const config = {
count: '2',
primaryDbName: 'test-primary',
primarySchemaPath: '/path/to/primary/schema',
// Missing secondaryDbName and secondarySchemaPath
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('DB_COUNT=2');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_ID=test-primary');
// Should not contain secondary database configuration
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DATABASE_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_SCHEMA_PATH');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_SCHEMA_PATH');
});
(0, vitest_1.it)('should not include secondary database configuration when count is 2 but secondaryDbName is missing', () => {
const config = {
count: '2',
primaryDbName: 'test-primary',
primarySchemaPath: '/path/to/primary/schema',
secondarySchemaPath: '/path/to/secondary/schema',
// Missing secondaryDbName
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('DB_COUNT=2');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DATABASE_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_SCHEMA_PATH');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_SCHEMA_PATH');
});
(0, vitest_1.it)('should not include secondary database configuration when count is 2 but secondarySchemaPath is missing', () => {
const config = {
count: '2',
primaryDbName: 'test-primary',
primarySchemaPath: '/path/to/primary/schema',
secondaryDbName: 'test-secondary',
// Missing secondarySchemaPath
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('DB_COUNT=2');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DATABASE_ID');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_DB_SCHEMA_PATH');
(0, vitest_1.expect)(result).not.toContain('SECONDARY_SCHEMA_PATH');
});
(0, vitest_1.it)('should include header comments', () => {
const config = {
count: '1',
primaryDbName: 'test-db',
primarySchemaPath: '/path/to/schema',
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('# ================================================');
(0, vitest_1.expect)(result).toContain('# Spanner E2E Testing Framework Configuration');
(0, vitest_1.expect)(result).toContain('# Copy this file to .env and adjust the settings');
(0, vitest_1.expect)(result).toContain('# ================================================');
(0, vitest_1.expect)(result).toContain('# 🔧 Database Settings');
(0, vitest_1.expect)(result).toContain('# 📊 Project Settings (usually no need to change)');
(0, vitest_1.expect)(result).toContain('# 🐳 Docker Settings (usually no need to change)');
});
(0, vitest_1.it)('should handle special characters in database names and paths', () => {
const config = {
count: '2',
primaryDbName: 'test-db_with-special.chars',
primarySchemaPath: '/path/to/schema with spaces',
secondaryDbName: 'secondary-db_with-special.chars',
secondarySchemaPath: '/path/to/secondary schema with spaces',
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_ID=test-db_with-special.chars');
(0, vitest_1.expect)(result).toContain('PRIMARY_DB_SCHEMA_PATH=/path/to/schema with spaces');
(0, vitest_1.expect)(result).toContain('SECONDARY_DB_ID=secondary-db_with-special.chars');
(0, vitest_1.expect)(result).toContain('SECONDARY_DB_SCHEMA_PATH=/path/to/secondary schema with spaces');
});
(0, vitest_1.it)('should maintain consistent formatting', () => {
const config = {
count: '1',
primaryDbName: 'test-db',
primarySchemaPath: '/path/to/schema',
};
const result = (0, configuration_1.generateEnvironmentContent)(config);
// Check that each section is properly separated
const sections = result.split('\n\n');
(0, vitest_1.expect)(sections.length).toBeGreaterThan(1);
// Check that variables are properly formatted (KEY=VALUE)
const lines = result.split('\n');
const variableLines = lines.filter(line => line.includes('=') && !line.startsWith('#'));
variableLines.forEach(line => {
(0, vitest_1.expect)(line).toMatch(/^[A-Z_]+=.+$/);
});
});
});
(0, vitest_1.describe)('PromptInterface', () => {
(0, vitest_1.it)('should create readline interface on construction', async () => {
const mockReadlineInterface = {
question: vitest_1.vi.fn((query, callback) => {
callback('1');
}),
close: vitest_1.vi.fn(),
};
vitest_1.vi.mocked(readline.createInterface).mockReturnValue(mockReadlineInterface);
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
// Trigger the creation of PromptInterface through interactive configuration
await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(readline.createInterface).toHaveBeenCalledWith({
input: process.stdin,
output: process.stdout,
});
});
(0, vitest_1.it)('should handle question method correctly', async () => {
const mockQuestion = vitest_1.vi.fn();
const mockClose = vitest_1.vi.fn();
const mockReadlineInterface = {
question: mockQuestion,
close: mockClose,
};
vitest_1.vi.mocked(readline.createInterface).mockReturnValue(mockReadlineInterface);
mockQuestion.mockImplementationOnce((query, callback) => {
(0, vitest_1.expect)(query).toBe('Select number of databases (1 or 2): ');
callback('1');
});
mockQuestion.mockImplementationOnce((query, callback) => {
(0, vitest_1.expect)(query).toBe('Primary DB name (default: primary-db): ');
callback('test-db');
});
mockQuestion.mockImplementationOnce((query, callback) => {
(0, vitest_1.expect)(query).toBe('Primary DB schema path: ');
callback('/path/to/schema');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
vitest_1.vi.mocked(validation_1.validateSchemaPath).mockImplementation(() => { });
await (0, configuration_1.getConfiguration)(false);
(0, vitest_1.expect)(mockQuestion).toHaveBeenCalledTimes(3);
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
(0, vitest_1.it)('should close readline interface properly', async () => {
const mockQuestion = vitest_1.vi.fn();
const mockClose = vitest_1.vi.fn();
const mockReadlineInterface = {
question: mockQuestion,
close: mockClose,
};
vitest_1.vi.mocked(readline.createInterface).mockReturnValue(mockReadlineInterface);
mockQuestion.mockImplementationOnce((query, callback) => {
callback('1');
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => {
throw new Error('Validation error');
});
await (0, vitest_1.expect)((0, configuration_1.getConfiguration)(false)).rejects.toThrow();
(0, vitest_1.expect)(mockClose).toHaveBeenCalled();
});
});
(0, vitest_1.describe)('Edge Cases and Error Handling', () => {
(0, vitest_1.it)('should handle empty string environment variables', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '';
process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME] = '';
process.env[constants_1.ENV_VARS.PRIMARY_SCHEMA_PATH] = '';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result.count).toBe(constants_1.DEFAULTS.DB_COUNT);
(0, vitest_1.expect)(result.primaryDbName).toBe(constants_1.DEFAULTS.PRIMARY_DB_NAME);
(0, vitest_1.expect)(result.primarySchemaPath).toBe(constants_1.DEFAULTS.PRIMARY_SCHEMA_PATH);
});
(0, vitest_1.it)('should handle undefined environment variables gracefully', async () => {
// Ensure all environment variables are undefined
Object.values(constants_1.ENV_VARS).forEach(envVar => {
delete process.env[envVar];
});
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
const result = await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(result.count).toBe(constants_1.DEFAULTS.DB_COUNT);
(0, vitest_1.expect)(result.primaryDbName).toBe(constants_1.DEFAULTS.PRIMARY_DB_NAME);
(0, vitest_1.expect)(result.primarySchemaPath).toBe(constants_1.DEFAULTS.PRIMARY_SCHEMA_PATH);
});
(0, vitest_1.it)('should preserve original process.env after configuration', async () => {
process.env[constants_1.ENV_VARS.DB_COUNT] = '1';
process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME] = 'test-db';
vitest_1.vi.mocked(validation_1.validateDatabaseCount).mockImplementation(() => { });
await (0, configuration_1.getConfiguration)(true);
(0, vitest_1.expect)(process.env[constants_1.ENV_VARS.DB_COUNT]).toBe('1');
(0, vitest_1.expect)(process.env[constants_1.ENV_VARS.PRIMARY_DB_NAME]).toBe('test-db');
});
});
});
//# sourceMappingURL=configuration.test.js.map