1// SPDX-License-Identifier: GPL-2.0-only
2// Copyright (c) 2026-present FERS Contributors (see AUTHORS.md).
4import { describe, expect, test } from 'bun:test';
5import type { SimulationProgressState } from '@/stores/simulationProgressStore';
7 addSimulationProgressEvent,
8 getSimulationProgressPercent,
9 normalizeCompletedProgressSnapshot,
10} from './simulationProgress';
12const trackProgress = (events: SimulationProgressState[]) => {
13 const tracked: Record<string, SimulationProgressState> = {};
15 for (const event of events) {
16 Object.assign(tracked, addSimulationProgressEvent(tracked, event));
22describe('simulation progress normalization', () => {
23 test('keeps CW receiver phases on one stable row', () => {
24 const tracked = trackProgress([
26 message: 'Finalizing CW Receiver CWRadar',
31 message: 'Rendering Interference for CWRadar',
36 message: 'Applying Noise for CWRadar',
41 message: 'Writing HDF5 for CWRadar',
46 message: 'Finalized CWRadar',
52 expect(Object.keys(tracked)).toEqual(['receiver:CWRadar']);
53 expect(tracked['receiver:CWRadar']).toEqual({
54 message: 'Finalized CWRadar',
59 id: 'streaming-finalizing',
60 message: 'Finalizing CW Receiver CWRadar',
65 id: 'streaming-rendering-interference',
66 message: 'Rendering Interference for CWRadar',
71 id: 'streaming-applying-noise',
72 message: 'Applying Noise for CWRadar',
77 id: 'streaming-writing-hdf5',
78 message: 'Writing HDF5 for CWRadar',
83 id: 'streaming-finalized',
84 message: 'Finalized CWRadar',
92 test('keeps FMCW receiver phases on one stable row', () => {
93 const tracked = trackProgress([
95 message: 'Finalizing FMCW Receiver TrackerDriftFMCW',
100 message: 'Rendering Interference for TrackerDriftFMCW',
105 message: 'Applying Noise for TrackerDriftFMCW',
110 message: 'Writing HDF5 for TrackerDriftFMCW',
115 message: 'Finalized TrackerDriftFMCW',
121 expect(Object.keys(tracked)).toEqual(['receiver:TrackerDriftFMCW']);
122 expect(tracked['receiver:TrackerDriftFMCW']).toMatchObject({
123 message: 'Finalized TrackerDriftFMCW',
128 id: 'streaming-finalizing',
129 message: 'Finalizing FMCW Receiver TrackerDriftFMCW',
132 id: 'streaming-rendering-interference',
133 message: 'Rendering Interference for TrackerDriftFMCW',
136 id: 'streaming-applying-noise',
137 message: 'Applying Noise for TrackerDriftFMCW',
140 id: 'streaming-writing-hdf5',
141 message: 'Writing HDF5 for TrackerDriftFMCW',
144 id: 'streaming-finalized',
145 message: 'Finalized TrackerDriftFMCW',
151 test('keeps pulsed export chunks and completion on one stable row', () => {
152 const tracked = trackProgress([
154 message: 'Exporting PulsedRadar: Chunk 9928',
159 message: 'Finished Exporting PulsedRadar',
165 expect(Object.keys(tracked)).toEqual(['receiver:PulsedRadar']);
166 expect(tracked['receiver:PulsedRadar']).toEqual({
167 message: 'Finished Exporting PulsedRadar',
173 message: 'Exporting PulsedRadar: Chunk 9928',
178 id: 'export-finished',
179 message: 'Finished Exporting PulsedRadar',
187 test('keeps only the latest chunk detail for high-volume export updates', () => {
188 const tracked = trackProgress([
190 message: 'Exporting PulsedRadar: Chunk 10',
195 message: 'Exporting PulsedRadar: Chunk 9928',
201 expect(tracked['receiver:PulsedRadar'].details).toEqual([
204 message: 'Exporting PulsedRadar: Chunk 9928',
211 test('keeps main simulation messages out of the detail list', () => {
212 const tracked = trackProgress([
214 message: 'Simulating... 1.00s / 10.00s',
219 message: 'Main simulation finished. Waiting for data export...',
224 message: 'Simulation complete',
230 expect(Object.keys(tracked)).toEqual(['main']);
231 expect(tracked.main).toEqual({
232 message: 'Simulation complete',
238 test('marks known stale receiver and export rows complete after success', () => {
239 const completed = normalizeCompletedProgressSnapshot({
241 message: 'Finalizing CW Receiver CWRadar',
246 message: 'Writing HDF5 for CWRadar',
251 message: 'Exporting PulsedRadar: Chunk 9928',
256 message: 'Main simulation finished. Waiting for data export...',
262 expect(completed).toEqual({
263 'receiver:CWRadar': {
264 message: 'Finalized CWRadar',
269 id: 'streaming-finalizing',
270 message: 'Finalizing CW Receiver CWRadar',
275 id: 'streaming-writing-hdf5',
276 message: 'Writing HDF5 for CWRadar',
281 id: 'streaming-finalized',
282 message: 'Finalized CWRadar',
288 'receiver:PulsedRadar': {
289 message: 'Finished Exporting PulsedRadar',
295 message: 'Exporting PulsedRadar: Chunk 9928',
300 id: 'export-finished',
301 message: 'Finished Exporting PulsedRadar',
308 message: 'Simulation complete',
315 test('clamps determinate progress percentages', () => {
317 getSimulationProgressPercent({
324 getSimulationProgressPercent({
331 getSimulationProgressPercent({