# Path: bibliopixel/control/midi.py
#     MESSAGE_TYPES = set(s['type'] for s in mido.messages.specs.SPECS)
#     MESSAGE_TYPES = set()
# MIDO_ERROR = """You need to install mido.  Try
#     pip install mido
# """
# MIDO_BACKEND_ERROR = """You have the wrong rtmidi installed.  Try
#     pip uninstall -y rtmidi
#     pip install -y python-rtmidi
# """
#     EXTRACTOR = {
#         # There are more mido message types that we haven't used yet.
#         'keys_by_type': {
#             'aftertouch': (
#                 'port', 'channel', 'type', 'value'),
#             'control_change': (
#                 'port', 'channel', 'type', 'control', 'value'),
#             'note_off': (
#                 'port', 'channel', 'type', 'note', 'velocity'),
#             'note_on': (
#                 'port', 'channel', 'type', 'note', 'velocity'),
#             'pitchwheel': (
#                 'port', 'channel', 'type', 'pitch'),
#             'program_change': (
#                 'port', 'channel', 'type', 'program'),
#         },
# 
#         # Some numeric fields (channel, control, program and note) don't get
#         # normalized because they are basically names.
#         'normalizers': {
#             'pitch': lambda x: fractions.Fraction(x - 8192) / 8192,
#             'value': lambda x: fractions.Fraction(x) / 127,
#             'velocity': lambda x: fractions.Fraction(x) / 127,
#         },
# 
#         'omit': ('port', 'channel'),
#     }
# class Midi(control.ExtractedLoop):
#     def __init__(self, use_note_off=True, **kwds):
#     def messages(self):


import fractions, time, unittest
from bibliopixel.control import midi
from argparse import Namespace
from test.bibliopixel import patch
        self.ports.multi_receive = multi_port

    def get_input_names(self):
        class Port(str):
            def name(self):
                return self

        return [Port('one'), Port('two')]

    def open_input(self, x):
        return x


class MidiTest(unittest.TestCase):
    routing = {
        'note_on': '.note_on',
        'note_off': '.note_off',
        'control_change': {
            '1': '.cc1',
            '2': '.cc2',
        },
        'pitchwheel': '.pitch',
    }

    def run_test(self, msgs, expected, routing=None, **kwds):
        with patch.patch(midi, 'mido', FakeMido(msgs)):
            class Root:
                pass

            root = Root()

# Path: bibliopixel/control/midi.py
#     MESSAGE_TYPES = set(s['type'] for s in mido.messages.specs.SPECS)
#     MESSAGE_TYPES = set()
# MIDO_ERROR = """You need to install mido.  Try
#     pip install mido
# """
# MIDO_BACKEND_ERROR = """You have the wrong rtmidi installed.  Try
#     pip uninstall -y rtmidi
#     pip install -y python-rtmidi
# """
#     EXTRACTOR = {
#         # There are more mido message types that we haven't used yet.
#         'keys_by_type': {
#             'aftertouch': (
#                 'port', 'channel', 'type', 'value'),
#             'control_change': (
#                 'port', 'channel', 'type', 'control', 'value'),
#             'note_off': (
#                 'port', 'channel', 'type', 'note', 'velocity'),
#             'note_on': (
#                 'port', 'channel', 'type', 'note', 'velocity'),
#             'pitchwheel': (
#                 'port', 'channel', 'type', 'pitch'),
#             'program_change': (
#                 'port', 'channel', 'type', 'program'),
#         },
# 
#         # Some numeric fields (channel, control, program and note) don't get
#         # normalized because they are basically names.
#         'normalizers': {
#             'pitch': lambda x: fractions.Fraction(x - 8192) / 8192,
#             'value': lambda x: fractions.Fraction(x) / 127,
#             'velocity': lambda x: fractions.Fraction(x) / 127,
#         },
# 
#         'omit': ('port', 'channel'),
#     }
# class Midi(control.ExtractedLoop):
#     def __init__(self, use_note_off=True, **kwds):
#     def messages(self):


# Path: test/bibliopixel/control/midi_test.py
import fractions, time, unittest
from bibliopixel.control import midi
from argparse import Namespace
from test.bibliopixel import patch

        self.ports.multi_receive = multi_port

    def get_input_names(self):
        class Port(str):
            def name(self):
                return self

        return [Port('one'), Port('two')]

    def open_input(self, x):
        return x


class MidiTest(unittest.TestCase):
    routing = {
        'note_on': '.note_on',
        'note_off': '.note_off',
        'control_change': {
            '1': '.cc1',
            '2': '.cc2',
        },
        'pitchwheel': '.pitch',
    }

    def run_test(self, msgs, expected, routing=None, **kwds):
        with patch.patch(midi, 'mido', FakeMido(msgs)):
            class Root:
                pass

            root = Root()

            m = midi.Midi(routing=routing or self.routing, **kwds)