Files
morning-report/test/sequencer.test.ts
Cory Sanin 749b3e082c
All checks were successful
NPM Audit Check / Check NPM audit (push) Successful in -2m17s
Unit tests / Unit tests (push) Successful in -2m6s
stitcher function
2025-08-29 16:09:08 -05:00

191 lines
6.1 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { type CurrentWeather, type Options } from 'openweather-api-node';
import { Sequencer } from '../src/sequencer.js';
import type { Config } from '../src/index.js';
const dummyWeather: Options = { key: 'dummy' };
vi.mock('openweather-api-node', () => {
return {
OpenWeatherAPI: vi.fn().mockImplementation((_) => {
return {
getToday: vi.fn(() => {
return {
"lat": 43.0748,
"lon": -89.3838,
"dt": "2025-08-29T06:31:05.000Z",
"dtRaw": 1756449065,
"timezoneOffset": -18000,
"astronomical": {
"sunrise": "2025-08-29T11:19:05.000Z",
"sunriseRaw": 1756466345,
"sunset": "2025-08-30T00:38:08.000Z",
"sunsetRaw": 1756514288
},
"weather": {
"temp": {
"cur": 55.85,
"min": 52.99,
"max": 58.01
},
"feelsLike": {
"cur": 55.31
},
"pressure": 1022,
"humidity": 89,
"clouds": 0,
"visibility": 10000,
"wind": {
"deg": 140,
"speed": 5.75
},
"rain": 0,
"snow": 0,
"conditionId": 800,
"main": "Clear",
"description": "clear sky",
"icon": {
"url": "http://openweathermap.org/img/wn/01n@2x.png",
"raw": "01n"
}
}
}
})
}
})
}
});
describe('sequencer', () => {
it('can generate a list from a static config', async () => {
expect(await Sequencer({
programs: [['sequence 1', 'segment 1', 'segment 2']],
segments: {
'segment 1': ['sequence 1'],
'segment 2': ['sequence 2']
},
sequences: {
'sequence 1': {
'tracks': [
'seq1.flac'
]
},
'sequence 2': {
'tracks': [
'seq2.flac'
]
}
},
voices: {},
weather: dummyWeather
})).to.include.ordered.members(['seq1.flac', 'seq1.flac', 'seq2.flac']);
});
it('can include tracks conditionally', async () => {
expect(await Sequencer({
programs: [['segment 1', 'sequence 1', 'segment 2', 'sequence 2']],
segments: {
'segment 1': ['sequence 1'],
'segment 2': ['sequence 2']
},
sequences: {
'sequence 1': {
'conditions': ['1 = 1', '1.1 > 1', '2 >= 1', '1 < 2', '1 <= 1', '-1 != 0', undefined],
'tracks': [
'seq1.flac'
]
},
'sequence 2': {
'conditions': ['weather.lat = -500'],
'tracks': [
'seq2.flac'
]
}
},
voices: {},
weather: dummyWeather
})).to.be.ordered.members(['seq1.flac', 'seq1.flac']);
});
it('throws an error on invalid conditions', async () => {
await expect(Sequencer({
programs: [['sequence 1']],
segments: {
},
sequences: {
'sequence 1': {
'conditions': ['100'],
'tracks': [
'seq1.flac'
]
}
},
voices: {},
weather: dummyWeather
})).rejects.toThrow(/not in the correct format/);
await expect(Sequencer({
programs: [['sequence 1']],
segments: {
},
sequences: {
'sequence 1': {
'conditions': ['1 ~ 2'],
'tracks': [
'seq1.flac'
]
}
},
voices: {},
weather: dummyWeather
})).rejects.toThrow(/Unsupported relational operator/);
});
it('can stringify conditions', async () => {
expect(await Sequencer({
programs: [['sequence 1']],
segments: {
},
sequences: {
'sequence 1': {
'conditions': ['weather.feelsLike = {"cur":55.31}'],
'tracks': [
'seq1.flac'
]
}
},
voices: {},
weather: dummyWeather
})).to.be.ordered.members(['seq1.flac']);
});
it('can parse voice macros', async () => {
expect(await Sequencer({
programs: [['sequence 1']],
segments: {
},
sequences: {
'sequence 1': {
'tracks': [
'%alice weather.temp.max'
]
}
},
voices: {
"alice": {
"directory": "alice/",
"extension": "flac"
}
},
weather: dummyWeather
})).to.be.ordered.members([
'alice/fifty.flac',
'alice/eight.flac',
'alice/point.flac',
'alice/zero.flac',
'alice/one.flac'
]);
});
});