From ca35520338057512a71acd42bb116ffbb82cc192 Mon Sep 17 00:00:00 2001 From: tanaka takashi Date: Sat, 11 Jul 2026 19:02:14 +0900 Subject: feat: implement Famicom-style MML composer MCP server - Add FastMCP server with compose_mml tool - Support ppmck and pyxel MML syntax - Add lexer and parsers for both formats - Add NES APU-style synthesizer (pulse/triangle/noise) to WAV - Add MML templates (basic/melody/chord/drum/empty) for both modes - Add tests for lexer, parser, and server - Support stdio, http, sse, streamable-http transports - Update README, pyproject.toml, and .gitignore --- tests/test_lexer.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/test_lexer.py (limited to 'tests/test_lexer.py') diff --git a/tests/test_lexer.py b/tests/test_lexer.py new file mode 100644 index 0000000..1bb2213 --- /dev/null +++ b/tests/test_lexer.py @@ -0,0 +1,27 @@ +"""Tests for the MML lexer.""" + +from mml_composemusic_mcp.lexer import TokenType, tokenize + + +def test_ppmck_tokens(): + source = "A t150 l8 o4 v15 q2\nc d e f" + tokens = tokenize(source, "ppmck") + types = [t.type for t in tokens] + assert TokenType.TRACK_HEADER in types + assert TokenType.TEMPO in types + assert TokenType.NOTE in types + + +def test_pyxel_tokens(): + source = "0: T150 L8 O4 V100 @1\nC D E F" + tokens = tokenize(source, "pyxel") + types = [t.type for t in tokens] + assert TokenType.TRACK_HEADER in types + assert TokenType.AT in types + assert TokenType.NOTE in types + + +def test_pyxel_repeat(): + tokens = tokenize("[ C D ]2", "pyxel") + assert any(t.type == TokenType.REPEAT_START for t in tokens) + assert any(t.type == TokenType.REPEAT_END for t in tokens) -- cgit v1.2.3