# Copyright (c) 2011 Hesky Fisher
# See LICENSE.txt for details.

"""Unit tests for passport.py."""

import threading

from plover.machine.passport import Passport

from . import parametrize


class MockSerial:

    def __init__(self, **params):
        pass

    def isOpen(self):
        return True

    def inWaiting(self):
        return len(self.data)

    def read(self, size=1):
        assert size >= self.inWaiting()
        if not self.data:
            return ''
        data = self.data.pop(0)
        if not self.data:
            self.event.set()
        return data

    def close(self):
        pass


PASSPORT_TESTS = (
    # Test all keys
    lambda: ((b'!f#f+f*fAfCfBfEfDfGfFfHfKfLfOfNfQfPfSfRfUfTfWfYfXfZf^f~f',),
             [set(Passport.get_keys()),]),
    # Anything below 8 is not registered
    lambda: ((b'S9T8A7',), [['S', 'T'],]),
    # Sequence of strokes
    lambda: ((b'SfTf', b'Zf', b'QfLf'), [['S', 'T'], ['Z',], ['Q', 'L']]),
)

@parametrize(PASSPORT_TESTS)
def test_passport(monkeypatch, inputs, expected):
    params = {k: v[0] for k, v in Passport.get_option_info().items()}
    class mock(MockSerial):
        event = threading.Event()
        data = [b'<123/' + s + b'/something>' for s in inputs]
    monkeypatch.setattr('plover.machine.base.serial.Serial', mock)
    actual = []
    m = Passport(params)
    m.add_stroke_callback(actual.append)
    m.start_capture()
    mock.event.wait()
    m.stop_capture()
    assert len(actual) == len(expected)
    for actual_keys, expected_keys in zip(actual, expected):
        assert sorted(actual_keys) == sorted(expected_keys)
