File: test_parser.py

package info (click to toggle)
python-mido 1.3.3-0.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 920 kB
  • sloc: python: 4,006; makefile: 127; sh: 4
file content (133 lines) | stat: -rw-r--r-- 3,426 bytes parent folder | download
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# SPDX-FileCopyrightText: 2017 Ole Martin Bjorndalen <ombdalen@gmail.com>
#
# SPDX-License-Identifier: MIT

import random

from pytest import raises

from mido.messages import Message, specs
from mido.parser import Parser, parse, parse_all


def test_parse():
    """Parse a note_on msg and compare it to one created with Message()."""
    parsed = parse(b'\x90\x4c\x20')
    other = Message('note_on', channel=0, note=0x4c, velocity=0x20)
    assert parsed == other


def test_parse_stray_data():
    """The parser should ignore stray data bytes."""
    assert parse_all(b'\x20\x30') == []


def test_parse_stray_status_bytes():
    """The parser should ignore stray status bytes."""
    assert parse_all(b'\x90\x90\xf0') == []


def test_encode_and_parse():
    """Encode a message and then parse it.

    Should return the same message.
    """
    note_on = Message('note_on')
    assert note_on == parse(note_on.bytes())


def test_feed_byte():
    """Put various things into feed_byte()."""
    parser = Parser()

    parser.feed_byte(0)
    parser.feed_byte(255)

    with raises(TypeError):
        parser.feed_byte([1, 2, 3])

    with raises(ValueError):
        parser.feed_byte(-1)

    with raises(ValueError):
        parser.feed_byte(256)


def test_feed():
    """Put various things into feed()."""
    parser = Parser()

    parser.feed([])
    parser.feed([1, 2, 3])
    # TODO: add more valid types.

    with raises(TypeError):
        parser.feed(1)

    with raises(TypeError):
        parser.feed(None)

    with raises(TypeError):
        parser.feed()


def test_parse_random_bytes():
    """Parser should not crash when parsing random data."""
    randrange = random.Random('a_random_seed').randrange
    parser = Parser()
    for _ in range(10000):
        byte = randrange(256)
        parser.feed_byte(byte)


def test_parse_channel():
    """Parser should not discard the channel in channel messages."""
    assert parse([0x90, 0x00, 0x00]).channel == 0
    assert parse([0x92, 0x00, 0x00]).channel == 2


def test_one_byte_message():
    """Messages that are one byte long should not wait for data bytes."""
    messages = parse_all([0xf6])  # Tune request.
    assert len(messages) == 1
    assert messages[0].type == 'tune_request'


def test_undefined_messages():
    """The parser should ignore undefined status bytes and sysex_end."""
    messages = parse_all([0xf4, 0xf5, 0xf7, 0xf9, 0xfd])
    assert messages == []


def test_realtime_inside_sysex():
    """Realtime message inside sysex should be delivered first."""
    messages = parse_all([0xf0, 0, 0xfb, 0, 0xf7])
    assert len(messages) == 2
    assert messages[0].type == 'continue'
    assert messages[1].type == 'sysex'


def test_undefined_realtime_inside_sysex():
    """Undefined realtime message inside sysex should ignored."""
    messages = parse_all([0xf0, 0, 0xf9, 0xfd, 0, 0xf7])
    assert len(messages) == 1
    assert messages[0].type == 'sysex'


def test_encode_and_parse_all():
    """Encode and then parse all message types.

    This checks mostly for errors in the parser.
    """

    parser = Parser()
    for type_ in sorted(specs.SPEC_BY_TYPE.keys()):
        msg = Message(type_)
        parser.feed(msg.bytes())
        assert parser.get_message() == msg

    assert parser.get_message() is None


def test_parser_ascii_text():
    assert parse_all(b'7 bit ASCII should not produce any messages') == []