2026-06-08 22:28:07 +02:00
|
|
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
|
|
|
import { loadConfig, DEFAULT_RENDER } from './config';
|
|
|
|
|
|
|
|
|
|
function mockFetch(body: unknown, ok = true) {
|
|
|
|
|
vi.stubGlobal('fetch', vi.fn().mockResolvedValue({
|
|
|
|
|
ok,
|
|
|
|
|
json: () => Promise.resolve(body),
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
afterEach(() => vi.unstubAllGlobals());
|
|
|
|
|
|
|
|
|
|
describe('loadConfig', () => {
|
|
|
|
|
it('loads stream URL and fills render defaults', async () => {
|
|
|
|
|
mockFetch({ streamUrl: 'http://cam/stream' });
|
|
|
|
|
const cfg = await loadConfig('config.json');
|
|
|
|
|
expect(cfg.streamUrl).toBe('http://cam/stream');
|
|
|
|
|
expect(cfg.renderDefaults).toEqual(DEFAULT_RENDER);
|
|
|
|
|
expect(cfg.calibration).toBeNull();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('keeps a valid calibration', async () => {
|
|
|
|
|
const calibration = {
|
|
|
|
|
imagePoints: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
|
|
|
|
machinePoints: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
|
|
|
|
homography: [1, 0, 0, 0, 1, 0, 0, 0, 1],
|
|
|
|
|
};
|
|
|
|
|
mockFetch({ streamUrl: 'x', calibration });
|
|
|
|
|
const cfg = await loadConfig('config.json');
|
|
|
|
|
expect(cfg.calibration).toEqual(calibration);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('drops a malformed calibration to null', async () => {
|
|
|
|
|
mockFetch({ streamUrl: 'x', calibration: { homography: [1, 2, 3] } });
|
|
|
|
|
const cfg = await loadConfig('config.json');
|
|
|
|
|
expect(cfg.calibration).toBeNull();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('throws when the request fails', async () => {
|
|
|
|
|
mockFetch({}, false);
|
|
|
|
|
await expect(loadConfig('config.json')).rejects.toThrow();
|
|
|
|
|
});
|
2026-06-08 22:30:39 +02:00
|
|
|
|
|
|
|
|
it('ignores malformed renderDefaults fields, keeping defaults and dropping extras', async () => {
|
|
|
|
|
mockFetch({ streamUrl: 'x', renderDefaults: { lineWidth: 'thick', cutColor: '#abc', bogus: true } });
|
|
|
|
|
const cfg = await loadConfig('config.json');
|
|
|
|
|
expect(cfg.renderDefaults.cutColor).toBe('#abc'); // valid string kept
|
|
|
|
|
expect(cfg.renderDefaults.lineWidth).toBe(DEFAULT_RENDER.lineWidth); // invalid number → default
|
|
|
|
|
expect(cfg.renderDefaults.rapidColor).toBe(DEFAULT_RENDER.rapidColor); // missing → default
|
|
|
|
|
expect(cfg.renderDefaults).not.toHaveProperty('bogus'); // extra key dropped
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('rejects a calibration whose homography contains NaN', async () => {
|
|
|
|
|
const calibration = {
|
|
|
|
|
imagePoints: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
|
|
|
|
machinePoints: [[0, 0], [1, 0], [1, 1], [0, 1]],
|
|
|
|
|
homography: [1, 0, 0, 0, 1, 0, 0, 0, NaN],
|
|
|
|
|
};
|
|
|
|
|
mockFetch({ streamUrl: 'x', calibration });
|
|
|
|
|
const cfg = await loadConfig('config.json');
|
|
|
|
|
expect(cfg.calibration).toBeNull();
|
|
|
|
|
});
|
2026-06-08 22:28:07 +02:00
|
|
|
});
|