UNPKG

amaran-light-cli

Version:

Command line tool for controlling Aputure Amaran lights via WebSocket to a local Amaran desktop app.

96 lines 4.24 kB
import { Command } from 'commander'; import { describe, expect, it, vi } from 'vitest'; import registerAutoCct from '../commands/daylightSimulation/autoCct.js'; import registerConfig from '../commands/deviceControl/config.js'; import { interpolateMaxLux, parseMaxLuxMap } from '../daylightSimulation/mathUtil.js'; describe('Max Lux Map Feature', () => { describe('Math Utils', () => { const map = { 2700: 8000, 5600: 10000, 6500: 9000, }; it('parses valid map string', () => { const result = parseMaxLuxMap('2700:8000, 5600:10000, 6500:9000'); expect(result).toEqual(map); }); it('returns null for invalid string', () => { expect(parseMaxLuxMap('invalid')).toBeNull(); expect(parseMaxLuxMap('2700:abc')).toBeNull(); }); it('interpolates correctly within range', () => { // 4150 is exactly half way between 2700 and 5600. // 2700->8000, 5600->10000. Diff = 2000. Half = 1000. Result 9000. expect(interpolateMaxLux(4150, map)).toBeCloseTo(9000); }); it('clamps to lower bound', () => { expect(interpolateMaxLux(2000, map)).toBe(8000); }); it('clamps to upper bound', () => { expect(interpolateMaxLux(7000, map)).toBe(9000); }); it('handles exact match', () => { expect(interpolateMaxLux(5600, map)).toBe(10000); }); }); describe('Config Command Integration', () => { it('saves parsed map to config', async () => { const program = new Command(); program.exitOverride(); const saveConfig = vi.fn(); const deps = { asyncCommand: (fn) => (...args) => fn(...args), loadConfig: () => ({}), saveConfig, }; registerConfig(program, deps); await program.parseAsync(['node', 'test', 'config', '--max-lux', '2700:8000,5600:10000']); expect(saveConfig).toHaveBeenCalledWith(expect.objectContaining({ maxLux: { 2700: 8000, 5600: 10000 }, }), expect.anything()); }); }); describe('AutoCCT Integration', () => { // Mock cctUtil to control the "current" CCT vi.mock('../daylightSimulation/cctUtil', () => ({ calculateCCT: vi.fn(() => ({ cct: 4150, intensity: 500, lightOutput: 4500 })), // 4500 lux target parseCurveType: vi.fn(() => 'HANN'), CurveType: { HANN: 'hann' }, })); vi.mock('../daylightSimulation/geoipUtil', () => ({ getLocationFromIP: vi.fn(() => ({ ll: [0, 0] })), })); it('uses interpolated max lux for intensity calculation', async () => { const setCCT = vi.fn(); const disconnect = vi.fn(async () => Promise.resolve()); const controllerStub = { getDevices: () => [{ node_id: 'AAA-111' }], getLightSleepStatus: (_id, cb) => cb(true, 'ok', { sleep: false }), setCCT, disconnect, on: vi.fn(), off: vi.fn(), }; const _actionSpy = vi.fn(); // Mock dependencies const deps = { createController: async () => controllerStub, findDevice: () => ({ node_id: 'AAA-111' }), asyncCommand: ((fn) => (...args) => fn(...args)), loadConfig: () => ({}), }; const program = new Command(); program.exitOverride(); registerAutoCct(program, deps); // Max Lux Map: 2700:8000, 5600:10000. // Target CCT from mock is 4150. // Interpolated Max Lux should be 9000 (midpoint). // Target Output is 4500. // Intensity should be 4500 / 9000 = 0.5 = 50%. // 50% * 10 = 500 raw intensity. await program.parseAsync(['node', 'test', 'auto-cct', '--max-lux', '2700:8000,5600:10000']); expect(setCCT).toHaveBeenCalledWith('AAA-111', 4150, 500); }); }); }); //# sourceMappingURL=maxLuxInterpolation.test.js.map