@sailboat-computer/data-storage
Version:
Shared data storage library for sailboat computer v3
242 lines (204 loc) • 7.45 kB
text/typescript
/**
* Global test setup for @sailboat-computer/data-storage
*
* This file contains common setup and teardown logic for all tests.
*/
import { StoredData, DataQuery } from '../src/types';
// Set test environment variables
process.env.NODE_ENV = 'test';
// Mock external dependencies if needed
jest.mock('ioredis');
jest.mock('influxdb-client');
jest.mock('pg');
// Global beforeAll hook
beforeAll(() => {
// Add any global setup here
console.log('Starting @sailboat-computer/data-storage tests');
});
// Global afterAll hook
afterAll(() => {
// Add any global cleanup here
console.log('Completed @sailboat-computer/data-storage tests');
});
// Global beforeEach hook
beforeEach(() => {
// Reset all mocks before each test
jest.clearAllMocks();
});
// Helper functions for tests
export const createMockStoredData = (data: any, category: string, timestamp?: string, tags?: Record<string, string>): StoredData => {
return {
data,
metadata: {
id: `test-id-${Date.now()}`,
category,
timestamp: timestamp || new Date().toISOString(),
tags: tags || {}
}
};
};
export const createMockDataQuery = (category: string, timeRange?: { start?: string; end?: string }, tags?: Record<string, string>): DataQuery => {
return {
category,
timeRange,
tags
};
};
// Mock data generators
export const generateMockEnvironmentalData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 60000); // 1 minute intervals
result.push(createMockStoredData(
{
temperature: 20 + Math.random() * 10,
humidity: 50 + Math.random() * 30,
pressure: 1010 + Math.random() * 10
},
'environmental.readings',
time.toISOString(),
{ location: i % 2 === 0 ? 'cabin' : 'deck', sensor: `sensor-${i % 3}` }
));
}
return result;
};
export const generateMockNavigationData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
let lat = 37.7749;
let lon = -122.4194;
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 60000); // 1 minute intervals
// Simulate movement
lat += (Math.random() - 0.5) * 0.001;
lon += (Math.random() - 0.5) * 0.001;
result.push(createMockStoredData(
{
latitude: lat,
longitude: lon,
speed: 5 + Math.random() * 3,
heading: (i * 10) % 360
},
'navigation.position',
time.toISOString(),
{ source: i % 2 === 0 ? 'gps' : 'compass', accuracy: `${Math.random() * 10}` }
));
}
return result;
};
export const generateMockWeatherData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
let lat = 37.7749;
let lon = -122.4194;
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 3600000); // 1 hour intervals
// Simulate grid movement
lat = 37.7749 + Math.floor(i / 10) * 0.1;
lon = -122.4194 + (i % 10) * 0.1;
result.push(createMockStoredData(
{
latitude: lat,
longitude: lon,
temperature: 15 + Math.sin(i / 24 * Math.PI * 2) * 5 + Math.random() * 2, // Daily cycle
pressure: 1013 + Math.sin(i / 48 * Math.PI * 2) * 5 + Math.random(), // 2-day cycle
pressureChangeRate: Math.sin(i / 12 * Math.PI * 2) * 0.5, // 12-hour cycle
humidity: 70 + Math.random() * 20,
windSpeed: 5 + Math.random() * 15 + (i % 24 < 12 ? 5 : 0), // Stronger during day
windDirection: (225 + i * 5) % 360,
cloudCover: Math.min(100, Math.max(0, 50 + Math.sin(i / 12 * Math.PI * 2) * 40)),
precipitation: Math.max(0, Math.sin(i / 6 * Math.PI * 2) * 5)
},
'weather.data',
time.toISOString(),
{ source: 'noaa', region: 'san-francisco-bay', grid: `${Math.floor(lat * 10)},${Math.floor(lon * 10)}` }
));
}
return result;
};
export const generateMockSeaStateData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
let lat = 37.8;
let lon = -122.5;
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 3600000); // 1 hour intervals
// Simulate grid movement
lat = 37.8 + Math.floor(i / 10) * 0.05;
lon = -122.5 + (i % 10) * 0.05;
result.push(createMockStoredData(
{
latitude: lat,
longitude: lon,
waveHeight: 0.5 + Math.sin(i / 12 * Math.PI * 2) * 0.5 + Math.random() * 0.5, // 12-hour cycle
wavePeriod: 6 + Math.sin(i / 24 * Math.PI * 2) * 2 + Math.random(), // Daily cycle
waveDirection: (240 + i * 3) % 360,
swellHeight: 0.3 + Math.sin(i / 48 * Math.PI * 2) * 0.3 + Math.random() * 0.2, // 2-day cycle
swellPeriod: 10 + Math.sin(i / 48 * Math.PI * 2) * 2 + Math.random(), // 2-day cycle
swellDirection: (260 + i * 2) % 360,
seaTemperature: 15 + Math.sin(i / 24 * Math.PI * 2) * 1 + Math.random(), // Daily cycle
currentSpeed: 0.2 + Math.sin(i / 12 * Math.PI * 2) * 0.3 + Math.random() * 0.1, // 12-hour cycle (tidal)
currentDirection: (180 + Math.sin(i / 12 * Math.PI * 2) * 90) % 360 // 12-hour cycle (tidal)
},
'sea.state',
time.toISOString(),
{ source: 'buoy', location: 'golden-gate', grid: `${Math.floor(lat * 20)},${Math.floor(lon * 20)}` }
));
}
return result;
};
export const generateMockEngineData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
let status = 'stopped';
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 60000); // 1 minute intervals
// Simulate engine cycles
if (i % 30 === 0) {
status = status === 'stopped' ? 'started' : 'stopped';
}
const rpm = status === 'stopped' ? 0 : 1800 + Math.random() * 200;
result.push(createMockStoredData(
{
rpm,
temperature: status === 'stopped' ? 25 + Math.random() * 5 : 80 + Math.random() * 10,
status,
fuelLevel: 100 - i * 0.1,
oilPressure: status === 'stopped' ? 0 : 30 + Math.random() * 5
},
'engine.data',
time.toISOString(),
{ engine: 'main', hours: `${1250 + i / 60}` }
));
}
return result;
};
export const generateMockEquipmentData = (count: number): StoredData[] => {
const result: StoredData[] = [];
const baseTime = new Date();
let maintenanceEvent = false;
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * 3600000); // 1 hour intervals
// Simulate maintenance events
if (i % 100 === 0) {
maintenanceEvent = true;
} else if (i % 100 === 1) {
maintenanceEvent = false;
}
result.push(createMockStoredData(
{
name: 'Watermaker',
status: 'operational',
pressure: 50 + Math.random() * 10,
eventType: maintenanceEvent ? 'service' : undefined,
serviceType: maintenanceEvent ? 'filter replacement' : undefined,
runtime: 1000 + i
},
'equipment.data',
time.toISOString(),
{ location: 'engine room', maintenance: maintenanceEvent ? 'true' : 'false' }
));
}
return result;
};