Procedurally generates a radio weather report

test for conditions

Changed files
+86 -16
src
test
+3
src/sequencer.ts
··· 41 41 case '=': 42 42 case '==': 43 43 return lhsResolved == rhsResolved; 44 + case '!=': 45 + return lhsResolved != rhsResolved; 44 46 case '<': 45 47 return lhsResolved < rhsResolved; 46 48 case '<=': ··· 88 90 config = conf; 89 91 const weather = new OpenWeatherAPI(conf.weather); 90 92 const currentWeather = await weather.getCurrent(); 93 + console.log(JSON.stringify(currentWeather)); 91 94 const sequence: string[] = []; 92 95 const program: SegmentName[] = selectOne(conf.programs); 93 96 for (let i = 0; i < program.length; i++) {
+68 -1
test/sequencer.test.ts
··· 9 9 return { 10 10 OpenWeatherAPI: vi.fn().mockImplementation((_) => { 11 11 return { 12 - getCurrent: vi.fn(() => {}) 12 + getCurrent: vi.fn(() => { 13 + return { 14 + "lat": 43.0748, 15 + "lon": -89.3838, 16 + "dt": "2025-08-29T06:31:05.000Z", 17 + "dtRaw": 1756449065, 18 + "timezoneOffset": -18000, 19 + "astronomical": { 20 + "sunrise": "2025-08-29T11:19:05.000Z", 21 + "sunriseRaw": 1756466345, 22 + "sunset": "2025-08-30T00:38:08.000Z", 23 + "sunsetRaw": 1756514288 24 + }, 25 + "weather": { 26 + "temp": { 27 + "cur": 55.85, 28 + "min": 52.99, 29 + "max": 58.01 30 + }, 31 + "feelsLike": { 32 + "cur": 55.31 33 + }, 34 + "pressure": 1022, 35 + "humidity": 89, 36 + "clouds": 0, 37 + "visibility": 10000, 38 + "wind": { 39 + "deg": 140, 40 + "speed": 5.75 41 + }, 42 + "rain": 0, 43 + "snow": 0, 44 + "conditionId": 800, 45 + "main": "Clear", 46 + "description": "clear sky", 47 + "icon": { 48 + "url": "http://openweathermap.org/img/wn/01n@2x.png", 49 + "raw": "01n" 50 + } 51 + } 52 + } 53 + }) 13 54 } 14 55 }) 15 56 } ··· 38 79 voices: {}, 39 80 weather: dummyWeather 40 81 })).to.include.ordered.members(['seq1.flac', 'seq1.flac', 'seq2.flac']); 82 + }); 83 + 84 + it('can include tracks conditionally', async () => { 85 + expect(await Sequencer({ 86 + programs: [['segment 1', 'segment 2']], 87 + segments: { 88 + 'segment 1': ['sequence 1'], 89 + 'segment 2': ['sequence 2'] 90 + }, 91 + sequences: { 92 + 'sequence 1': { 93 + 'conditions': ['1 = 1', '1.1 > 1', '2 >= 1', '1 < 2', '1 <= 1', '-1 != 0', undefined], 94 + 'tracks': [ 95 + 'seq1.flac' 96 + ] 97 + }, 98 + 'sequence 2': { 99 + 'conditions': ['weather.lat = -500'], 100 + 'tracks': [ 101 + 'seq2.flac' 102 + ] 103 + } 104 + }, 105 + voices: {}, 106 + weather: dummyWeather 107 + })).to.be.ordered.members(['seq1.flac']); 41 108 }); 42 109 }); 43 110
+15 -15
test/voice.test.ts
··· 10 10 11 11 describe('voiceLines', () => { 12 12 it('handles integers', () => { 13 - expect(voiceLines(dummyVoice, 16549872)).to.include.ordered.members( 13 + expect(voiceLines(dummyVoice, 16549872)).to.be.ordered.members( 14 14 [ 15 15 LINES.SIX, LINES.TEEN, LINES.MILLION, LINES.FIVE, LINES.HUNDRED, LINES.FORTY, 16 16 LINES.NINE, LINES.THOUSAND, LINES.EIGHT, LINES.HUNDRED, LINES.SEVENTY, LINES.TWO ··· 19 19 }); 20 20 21 21 it('handles floating point', () => { 22 - expect(voiceLines(dummyVoice, 672.09435)).to.include.ordered.members( 22 + expect(voiceLines(dummyVoice, 672.09435)).to.be.ordered.members( 23 23 [ 24 24 LINES.SIX, LINES.HUNDRED, LINES.SEVENTY, LINES.TWO, LINES.POINT, LINES.ZERO, 25 25 LINES.NINE, LINES.FOUR, LINES.THREE, LINES.FIVE ··· 28 28 }); 29 29 30 30 it('handles the negative', () => { 31 - expect(voiceLines(dummyVoice, -672.09435)).to.include.ordered.members( 31 + expect(voiceLines(dummyVoice, -672.09435)).to.be.ordered.members( 32 32 [ 33 33 LINES.NEGATIVE, LINES.SIX, LINES.HUNDRED, LINES.SEVENTY, LINES.TWO, LINES.POINT, LINES.ZERO, 34 34 LINES.NINE, LINES.FOUR, LINES.THREE, LINES.FIVE ··· 37 37 }); 38 38 39 39 it('handles zero', () => { 40 - expect(voiceLines(dummyVoice, 0)).to.include.ordered.members( 40 + expect(voiceLines(dummyVoice, 0)).to.be.ordered.members( 41 41 [ 42 42 LINES.ZERO 43 43 ] ··· 45 45 }); 46 46 47 47 it('handles large numbers with many zeroes', () => { 48 - expect(voiceLines(dummyVoice, 700000000000001)).to.include.ordered.members( 48 + expect(voiceLines(dummyVoice, 700000000000001)).to.be.ordered.members( 49 49 [ 50 50 LINES.SEVEN, LINES.HUNDRED, LINES.TRILLION, LINES.ONE 51 51 ] 52 52 ); 53 53 54 - expect(voiceLines(dummyVoice, 1000001)).to.include.ordered.members( 54 + expect(voiceLines(dummyVoice, 1000001)).to.be.ordered.members( 55 55 [ 56 56 LINES.ONE, LINES.MILLION, LINES.ONE 57 57 ] 58 58 ); 59 59 60 - expect(voiceLines(dummyVoice, 9000000001000)).to.include.ordered.members( 60 + expect(voiceLines(dummyVoice, 9000000001000)).to.be.ordered.members( 61 61 [ 62 62 LINES.NINE, LINES.TRILLION, LINES.ONE, LINES.THOUSAND 63 63 ] 64 64 ); 65 65 66 - expect(voiceLines(dummyVoice, 60002000000000.12)).to.include.ordered.members( 66 + expect(voiceLines(dummyVoice, 60002000000000.12)).to.be.ordered.members( 67 67 [ 68 68 LINES.SIXTY, LINES.TRILLION, LINES.TWO, LINES.BILLION, LINES.POINT, LINES.ONE, LINES.TWO 69 69 ] 70 70 ); 71 71 72 - expect(voiceLines(dummyVoice, 100010001)).to.include.ordered.members( 72 + expect(voiceLines(dummyVoice, 100010001)).to.be.ordered.members( 73 73 [ 74 74 LINES.ONE, LINES.HUNDRED, LINES.MILLION, LINES.TEN, LINES.THOUSAND, LINES.ONE 75 75 ] ··· 77 77 }); 78 78 79 79 it('handles irregularly named numbers', () => { 80 - expect(voiceLines(dummyVoice, 210)).to.include.ordered.members( 80 + expect(voiceLines(dummyVoice, 210)).to.be.ordered.members( 81 81 [ 82 82 LINES.TWO, LINES.HUNDRED, LINES.TEN 83 83 ] 84 84 ); 85 85 86 - expect(voiceLines(dummyVoice, 311)).to.include.ordered.members( 86 + expect(voiceLines(dummyVoice, 311)).to.be.ordered.members( 87 87 [ 88 88 LINES.THREE, LINES.HUNDRED, LINES.ELEVEN 89 89 ] 90 90 ); 91 91 92 - expect(voiceLines(dummyVoice, 412)).to.include.ordered.members( 92 + expect(voiceLines(dummyVoice, 412)).to.be.ordered.members( 93 93 [ 94 94 LINES.FOUR, LINES.HUNDRED, LINES.TWELVE 95 95 ] 96 96 ); 97 97 98 - expect(voiceLines(dummyVoice, 513)).to.include.ordered.members( 98 + expect(voiceLines(dummyVoice, 513)).to.be.ordered.members( 99 99 [ 100 100 LINES.FIVE, LINES.HUNDRED, LINES.THIRTEEN 101 101 ] 102 102 ); 103 103 104 - expect(voiceLines(dummyVoice, 615)).to.include.ordered.members( 104 + expect(voiceLines(dummyVoice, 615)).to.be.ordered.members( 105 105 [ 106 106 LINES.SIX, LINES.HUNDRED, LINES.FIFTEEN 107 107 ] ··· 121 121 directory, 122 122 extension: 'flac' 123 123 } 124 - expect(voiceLines(v, 29)).to.include.ordered.members([ 124 + expect(voiceLines(v, 29)).to.be.ordered.members([ 125 125 path.join(directory, `twenty.flac`), 126 126 path.join(directory, `nine.flac`), 127 127 ]);