UNPKG

@sailboat-computer/data-storage

Version:

Shared data storage library for sailboat computer v3

218 lines (197 loc) 8 kB
/** * Integration tests for the downsampling pipeline */ import { createDownsamplingEngine } from '../../src/downsampling/engine'; import { createTimeBasedDownsampler } from '../../src/downsampling/strategies/time-based'; import { createGeospatialDownsampler } from '../../src/downsampling/strategies/geospatial'; import { createCycleBasedDownsampler } from '../../src/downsampling/strategies/cycle-based'; import { createMaintenanceBasedDownsampler } from '../../src/downsampling/strategies/maintenance-based'; import { createGeotemporalGridDownsampler } from '../../src/downsampling/strategies/geotemporal-grid'; import { generateMockEnvironmentalData, generateMockNavigationData, generateMockEngineData, generateMockEquipmentData } from '../setup'; import { createWeatherDataGrid, createWeatherTimeSeries, createStormWeatherDataPoint } from '../fixtures/weather-data'; import { createSeaStateDataGrid, createSeaStateTimeSeries, createRoughSeaStateDataPoint } from '../fixtures/sea-state-data'; describe('Downsampling Pipeline Integration', () => { // Create downsampling engine const downsamplingEngine = createDownsamplingEngine(); // Register all downsamplers beforeAll(() => { downsamplingEngine.registerDownsampler(createTimeBasedDownsampler()); downsamplingEngine.registerDownsampler(createGeospatialDownsampler()); downsamplingEngine.registerDownsampler(createCycleBasedDownsampler()); downsamplingEngine.registerDownsampler(createMaintenanceBasedDownsampler()); downsamplingEngine.registerDownsampler(createGeotemporalGridDownsampler()); }); describe('Downsampling Engine with GeotemporalGridDownsampler', () => { it('should initialize with geotemporal grid strategy', () => { // Initialize with weather rule downsamplingEngine.initialize([ { id: 'weather-rule', name: 'Weather Data Downsampling', dataType: 'weather.data', strategy: { type: 'geotemporal-grid', baseGridSize: 1.0, adaptiveGridLevels: 3, temporalHierarchy: { recent: { maxAge: 7, resolution: 1 }, mediumTerm: { maxAge: 30, resolution: 6 }, longTerm: { maxAge: 90, resolution: 24 }, historical: { maxAge: 365, resolution: 168 }, seasonal: { resolution: 720 } }, vesselPosition: { latitude: 37.7749, longitude: -122.4194 }, criticalFeatureThresholds: { pressureChangeRate: 1.0, windSpeed: 25, waveHeight: 2.5, temperatureGradient: 5.0 } } } ]); // We can't directly verify the rules, but we can test functionality // by downsampling data and checking the results }); it('should downsample weather data using the engine', async () => { // Generate test data const weatherData = createWeatherDataGrid(37.7749, -122.4194, 1.0, 10, new Date()); // Run downsampling const result = await downsamplingEngine.downsample(weatherData); // Verify results expect(result.length).toBeLessThan(weatherData.length); expect(result[0].metadata.tags.downsampled).toBe('true'); expect(result[0].metadata.tags.downsamplingStrategy).toBe('geotemporal-grid'); }); it('should initialize with multiple rules including geotemporal grid', () => { // Initialize with multiple rules downsamplingEngine.initialize([ { id: 'environmental-rule', name: 'Environmental Data Downsampling', dataType: 'environmental.readings', strategy: { type: 'time-based', levels: [ { ageThreshold: 1, interval: '1m', aggregations: [{ function: 'avg', field: 'temperature' }] } ] } }, { id: 'navigation-rule', name: 'Navigation Data Downsampling', dataType: 'navigation.position', strategy: { type: 'geospatial', simplificationTolerance: 10, preserveDirectionChanges: true, minAngleChange: 30, preserveKeyPoints: true } }, { id: 'weather-rule', name: 'Weather Data Downsampling', dataType: 'weather.data', strategy: { type: 'geotemporal-grid', baseGridSize: 1.0, adaptiveGridLevels: 3, temporalHierarchy: { recent: { maxAge: 7, resolution: 1 }, mediumTerm: { maxAge: 30, resolution: 6 }, longTerm: { maxAge: 90, resolution: 24 }, historical: { maxAge: 365, resolution: 168 }, seasonal: { resolution: 720 } } } }, { id: 'sea-state-rule', name: 'Sea State Data Downsampling', dataType: 'sea.state', strategy: { type: 'geotemporal-grid', baseGridSize: 0.5, adaptiveGridLevels: 3, temporalHierarchy: { recent: { maxAge: 3, resolution: 1 }, mediumTerm: { maxAge: 14, resolution: 3 }, longTerm: { maxAge: 60, resolution: 12 }, historical: { maxAge: 180, resolution: 72 }, seasonal: { resolution: 720 } } } } ]); // We can't directly verify the rules, but we can test functionality // by downsampling data and checking the results }); it('should downsample different types of data', async () => { // Generate test data const environmentalData = generateMockEnvironmentalData(100).map(item => { item.metadata.category = 'environmental.readings'; return item; }); const navigationData = generateMockNavigationData(100).map(item => { item.metadata.category = 'navigation.position'; return item; }); const weatherData = createWeatherDataGrid(37.7749, -122.4194, 1.0, 10, new Date()).map(item => { item.metadata.category = 'weather.data'; return item; }); const seaStateData = createSeaStateDataGrid(37.8, -122.5, 0.5, 10, new Date()).map(item => { item.metadata.category = 'sea.state'; return item; }); // Combine all data const allData = [ ...environmentalData, ...navigationData, ...weatherData, ...seaStateData ]; // Run downsampling const result = await downsamplingEngine.downsample(allData); // Verify results expect(result.length).toBeLessThan(allData.length); // Group results by category const resultsByCategory = result.reduce((acc, item) => { const category = item.metadata.category; if (!acc[category]) { acc[category] = []; } acc[category].push(item); return acc; }, {} as Record<string, any[]>); // Verify each category has results expect(resultsByCategory['environmental.readings']).toBeDefined(); expect(resultsByCategory['navigation.position']).toBeDefined(); expect(resultsByCategory['weather.data']).toBeDefined(); expect(resultsByCategory['sea.state']).toBeDefined(); // Verify correct strategies were applied expect(resultsByCategory['environmental.readings'][0].metadata.tags.downsamplingStrategy).toBe('time-based'); expect(resultsByCategory['navigation.position'][0].metadata.tags.downsamplingStrategy).toBe('geospatial'); expect(resultsByCategory['weather.data'][0].metadata.tags.downsamplingStrategy).toBe('geotemporal-grid'); expect(resultsByCategory['sea.state'][0].metadata.tags.downsamplingStrategy).toBe('geotemporal-grid'); }); }); });