summaryrefslogtreecommitdiff
path: root/tests/test_parser.py
blob: 291eb9bb18135fd99f6e09bd200ceadbf9900ab8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""Tests for PPMCK and Pyxel parsers (AST output)."""

from mml_composemusic_mcp.ast_nodes import NoteStmt, Program, Track
from mml_composemusic_mcp.lexer import tokenize
from mml_composemusic_mcp.parser_ppmck import parse_ppmck
from mml_composemusic_mcp.parser_pyxel import parse_pyxel

PPMCK_EXAMPLE = """#TITLE "Test"
A t150 l8 o4 v15 @2
  c d e f
B o3
  c e g
"""

PYXEL_EXAMPLE = """0: T150 L8 O4 V100 @1
  C D E F
1: O3
  C E G
"""


def test_ppmck_parse():
    tokens = tokenize(PPMCK_EXAMPLE, "ppmck")
    program, errors = parse_ppmck(PPMCK_EXAMPLE, tokens)
    assert isinstance(program, Program)
    assert not any(e.severity == "error" for e in errors)
    assert len(program.tracks) == 2
    assert program.tracks[0].channel == "Pulse1"
    assert program.tracks[1].channel == "Pulse2"
    notes = [s for s in program.tracks[0].statements if isinstance(s, NoteStmt)]
    assert notes[0].note_name == "c"


def test_pyxel_parse():
    tokens = tokenize(PYXEL_EXAMPLE, "pyxel")
    program, errors = parse_pyxel(PYXEL_EXAMPLE, tokens)
    assert isinstance(program, Program)
    assert not any(e.severity == "error" for e in errors)
    assert len(program.tracks) == 2
    assert program.tracks[0].channel == "Pulse1"
    notes = [s for s in program.tracks[0].statements if isinstance(s, NoteStmt)]
    assert notes[0].note_name == "c"


def test_pyxel_repeat_ast():
    source = "0: T120 L4 O4\n[ C D ]2"
    tokens = tokenize(source, "pyxel")
    program, errors = parse_pyxel(source, tokens)
    assert not any(e.severity == "error" for e in errors)
    assert isinstance(program.tracks[0], Track)


def test_invalid_mode_error():
    from mml_composemusic_mcp.server import _parse_mml

    seq, errors = _parse_mml("A c", "unknown")
    assert seq is None
    assert any(e.severity == "error" for e in errors)