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') == []
|