File
Blob: scripts/test_music.py
| 1 | """Validate playlist packing and limits with synthetic Opus packets.""" |
| 2 | from pathlib import Path |
| 3 | from argparse import Namespace |
| 4 | import json |
| 5 | import runpy |
| 6 | import tempfile |
| 7 | import unittest |
| 8 | |
| 9 | prepare = runpy.run_path(str(Path(__file__).with_name("prepare_music.py"))) |
| 10 | song = prepare["pack_song"] |
| 11 | catalog = prepare["pack_catalog"] |
| 12 | |
| 13 | |
| 14 | class MusicTests(unittest.TestCase): |
| 15 | def playlist_inputs(self, entries): |
| 16 | with tempfile.TemporaryDirectory() as directory: |
| 17 | path = Path(directory) / "playlist.json" |
| 18 | path.write_text(json.dumps(entries)) |
| 19 | args = Namespace(playlist=path, files=[], title=None, artist=None) |
| 20 | return prepare["inputs"](args) |
| 21 | |
| 22 | def test_playlist_bitrates_preserve_defaults_and_per_song_overrides(self): |
| 23 | entries = self.playlist_inputs([ |
| 24 | "first.flac", |
| 25 | {"file": "second.flac", "title": "Second", "bitrateKbps": 88}, |
| 26 | {"file": "third.flac", "bitrateKbps": 64}, |
| 27 | ]) |
| 28 | self.assertEqual([entry["bitrateKbps"] for entry in entries], [96, 88, 64]) |
| 29 | self.assertEqual(entries[1]["title"], "Second") |
| 30 | |
| 31 | def test_invalid_playlist_bitrates_are_rejected_before_encoding(self): |
| 32 | for value in [None, True, False, "88", "88k", 88.5, 0, -1, 513]: |
| 33 | with self.subTest(value=value), self.assertRaisesRegex(ValueError, "bitrateKbps"): |
| 34 | self.playlist_inputs([{"file": "missing.flac", "bitrateKbps": value}]) |
| 35 | |
| 36 | def test_catalog_matches_the_independent_rust_fixture(self): |
| 37 | packets = [b"\xf8\xff\xfe"] |
| 38 | packed = catalog([song(packets*2, "First café", "Artist"), song(packets*3, "第二首", "")]) |
| 39 | fixture = Path(__file__).resolve().parents[1] / "firmware/crates/radio-core/tests/fixtures/playlist-v4.pack" |
| 40 | self.assertEqual(packed, fixture.read_bytes()) |
| 41 | |
| 42 | def test_bounds_are_applied_before_writing(self): |
| 43 | packet = b"\xf8\xff\xfe" |
| 44 | for packets in [[], [b""], [b"x"*1276]]: |
| 45 | with self.assertRaises(ValueError): song(packets,"Title","") |
| 46 | packed = song([packet], "Title", "") |
| 47 | for songs in [[], [packed]*33]: |
| 48 | with self.assertRaises(ValueError): catalog(songs) |
| 49 | large = song([packet]*30000, "Title", "") |
| 50 | with self.assertRaises(ValueError): catalog([large]*7) |
| 51 | |
| 52 | |
| 53 | if __name__ == "__main__": |
| 54 | unittest.main() |