linxus fs fixes
This commit is contained in:
parent
ac23b70146
commit
0b7846fe67
292 changed files with 41947 additions and 41947 deletions
|
|
@ -1,183 +1,183 @@
|
|||
/**
|
||||
* Integration Test Setup
|
||||
*
|
||||
* Sets up test containers and real database instances for integration testing.
|
||||
* This file is executed before integration tests run.
|
||||
*/
|
||||
import { GenericContainer } from 'testcontainers';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
let questdbContainer;
|
||||
let postgresContainer;
|
||||
let mongoContainer;
|
||||
let mongoMemoryServer;
|
||||
/**
|
||||
* Global setup for integration tests
|
||||
* Starts real database containers for testing
|
||||
*/
|
||||
beforeAll(async () => {
|
||||
console.log('🚀 Starting integration test containers...');
|
||||
try {
|
||||
// Start QuestDB container
|
||||
console.log('📊 Starting QuestDB container...');
|
||||
questdbContainer = await new GenericContainer('questdb/questdb:7.3.10')
|
||||
.withExposedPorts(9000, 8812, 9009)
|
||||
.withEnvironment({
|
||||
'QDB_TELEMETRY_ENABLED': 'false',
|
||||
'QDB_LOG_LEVEL': 'ERROR'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Start PostgreSQL container
|
||||
console.log('🐘 Starting PostgreSQL container...');
|
||||
postgresContainer = await new GenericContainer('postgres:15-alpine')
|
||||
.withExposedPorts(5432)
|
||||
.withEnvironment({
|
||||
'POSTGRES_DB': 'trading_bot_test',
|
||||
'POSTGRES_USER': 'trading_admin',
|
||||
'POSTGRES_PASSWORD': 'trading_pass_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Start MongoDB container
|
||||
console.log('🍃 Starting MongoDB container...');
|
||||
mongoContainer = await new GenericContainer('mongo:7-jammy')
|
||||
.withExposedPorts(27017)
|
||||
.withEnvironment({
|
||||
'MONGO_INITDB_ROOT_USERNAME': 'trading_admin',
|
||||
'MONGO_INITDB_ROOT_PASSWORD': 'trading_mongo_test',
|
||||
'MONGO_INITDB_DATABASE': 'trading_bot_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Update environment variables for tests
|
||||
process.env.QUESTDB_HOST = questdbContainer.getHost();
|
||||
process.env.QUESTDB_HTTP_PORT = questdbContainer.getMappedPort(9000).toString();
|
||||
process.env.QUESTDB_PG_PORT = questdbContainer.getMappedPort(8812).toString();
|
||||
process.env.QUESTDB_INFLUX_PORT = questdbContainer.getMappedPort(9009).toString();
|
||||
process.env.POSTGRES_HOST = postgresContainer.getHost();
|
||||
process.env.POSTGRES_PORT = postgresContainer.getMappedPort(5432).toString();
|
||||
process.env.MONGODB_HOST = mongoContainer.getHost();
|
||||
process.env.MONGODB_PORT = mongoContainer.getMappedPort(27017).toString();
|
||||
console.log('✅ All containers started successfully!');
|
||||
console.log(`📊 QuestDB: http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`);
|
||||
console.log(`🐘 PostgreSQL: ${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}`);
|
||||
console.log(`🍃 MongoDB: ${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('❌ Failed to start test containers:', error);
|
||||
// Try to use MongoDB Memory Server as fallback
|
||||
console.log('🔄 Falling back to MongoDB Memory Server...');
|
||||
try {
|
||||
mongoMemoryServer = await MongoMemoryServer.create({
|
||||
instance: {
|
||||
dbName: 'trading_bot_test'
|
||||
}
|
||||
});
|
||||
const mongoUri = mongoMemoryServer.getUri();
|
||||
const mongoUrl = new URL(mongoUri);
|
||||
process.env.MONGODB_HOST = mongoUrl.hostname;
|
||||
process.env.MONGODB_PORT = mongoUrl.port;
|
||||
process.env.MONGODB_URI = mongoUri;
|
||||
console.log('✅ MongoDB Memory Server started as fallback');
|
||||
}
|
||||
catch (fallbackError) {
|
||||
console.error('❌ Failed to start MongoDB Memory Server:', fallbackError);
|
||||
throw fallbackError;
|
||||
}
|
||||
// For other databases, use localhost defaults if containers fail
|
||||
if (!questdbContainer) {
|
||||
console.log('⚠️ Using localhost QuestDB (ensure it\'s running)');
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
process.env.QUESTDB_INFLUX_PORT = '9009';
|
||||
}
|
||||
if (!postgresContainer) {
|
||||
console.log('⚠️ Using localhost PostgreSQL (ensure it\'s running)');
|
||||
process.env.POSTGRES_HOST = 'localhost';
|
||||
process.env.POSTGRES_PORT = '5432';
|
||||
}
|
||||
}
|
||||
}, 120000); // 2 minutes timeout for container startup
|
||||
/**
|
||||
* Global cleanup for integration tests
|
||||
* Stops all test containers
|
||||
*/
|
||||
afterAll(async () => {
|
||||
console.log('🧹 Cleaning up integration test containers...');
|
||||
const cleanup = async (container, name) => {
|
||||
if (container) {
|
||||
try {
|
||||
await container.stop();
|
||||
console.log(`✅ ${name} container stopped`);
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(`⚠️ Failed to stop ${name} container:`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
await Promise.all([
|
||||
cleanup(questdbContainer, 'QuestDB'),
|
||||
cleanup(postgresContainer, 'PostgreSQL'),
|
||||
cleanup(mongoContainer, 'MongoDB')
|
||||
]);
|
||||
if (mongoMemoryServer) {
|
||||
try {
|
||||
await mongoMemoryServer.stop();
|
||||
console.log('✅ MongoDB Memory Server stopped');
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('⚠️ Failed to stop MongoDB Memory Server:', error);
|
||||
}
|
||||
}
|
||||
console.log('🎉 Integration test cleanup complete!');
|
||||
}, 30000);
|
||||
/**
|
||||
* Wait for database services to be ready
|
||||
*/
|
||||
export const waitForServices = async (timeout = 30000) => {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
try {
|
||||
// Check if QuestDB HTTP interface is ready
|
||||
const questdbUrl = `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}/status`;
|
||||
const response = await fetch(questdbUrl);
|
||||
if (response.ok) {
|
||||
console.log('✅ QuestDB is ready');
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
// Service not ready yet, continue waiting
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
throw new Error('Services did not become ready within timeout');
|
||||
};
|
||||
/**
|
||||
* Test utilities for integration tests
|
||||
*/
|
||||
export const integrationTestHelpers = {
|
||||
/**
|
||||
* Get QuestDB HTTP URL
|
||||
*/
|
||||
getQuestDBUrl: () => `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`,
|
||||
/**
|
||||
* Get PostgreSQL connection string
|
||||
*/
|
||||
getPostgresUrl: () => `postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}`,
|
||||
/**
|
||||
* Get MongoDB connection string
|
||||
*/
|
||||
getMongoUrl: () => {
|
||||
if (process.env.MONGODB_URI) {
|
||||
return process.env.MONGODB_URI;
|
||||
}
|
||||
return `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DATABASE}`;
|
||||
},
|
||||
/**
|
||||
* Wait for services to be ready
|
||||
*/
|
||||
waitForServices
|
||||
};
|
||||
/**
|
||||
* Integration Test Setup
|
||||
*
|
||||
* Sets up test containers and real database instances for integration testing.
|
||||
* This file is executed before integration tests run.
|
||||
*/
|
||||
import { GenericContainer } from 'testcontainers';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
let questdbContainer;
|
||||
let postgresContainer;
|
||||
let mongoContainer;
|
||||
let mongoMemoryServer;
|
||||
/**
|
||||
* Global setup for integration tests
|
||||
* Starts real database containers for testing
|
||||
*/
|
||||
beforeAll(async () => {
|
||||
console.log('🚀 Starting integration test containers...');
|
||||
try {
|
||||
// Start QuestDB container
|
||||
console.log('📊 Starting QuestDB container...');
|
||||
questdbContainer = await new GenericContainer('questdb/questdb:7.3.10')
|
||||
.withExposedPorts(9000, 8812, 9009)
|
||||
.withEnvironment({
|
||||
'QDB_TELEMETRY_ENABLED': 'false',
|
||||
'QDB_LOG_LEVEL': 'ERROR'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Start PostgreSQL container
|
||||
console.log('🐘 Starting PostgreSQL container...');
|
||||
postgresContainer = await new GenericContainer('postgres:15-alpine')
|
||||
.withExposedPorts(5432)
|
||||
.withEnvironment({
|
||||
'POSTGRES_DB': 'trading_bot_test',
|
||||
'POSTGRES_USER': 'trading_admin',
|
||||
'POSTGRES_PASSWORD': 'trading_pass_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Start MongoDB container
|
||||
console.log('🍃 Starting MongoDB container...');
|
||||
mongoContainer = await new GenericContainer('mongo:7-jammy')
|
||||
.withExposedPorts(27017)
|
||||
.withEnvironment({
|
||||
'MONGO_INITDB_ROOT_USERNAME': 'trading_admin',
|
||||
'MONGO_INITDB_ROOT_PASSWORD': 'trading_mongo_test',
|
||||
'MONGO_INITDB_DATABASE': 'trading_bot_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
// Update environment variables for tests
|
||||
process.env.QUESTDB_HOST = questdbContainer.getHost();
|
||||
process.env.QUESTDB_HTTP_PORT = questdbContainer.getMappedPort(9000).toString();
|
||||
process.env.QUESTDB_PG_PORT = questdbContainer.getMappedPort(8812).toString();
|
||||
process.env.QUESTDB_INFLUX_PORT = questdbContainer.getMappedPort(9009).toString();
|
||||
process.env.POSTGRES_HOST = postgresContainer.getHost();
|
||||
process.env.POSTGRES_PORT = postgresContainer.getMappedPort(5432).toString();
|
||||
process.env.MONGODB_HOST = mongoContainer.getHost();
|
||||
process.env.MONGODB_PORT = mongoContainer.getMappedPort(27017).toString();
|
||||
console.log('✅ All containers started successfully!');
|
||||
console.log(`📊 QuestDB: http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`);
|
||||
console.log(`🐘 PostgreSQL: ${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}`);
|
||||
console.log(`🍃 MongoDB: ${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}`);
|
||||
}
|
||||
catch (error) {
|
||||
console.error('❌ Failed to start test containers:', error);
|
||||
// Try to use MongoDB Memory Server as fallback
|
||||
console.log('🔄 Falling back to MongoDB Memory Server...');
|
||||
try {
|
||||
mongoMemoryServer = await MongoMemoryServer.create({
|
||||
instance: {
|
||||
dbName: 'trading_bot_test'
|
||||
}
|
||||
});
|
||||
const mongoUri = mongoMemoryServer.getUri();
|
||||
const mongoUrl = new URL(mongoUri);
|
||||
process.env.MONGODB_HOST = mongoUrl.hostname;
|
||||
process.env.MONGODB_PORT = mongoUrl.port;
|
||||
process.env.MONGODB_URI = mongoUri;
|
||||
console.log('✅ MongoDB Memory Server started as fallback');
|
||||
}
|
||||
catch (fallbackError) {
|
||||
console.error('❌ Failed to start MongoDB Memory Server:', fallbackError);
|
||||
throw fallbackError;
|
||||
}
|
||||
// For other databases, use localhost defaults if containers fail
|
||||
if (!questdbContainer) {
|
||||
console.log('⚠️ Using localhost QuestDB (ensure it\'s running)');
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
process.env.QUESTDB_INFLUX_PORT = '9009';
|
||||
}
|
||||
if (!postgresContainer) {
|
||||
console.log('⚠️ Using localhost PostgreSQL (ensure it\'s running)');
|
||||
process.env.POSTGRES_HOST = 'localhost';
|
||||
process.env.POSTGRES_PORT = '5432';
|
||||
}
|
||||
}
|
||||
}, 120000); // 2 minutes timeout for container startup
|
||||
/**
|
||||
* Global cleanup for integration tests
|
||||
* Stops all test containers
|
||||
*/
|
||||
afterAll(async () => {
|
||||
console.log('🧹 Cleaning up integration test containers...');
|
||||
const cleanup = async (container, name) => {
|
||||
if (container) {
|
||||
try {
|
||||
await container.stop();
|
||||
console.log(`✅ ${name} container stopped`);
|
||||
}
|
||||
catch (error) {
|
||||
console.warn(`⚠️ Failed to stop ${name} container:`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
await Promise.all([
|
||||
cleanup(questdbContainer, 'QuestDB'),
|
||||
cleanup(postgresContainer, 'PostgreSQL'),
|
||||
cleanup(mongoContainer, 'MongoDB')
|
||||
]);
|
||||
if (mongoMemoryServer) {
|
||||
try {
|
||||
await mongoMemoryServer.stop();
|
||||
console.log('✅ MongoDB Memory Server stopped');
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('⚠️ Failed to stop MongoDB Memory Server:', error);
|
||||
}
|
||||
}
|
||||
console.log('🎉 Integration test cleanup complete!');
|
||||
}, 30000);
|
||||
/**
|
||||
* Wait for database services to be ready
|
||||
*/
|
||||
export const waitForServices = async (timeout = 30000) => {
|
||||
const start = Date.now();
|
||||
while (Date.now() - start < timeout) {
|
||||
try {
|
||||
// Check if QuestDB HTTP interface is ready
|
||||
const questdbUrl = `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}/status`;
|
||||
const response = await fetch(questdbUrl);
|
||||
if (response.ok) {
|
||||
console.log('✅ QuestDB is ready');
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
// Service not ready yet, continue waiting
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
throw new Error('Services did not become ready within timeout');
|
||||
};
|
||||
/**
|
||||
* Test utilities for integration tests
|
||||
*/
|
||||
export const integrationTestHelpers = {
|
||||
/**
|
||||
* Get QuestDB HTTP URL
|
||||
*/
|
||||
getQuestDBUrl: () => `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`,
|
||||
/**
|
||||
* Get PostgreSQL connection string
|
||||
*/
|
||||
getPostgresUrl: () => `postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}`,
|
||||
/**
|
||||
* Get MongoDB connection string
|
||||
*/
|
||||
getMongoUrl: () => {
|
||||
if (process.env.MONGODB_URI) {
|
||||
return process.env.MONGODB_URI;
|
||||
}
|
||||
return `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DATABASE}`;
|
||||
},
|
||||
/**
|
||||
* Wait for services to be ready
|
||||
*/
|
||||
waitForServices
|
||||
};
|
||||
//# sourceMappingURL=setup.js.map
|
||||
|
|
@ -1,208 +1,208 @@
|
|||
/**
|
||||
* Integration Test Setup
|
||||
*
|
||||
* Sets up test containers and real database instances for integration testing.
|
||||
* This file is executed before integration tests run.
|
||||
*/
|
||||
|
||||
import { GenericContainer, StartedTestContainer } from 'testcontainers';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
|
||||
let questdbContainer: StartedTestContainer;
|
||||
let postgresContainer: StartedTestContainer;
|
||||
let mongoContainer: StartedTestContainer;
|
||||
let mongoMemoryServer: MongoMemoryServer;
|
||||
|
||||
/**
|
||||
* Global setup for integration tests
|
||||
* Starts real database containers for testing
|
||||
*/
|
||||
beforeAll(async () => {
|
||||
console.log('🚀 Starting integration test containers...');
|
||||
|
||||
try {
|
||||
// Start QuestDB container
|
||||
console.log('📊 Starting QuestDB container...');
|
||||
questdbContainer = await new GenericContainer('questdb/questdb:7.3.10')
|
||||
.withExposedPorts(9000, 8812, 9009)
|
||||
.withEnvironment({
|
||||
'QDB_TELEMETRY_ENABLED': 'false',
|
||||
'QDB_LOG_LEVEL': 'ERROR'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Start PostgreSQL container
|
||||
console.log('🐘 Starting PostgreSQL container...');
|
||||
postgresContainer = await new GenericContainer('postgres:15-alpine')
|
||||
.withExposedPorts(5432)
|
||||
.withEnvironment({
|
||||
'POSTGRES_DB': 'trading_bot_test',
|
||||
'POSTGRES_USER': 'trading_admin',
|
||||
'POSTGRES_PASSWORD': 'trading_pass_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Start MongoDB container
|
||||
console.log('🍃 Starting MongoDB container...');
|
||||
mongoContainer = await new GenericContainer('mongo:7-jammy')
|
||||
.withExposedPorts(27017)
|
||||
.withEnvironment({
|
||||
'MONGO_INITDB_ROOT_USERNAME': 'trading_admin',
|
||||
'MONGO_INITDB_ROOT_PASSWORD': 'trading_mongo_test',
|
||||
'MONGO_INITDB_DATABASE': 'trading_bot_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Update environment variables for tests
|
||||
process.env.QUESTDB_HOST = questdbContainer.getHost();
|
||||
process.env.QUESTDB_HTTP_PORT = questdbContainer.getMappedPort(9000).toString();
|
||||
process.env.QUESTDB_PG_PORT = questdbContainer.getMappedPort(8812).toString();
|
||||
process.env.QUESTDB_INFLUX_PORT = questdbContainer.getMappedPort(9009).toString();
|
||||
|
||||
process.env.POSTGRES_HOST = postgresContainer.getHost();
|
||||
process.env.POSTGRES_PORT = postgresContainer.getMappedPort(5432).toString();
|
||||
|
||||
process.env.MONGODB_HOST = mongoContainer.getHost();
|
||||
process.env.MONGODB_PORT = mongoContainer.getMappedPort(27017).toString();
|
||||
|
||||
console.log('✅ All containers started successfully!');
|
||||
console.log(`📊 QuestDB: http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`);
|
||||
console.log(`🐘 PostgreSQL: ${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}`);
|
||||
console.log(`🍃 MongoDB: ${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to start test containers:', error);
|
||||
|
||||
// Try to use MongoDB Memory Server as fallback
|
||||
console.log('🔄 Falling back to MongoDB Memory Server...');
|
||||
try {
|
||||
mongoMemoryServer = await MongoMemoryServer.create({
|
||||
instance: {
|
||||
dbName: 'trading_bot_test'
|
||||
}
|
||||
});
|
||||
|
||||
const mongoUri = mongoMemoryServer.getUri();
|
||||
const mongoUrl = new URL(mongoUri);
|
||||
process.env.MONGODB_HOST = mongoUrl.hostname;
|
||||
process.env.MONGODB_PORT = mongoUrl.port;
|
||||
process.env.MONGODB_URI = mongoUri;
|
||||
|
||||
console.log('✅ MongoDB Memory Server started as fallback');
|
||||
} catch (fallbackError) {
|
||||
console.error('❌ Failed to start MongoDB Memory Server:', fallbackError);
|
||||
throw fallbackError;
|
||||
}
|
||||
|
||||
// For other databases, use localhost defaults if containers fail
|
||||
if (!questdbContainer) {
|
||||
console.log('⚠️ Using localhost QuestDB (ensure it\'s running)');
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
process.env.QUESTDB_INFLUX_PORT = '9009';
|
||||
}
|
||||
|
||||
if (!postgresContainer) {
|
||||
console.log('⚠️ Using localhost PostgreSQL (ensure it\'s running)');
|
||||
process.env.POSTGRES_HOST = 'localhost';
|
||||
process.env.POSTGRES_PORT = '5432';
|
||||
}
|
||||
}
|
||||
}, 120000); // 2 minutes timeout for container startup
|
||||
|
||||
/**
|
||||
* Global cleanup for integration tests
|
||||
* Stops all test containers
|
||||
*/
|
||||
afterAll(async () => {
|
||||
console.log('🧹 Cleaning up integration test containers...');
|
||||
|
||||
const cleanup = async (container: StartedTestContainer | undefined, name: string) => {
|
||||
if (container) {
|
||||
try {
|
||||
await container.stop();
|
||||
console.log(`✅ ${name} container stopped`);
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ Failed to stop ${name} container:`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
cleanup(questdbContainer, 'QuestDB'),
|
||||
cleanup(postgresContainer, 'PostgreSQL'),
|
||||
cleanup(mongoContainer, 'MongoDB')
|
||||
]);
|
||||
|
||||
if (mongoMemoryServer) {
|
||||
try {
|
||||
await mongoMemoryServer.stop();
|
||||
console.log('✅ MongoDB Memory Server stopped');
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Failed to stop MongoDB Memory Server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 Integration test cleanup complete!');
|
||||
}, 30000);
|
||||
|
||||
/**
|
||||
* Wait for database services to be ready
|
||||
*/
|
||||
export const waitForServices = async (timeout: number = 30000): Promise<void> => {
|
||||
const start = Date.now();
|
||||
|
||||
while (Date.now() - start < timeout) {
|
||||
try {
|
||||
// Check if QuestDB HTTP interface is ready
|
||||
const questdbUrl = `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}/status`;
|
||||
const response = await fetch(questdbUrl);
|
||||
|
||||
if (response.ok) {
|
||||
console.log('✅ QuestDB is ready');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// Service not ready yet, continue waiting
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
throw new Error('Services did not become ready within timeout');
|
||||
};
|
||||
|
||||
/**
|
||||
* Test utilities for integration tests
|
||||
*/
|
||||
export const integrationTestHelpers = {
|
||||
/**
|
||||
* Get QuestDB HTTP URL
|
||||
*/
|
||||
getQuestDBUrl: () => `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`,
|
||||
|
||||
/**
|
||||
* Get PostgreSQL connection string
|
||||
*/
|
||||
getPostgresUrl: () =>
|
||||
`postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}`,
|
||||
|
||||
/**
|
||||
* Get MongoDB connection string
|
||||
*/
|
||||
getMongoUrl: () => {
|
||||
if (process.env.MONGODB_URI) {
|
||||
return process.env.MONGODB_URI;
|
||||
}
|
||||
return `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DATABASE}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for services to be ready
|
||||
*/
|
||||
waitForServices
|
||||
};
|
||||
/**
|
||||
* Integration Test Setup
|
||||
*
|
||||
* Sets up test containers and real database instances for integration testing.
|
||||
* This file is executed before integration tests run.
|
||||
*/
|
||||
|
||||
import { GenericContainer, StartedTestContainer } from 'testcontainers';
|
||||
import { MongoMemoryServer } from 'mongodb-memory-server';
|
||||
|
||||
let questdbContainer: StartedTestContainer;
|
||||
let postgresContainer: StartedTestContainer;
|
||||
let mongoContainer: StartedTestContainer;
|
||||
let mongoMemoryServer: MongoMemoryServer;
|
||||
|
||||
/**
|
||||
* Global setup for integration tests
|
||||
* Starts real database containers for testing
|
||||
*/
|
||||
beforeAll(async () => {
|
||||
console.log('🚀 Starting integration test containers...');
|
||||
|
||||
try {
|
||||
// Start QuestDB container
|
||||
console.log('📊 Starting QuestDB container...');
|
||||
questdbContainer = await new GenericContainer('questdb/questdb:7.3.10')
|
||||
.withExposedPorts(9000, 8812, 9009)
|
||||
.withEnvironment({
|
||||
'QDB_TELEMETRY_ENABLED': 'false',
|
||||
'QDB_LOG_LEVEL': 'ERROR'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Start PostgreSQL container
|
||||
console.log('🐘 Starting PostgreSQL container...');
|
||||
postgresContainer = await new GenericContainer('postgres:15-alpine')
|
||||
.withExposedPorts(5432)
|
||||
.withEnvironment({
|
||||
'POSTGRES_DB': 'trading_bot_test',
|
||||
'POSTGRES_USER': 'trading_admin',
|
||||
'POSTGRES_PASSWORD': 'trading_pass_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Start MongoDB container
|
||||
console.log('🍃 Starting MongoDB container...');
|
||||
mongoContainer = await new GenericContainer('mongo:7-jammy')
|
||||
.withExposedPorts(27017)
|
||||
.withEnvironment({
|
||||
'MONGO_INITDB_ROOT_USERNAME': 'trading_admin',
|
||||
'MONGO_INITDB_ROOT_PASSWORD': 'trading_mongo_test',
|
||||
'MONGO_INITDB_DATABASE': 'trading_bot_test'
|
||||
})
|
||||
.withStartupTimeout(60000)
|
||||
.start();
|
||||
|
||||
// Update environment variables for tests
|
||||
process.env.QUESTDB_HOST = questdbContainer.getHost();
|
||||
process.env.QUESTDB_HTTP_PORT = questdbContainer.getMappedPort(9000).toString();
|
||||
process.env.QUESTDB_PG_PORT = questdbContainer.getMappedPort(8812).toString();
|
||||
process.env.QUESTDB_INFLUX_PORT = questdbContainer.getMappedPort(9009).toString();
|
||||
|
||||
process.env.POSTGRES_HOST = postgresContainer.getHost();
|
||||
process.env.POSTGRES_PORT = postgresContainer.getMappedPort(5432).toString();
|
||||
|
||||
process.env.MONGODB_HOST = mongoContainer.getHost();
|
||||
process.env.MONGODB_PORT = mongoContainer.getMappedPort(27017).toString();
|
||||
|
||||
console.log('✅ All containers started successfully!');
|
||||
console.log(`📊 QuestDB: http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`);
|
||||
console.log(`🐘 PostgreSQL: ${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}`);
|
||||
console.log(`🍃 MongoDB: ${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}`);
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to start test containers:', error);
|
||||
|
||||
// Try to use MongoDB Memory Server as fallback
|
||||
console.log('🔄 Falling back to MongoDB Memory Server...');
|
||||
try {
|
||||
mongoMemoryServer = await MongoMemoryServer.create({
|
||||
instance: {
|
||||
dbName: 'trading_bot_test'
|
||||
}
|
||||
});
|
||||
|
||||
const mongoUri = mongoMemoryServer.getUri();
|
||||
const mongoUrl = new URL(mongoUri);
|
||||
process.env.MONGODB_HOST = mongoUrl.hostname;
|
||||
process.env.MONGODB_PORT = mongoUrl.port;
|
||||
process.env.MONGODB_URI = mongoUri;
|
||||
|
||||
console.log('✅ MongoDB Memory Server started as fallback');
|
||||
} catch (fallbackError) {
|
||||
console.error('❌ Failed to start MongoDB Memory Server:', fallbackError);
|
||||
throw fallbackError;
|
||||
}
|
||||
|
||||
// For other databases, use localhost defaults if containers fail
|
||||
if (!questdbContainer) {
|
||||
console.log('⚠️ Using localhost QuestDB (ensure it\'s running)');
|
||||
process.env.QUESTDB_HOST = 'localhost';
|
||||
process.env.QUESTDB_HTTP_PORT = '9000';
|
||||
process.env.QUESTDB_PG_PORT = '8812';
|
||||
process.env.QUESTDB_INFLUX_PORT = '9009';
|
||||
}
|
||||
|
||||
if (!postgresContainer) {
|
||||
console.log('⚠️ Using localhost PostgreSQL (ensure it\'s running)');
|
||||
process.env.POSTGRES_HOST = 'localhost';
|
||||
process.env.POSTGRES_PORT = '5432';
|
||||
}
|
||||
}
|
||||
}, 120000); // 2 minutes timeout for container startup
|
||||
|
||||
/**
|
||||
* Global cleanup for integration tests
|
||||
* Stops all test containers
|
||||
*/
|
||||
afterAll(async () => {
|
||||
console.log('🧹 Cleaning up integration test containers...');
|
||||
|
||||
const cleanup = async (container: StartedTestContainer | undefined, name: string) => {
|
||||
if (container) {
|
||||
try {
|
||||
await container.stop();
|
||||
console.log(`✅ ${name} container stopped`);
|
||||
} catch (error) {
|
||||
console.warn(`⚠️ Failed to stop ${name} container:`, error);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await Promise.all([
|
||||
cleanup(questdbContainer, 'QuestDB'),
|
||||
cleanup(postgresContainer, 'PostgreSQL'),
|
||||
cleanup(mongoContainer, 'MongoDB')
|
||||
]);
|
||||
|
||||
if (mongoMemoryServer) {
|
||||
try {
|
||||
await mongoMemoryServer.stop();
|
||||
console.log('✅ MongoDB Memory Server stopped');
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Failed to stop MongoDB Memory Server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('🎉 Integration test cleanup complete!');
|
||||
}, 30000);
|
||||
|
||||
/**
|
||||
* Wait for database services to be ready
|
||||
*/
|
||||
export const waitForServices = async (timeout: number = 30000): Promise<void> => {
|
||||
const start = Date.now();
|
||||
|
||||
while (Date.now() - start < timeout) {
|
||||
try {
|
||||
// Check if QuestDB HTTP interface is ready
|
||||
const questdbUrl = `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}/status`;
|
||||
const response = await fetch(questdbUrl);
|
||||
|
||||
if (response.ok) {
|
||||
console.log('✅ QuestDB is ready');
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
// Service not ready yet, continue waiting
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
}
|
||||
|
||||
throw new Error('Services did not become ready within timeout');
|
||||
};
|
||||
|
||||
/**
|
||||
* Test utilities for integration tests
|
||||
*/
|
||||
export const integrationTestHelpers = {
|
||||
/**
|
||||
* Get QuestDB HTTP URL
|
||||
*/
|
||||
getQuestDBUrl: () => `http://${process.env.QUESTDB_HOST}:${process.env.QUESTDB_HTTP_PORT}`,
|
||||
|
||||
/**
|
||||
* Get PostgreSQL connection string
|
||||
*/
|
||||
getPostgresUrl: () =>
|
||||
`postgresql://${process.env.POSTGRES_USER}:${process.env.POSTGRES_PASSWORD}@${process.env.POSTGRES_HOST}:${process.env.POSTGRES_PORT}/${process.env.POSTGRES_DB}`,
|
||||
|
||||
/**
|
||||
* Get MongoDB connection string
|
||||
*/
|
||||
getMongoUrl: () => {
|
||||
if (process.env.MONGODB_URI) {
|
||||
return process.env.MONGODB_URI;
|
||||
}
|
||||
return `mongodb://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASSWORD}@${process.env.MONGODB_HOST}:${process.env.MONGODB_PORT}/${process.env.MONGODB_DATABASE}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* Wait for services to be ready
|
||||
*/
|
||||
waitForServices
|
||||
};
|
||||
|
|
|
|||
222
test/setup.js
222
test/setup.js
|
|
@ -1,112 +1,112 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Bun Test Setup File for Stock Bot Trading Platform
|
||||
*
|
||||
* Global test configuration and utilities available across all tests.
|
||||
* This file is executed before each test via bunfig.toml preload.
|
||||
*/
|
||||
// Increase test timeout if needed (already configured in bunfig.toml)
|
||||
// Bun.timeout = 30000;
|
||||
// Store original console methods to allow restoration
|
||||
const originalConsole = global.console;
|
||||
// Mock console methods to reduce noise during tests
|
||||
// These can be restored with testHelpers.restoreConsole()
|
||||
console.log = () => { };
|
||||
console.debug = () => { };
|
||||
console.info = () => { };
|
||||
console.warn = () => { };
|
||||
console.error = () => { };
|
||||
global.testHelpers = {
|
||||
/**
|
||||
* Sleep utility for async tests
|
||||
*/
|
||||
sleep: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
|
||||
/**
|
||||
* Consistent mock timestamp for tests
|
||||
*/
|
||||
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
|
||||
/**
|
||||
* Generate test OHLCV data
|
||||
*/
|
||||
generateTestOHLCV: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
open: 150.0,
|
||||
high: 153.0,
|
||||
low: 149.0,
|
||||
close: 152.5,
|
||||
volume: 10000,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Generate test trade data
|
||||
*/
|
||||
generateTestTrade: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
price: 152.5,
|
||||
size: 100,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
exchange: 'NASDAQ',
|
||||
conditions: ['@', 'T'],
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Generate test quote data
|
||||
*/
|
||||
generateTestQuote: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
bidPrice: 152.45,
|
||||
bidSize: 200,
|
||||
askPrice: 152.55,
|
||||
askSize: 150,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Create a mock logger
|
||||
*/
|
||||
mockLogger: () => ({
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
warn: () => { },
|
||||
error: () => { },
|
||||
critical: () => { },
|
||||
}),
|
||||
/**
|
||||
* Restore console methods
|
||||
*/
|
||||
restoreConsole: () => {
|
||||
global.console = originalConsole;
|
||||
}
|
||||
};
|
||||
// Set up spyOn utilities
|
||||
// Similar to jest.spyOn but using Bun's built-in spy functionality
|
||||
// This makes it easier to migrate from Jest
|
||||
global.spyOn = function (object, method) {
|
||||
const original = object[method];
|
||||
const mock = function (...args) {
|
||||
mock.mock.calls.push(args);
|
||||
return mock.mockImplementation ? mock.mockImplementation(...args) : original.apply(object, args);
|
||||
};
|
||||
mock.mock = { calls: [] };
|
||||
mock.mockClear = () => { mock.mock.calls = []; return mock; };
|
||||
mock.mockReset = () => {
|
||||
mock.mock.calls = [];
|
||||
mock.mockImplementation = null;
|
||||
return mock;
|
||||
};
|
||||
mock.mockImplementation = null;
|
||||
mock.mockReturnValue = (value) => {
|
||||
mock.mockImplementation = () => value;
|
||||
return mock;
|
||||
};
|
||||
mock.mockResolvedValue = (value) => {
|
||||
return mock.mockReturnValue(Promise.resolve(value));
|
||||
};
|
||||
mock.mockRejectedValue = (value) => {
|
||||
return mock.mockReturnValue(Promise.reject(value));
|
||||
};
|
||||
object[method] = mock;
|
||||
return mock;
|
||||
};
|
||||
"use strict";
|
||||
/**
|
||||
* Bun Test Setup File for Stock Bot Trading Platform
|
||||
*
|
||||
* Global test configuration and utilities available across all tests.
|
||||
* This file is executed before each test via bunfig.toml preload.
|
||||
*/
|
||||
// Increase test timeout if needed (already configured in bunfig.toml)
|
||||
// Bun.timeout = 30000;
|
||||
// Store original console methods to allow restoration
|
||||
const originalConsole = global.console;
|
||||
// Mock console methods to reduce noise during tests
|
||||
// These can be restored with testHelpers.restoreConsole()
|
||||
console.log = () => { };
|
||||
console.debug = () => { };
|
||||
console.info = () => { };
|
||||
console.warn = () => { };
|
||||
console.error = () => { };
|
||||
global.testHelpers = {
|
||||
/**
|
||||
* Sleep utility for async tests
|
||||
*/
|
||||
sleep: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
|
||||
/**
|
||||
* Consistent mock timestamp for tests
|
||||
*/
|
||||
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
|
||||
/**
|
||||
* Generate test OHLCV data
|
||||
*/
|
||||
generateTestOHLCV: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
open: 150.0,
|
||||
high: 153.0,
|
||||
low: 149.0,
|
||||
close: 152.5,
|
||||
volume: 10000,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Generate test trade data
|
||||
*/
|
||||
generateTestTrade: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
price: 152.5,
|
||||
size: 100,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
exchange: 'NASDAQ',
|
||||
conditions: ['@', 'T'],
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Generate test quote data
|
||||
*/
|
||||
generateTestQuote: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
bidPrice: 152.45,
|
||||
bidSize: 200,
|
||||
askPrice: 152.55,
|
||||
askSize: 150,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
/**
|
||||
* Create a mock logger
|
||||
*/
|
||||
mockLogger: () => ({
|
||||
debug: () => { },
|
||||
info: () => { },
|
||||
warn: () => { },
|
||||
error: () => { },
|
||||
critical: () => { },
|
||||
}),
|
||||
/**
|
||||
* Restore console methods
|
||||
*/
|
||||
restoreConsole: () => {
|
||||
global.console = originalConsole;
|
||||
}
|
||||
};
|
||||
// Set up spyOn utilities
|
||||
// Similar to jest.spyOn but using Bun's built-in spy functionality
|
||||
// This makes it easier to migrate from Jest
|
||||
global.spyOn = function (object, method) {
|
||||
const original = object[method];
|
||||
const mock = function (...args) {
|
||||
mock.mock.calls.push(args);
|
||||
return mock.mockImplementation ? mock.mockImplementation(...args) : original.apply(object, args);
|
||||
};
|
||||
mock.mock = { calls: [] };
|
||||
mock.mockClear = () => { mock.mock.calls = []; return mock; };
|
||||
mock.mockReset = () => {
|
||||
mock.mock.calls = [];
|
||||
mock.mockImplementation = null;
|
||||
return mock;
|
||||
};
|
||||
mock.mockImplementation = null;
|
||||
mock.mockReturnValue = (value) => {
|
||||
mock.mockImplementation = () => value;
|
||||
return mock;
|
||||
};
|
||||
mock.mockResolvedValue = (value) => {
|
||||
return mock.mockReturnValue(Promise.resolve(value));
|
||||
};
|
||||
mock.mockRejectedValue = (value) => {
|
||||
return mock.mockReturnValue(Promise.reject(value));
|
||||
};
|
||||
object[method] = mock;
|
||||
return mock;
|
||||
};
|
||||
//# sourceMappingURL=setup.js.map
|
||||
272
test/setup.ts
272
test/setup.ts
|
|
@ -1,136 +1,136 @@
|
|||
/**
|
||||
* Bun Test Setup File for Stock Bot Trading Platform
|
||||
*
|
||||
* Global test configuration and utilities available across all tests.
|
||||
* This file is executed before each test via bunfig.toml preload.
|
||||
*/
|
||||
|
||||
// Increase test timeout if needed (already configured in bunfig.toml)
|
||||
// Bun.timeout = 30000;
|
||||
|
||||
// Store original console methods to allow restoration
|
||||
const originalConsole = global.console;
|
||||
|
||||
// Mock console methods to reduce noise during tests
|
||||
// These can be restored with testHelpers.restoreConsole()
|
||||
console.log = () => {};
|
||||
console.debug = () => {};
|
||||
console.info = () => {};
|
||||
console.warn = () => {};
|
||||
console.error = () => {};
|
||||
|
||||
// Global test utilities available in all test files
|
||||
declare global {
|
||||
var testHelpers: {
|
||||
sleep: (ms: number) => Promise<void>;
|
||||
mockTimestamp: () => Date;
|
||||
generateTestOHLCV: (symbol?: string, overrides?: any) => any;
|
||||
generateTestTrade: (symbol?: string, overrides?: any) => any;
|
||||
generateTestQuote: (symbol?: string, overrides?: any) => any;
|
||||
mockLogger: () => any;
|
||||
restoreConsole: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
global.testHelpers = {
|
||||
/**
|
||||
* Sleep utility for async tests
|
||||
*/
|
||||
sleep: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
|
||||
|
||||
/**
|
||||
* Consistent mock timestamp for tests
|
||||
*/
|
||||
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
|
||||
|
||||
/**
|
||||
* Generate test OHLCV data
|
||||
*/
|
||||
generateTestOHLCV: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
open: 150.0,
|
||||
high: 153.0,
|
||||
low: 149.0,
|
||||
close: 152.5,
|
||||
volume: 10000,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Generate test trade data
|
||||
*/
|
||||
generateTestTrade: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
price: 152.5,
|
||||
size: 100,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
exchange: 'NASDAQ',
|
||||
conditions: ['@', 'T'],
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Generate test quote data
|
||||
*/
|
||||
generateTestQuote: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
bidPrice: 152.45,
|
||||
bidSize: 200,
|
||||
askPrice: 152.55,
|
||||
askSize: 150,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Create a mock logger
|
||||
*/
|
||||
mockLogger: () => ({
|
||||
debug: () => {},
|
||||
info: () => {},
|
||||
warn: () => {},
|
||||
error: () => {},
|
||||
critical: () => {},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Restore console methods
|
||||
*/
|
||||
restoreConsole: () => {
|
||||
global.console = originalConsole;
|
||||
}
|
||||
};
|
||||
|
||||
// Set up spyOn utilities
|
||||
// Similar to jest.spyOn but using Bun's built-in spy functionality
|
||||
// This makes it easier to migrate from Jest
|
||||
global.spyOn = function(object: any, method: string) {
|
||||
const original = object[method];
|
||||
const mock = function(...args: any[]) {
|
||||
mock.mock.calls.push(args);
|
||||
return mock.mockImplementation ? mock.mockImplementation(...args) : original.apply(object, args);
|
||||
};
|
||||
|
||||
mock.mock = { calls: [] };
|
||||
mock.mockClear = () => { mock.mock.calls = []; return mock; };
|
||||
mock.mockReset = () => {
|
||||
mock.mock.calls = [];
|
||||
mock.mockImplementation = null;
|
||||
return mock;
|
||||
};
|
||||
mock.mockImplementation = null;
|
||||
mock.mockReturnValue = (value: any) => {
|
||||
mock.mockImplementation = () => value;
|
||||
return mock;
|
||||
};
|
||||
mock.mockResolvedValue = (value: any) => {
|
||||
return mock.mockReturnValue(Promise.resolve(value));
|
||||
};
|
||||
mock.mockRejectedValue = (value: any) => {
|
||||
return mock.mockReturnValue(Promise.reject(value));
|
||||
};
|
||||
|
||||
object[method] = mock;
|
||||
return mock;
|
||||
};
|
||||
/**
|
||||
* Bun Test Setup File for Stock Bot Trading Platform
|
||||
*
|
||||
* Global test configuration and utilities available across all tests.
|
||||
* This file is executed before each test via bunfig.toml preload.
|
||||
*/
|
||||
|
||||
// Increase test timeout if needed (already configured in bunfig.toml)
|
||||
// Bun.timeout = 30000;
|
||||
|
||||
// Store original console methods to allow restoration
|
||||
const originalConsole = global.console;
|
||||
|
||||
// Mock console methods to reduce noise during tests
|
||||
// These can be restored with testHelpers.restoreConsole()
|
||||
console.log = () => {};
|
||||
console.debug = () => {};
|
||||
console.info = () => {};
|
||||
console.warn = () => {};
|
||||
console.error = () => {};
|
||||
|
||||
// Global test utilities available in all test files
|
||||
declare global {
|
||||
var testHelpers: {
|
||||
sleep: (ms: number) => Promise<void>;
|
||||
mockTimestamp: () => Date;
|
||||
generateTestOHLCV: (symbol?: string, overrides?: any) => any;
|
||||
generateTestTrade: (symbol?: string, overrides?: any) => any;
|
||||
generateTestQuote: (symbol?: string, overrides?: any) => any;
|
||||
mockLogger: () => any;
|
||||
restoreConsole: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
global.testHelpers = {
|
||||
/**
|
||||
* Sleep utility for async tests
|
||||
*/
|
||||
sleep: (ms: number) => new Promise(resolve => setTimeout(resolve, ms)),
|
||||
|
||||
/**
|
||||
* Consistent mock timestamp for tests
|
||||
*/
|
||||
mockTimestamp: () => new Date('2024-01-01T12:00:00Z'),
|
||||
|
||||
/**
|
||||
* Generate test OHLCV data
|
||||
*/
|
||||
generateTestOHLCV: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
open: 150.0,
|
||||
high: 153.0,
|
||||
low: 149.0,
|
||||
close: 152.5,
|
||||
volume: 10000,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Generate test trade data
|
||||
*/
|
||||
generateTestTrade: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
price: 152.5,
|
||||
size: 100,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
exchange: 'NASDAQ',
|
||||
conditions: ['@', 'T'],
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Generate test quote data
|
||||
*/
|
||||
generateTestQuote: (symbol = 'AAPL', overrides = {}) => ({
|
||||
symbol,
|
||||
bidPrice: 152.45,
|
||||
bidSize: 200,
|
||||
askPrice: 152.55,
|
||||
askSize: 150,
|
||||
timestamp: global.testHelpers.mockTimestamp(),
|
||||
...overrides
|
||||
}),
|
||||
|
||||
/**
|
||||
* Create a mock logger
|
||||
*/
|
||||
mockLogger: () => ({
|
||||
debug: () => {},
|
||||
info: () => {},
|
||||
warn: () => {},
|
||||
error: () => {},
|
||||
critical: () => {},
|
||||
}),
|
||||
|
||||
/**
|
||||
* Restore console methods
|
||||
*/
|
||||
restoreConsole: () => {
|
||||
global.console = originalConsole;
|
||||
}
|
||||
};
|
||||
|
||||
// Set up spyOn utilities
|
||||
// Similar to jest.spyOn but using Bun's built-in spy functionality
|
||||
// This makes it easier to migrate from Jest
|
||||
global.spyOn = function(object: any, method: string) {
|
||||
const original = object[method];
|
||||
const mock = function(...args: any[]) {
|
||||
mock.mock.calls.push(args);
|
||||
return mock.mockImplementation ? mock.mockImplementation(...args) : original.apply(object, args);
|
||||
};
|
||||
|
||||
mock.mock = { calls: [] };
|
||||
mock.mockClear = () => { mock.mock.calls = []; return mock; };
|
||||
mock.mockReset = () => {
|
||||
mock.mock.calls = [];
|
||||
mock.mockImplementation = null;
|
||||
return mock;
|
||||
};
|
||||
mock.mockImplementation = null;
|
||||
mock.mockReturnValue = (value: any) => {
|
||||
mock.mockImplementation = () => value;
|
||||
return mock;
|
||||
};
|
||||
mock.mockResolvedValue = (value: any) => {
|
||||
return mock.mockReturnValue(Promise.resolve(value));
|
||||
};
|
||||
mock.mockRejectedValue = (value: any) => {
|
||||
return mock.mockReturnValue(Promise.reject(value));
|
||||
};
|
||||
|
||||
object[method] = mock;
|
||||
return mock;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue