# Path: luma/core/device.py
# class parallel_device(device):
#     """
#     Wrapper class to manage communications with devices that can operate in
#     four or eight bit modes.
# 
#     .. note::
#         parallel_devices require specific timings which are managed by using
#         ``time.sleep`` to cause the process to block for small amounts of time.
#         If your application is especially time sensitive, consider running the
#         drivers in a separate thread.
# 
#     .. versionadded:: 1.16.0
#     """
# 
#     def __init__(self, const=None, serial_interface=None, exec_time=None, **kwargs):
#         super(parallel_device, self).__init__(const, serial_interface)
# 
#         self._exec_time = exec_time if exec_time is not None else \
#             serial_interface._pulse_time if hasattr(serial_interface, '_pulse_time') \
#             else 0
#         self._bitmode = serial_interface._bitmode if hasattr(serial_interface, '_bitmode') else 4
#         assert self._bitmode in (4, 8), f'Bit mode {self._bitmode} is invalid.  It can only be 4 or 8'
# 
#     def command(self, *cmd, exec_time=None, only_low_bits=False):
#         """
#         Sends a command or sequence of commands through to the serial interface.
#         If operating in four bit mode, expands each command from one byte
#         values (8 bits) to two nibble values (4 bits each)
# 
#         :param cmd: A spread of commands.
#         :type cmd: int
#         :param exec_time: Amount of time to wait for the command to finish
#             execution.  If not provided, the device default will be used instead
#         :type exec_time: float
#         :param only_low_bits: If ``True``, only the lowest four bits of the command
#             will be sent.  This is necessary on some devices during initialization
#         :type only_low_bits: bool
#         """
#         cmd = cmd if (self._bitmode == 8 or only_low_bits) else \
#             bytes_to_nibbles(cmd)
#         super(parallel_device, self).command(*cmd)
#         sleep(exec_time or self._exec_time)
# 
#     def data(self, data):
#         """
#         Sends a sequence of bytes through to the serial interface.
#         If operating in four bit mode, expands each byte from a single
#         value (8 bits) to two nibble values (4 bits each)
# 
#         :param data: a sequence of bytes to send to the display
#         :type data: list
#         """
#         data = data if self._bitmode == 8 else \
#             bytes_to_nibbles(data)
#         super(parallel_device, self).data(data)


from unittest.mock import Mock, call
from luma.core.device import parallel_device
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Richard Hull and contributors
# See LICENSE.rst for details.

"""
Tests for the :py:class:`luma.core.device.parallel_device` class.
"""



def test_4bit():
    serial = Mock(unsafe=True)
    serial._bitmode = 4
    serial._pulse_time = 1
    pd = parallel_device(serial_interface=serial)

    pd.command(0x10, 0x11, 0xff)
    pd.data([0x41, 0x42, 0x43])

    comm = call(0x01, 0x00, 0x01, 0x01, 0x0f, 0x0f)
    data = call([0x04, 0x01, 0x04, 0x02, 0x04, 0x03])
    serial.command.assert_has_calls([comm])
    serial.data.assert_has_calls([data])


def test_8bit():
    serial = Mock(unsafe=True)
    serial._bitmode = 8
    serial._pulse_time = 1

# Path: luma/core/device.py
# class parallel_device(device):
#     """
#     Wrapper class to manage communications with devices that can operate in
#     four or eight bit modes.
# 
#     .. note::
#         parallel_devices require specific timings which are managed by using
#         ``time.sleep`` to cause the process to block for small amounts of time.
#         If your application is especially time sensitive, consider running the
#         drivers in a separate thread.
# 
#     .. versionadded:: 1.16.0
#     """
# 
#     def __init__(self, const=None, serial_interface=None, exec_time=None, **kwargs):
#         super(parallel_device, self).__init__(const, serial_interface)
# 
#         self._exec_time = exec_time if exec_time is not None else \
#             serial_interface._pulse_time if hasattr(serial_interface, '_pulse_time') \
#             else 0
#         self._bitmode = serial_interface._bitmode if hasattr(serial_interface, '_bitmode') else 4
#         assert self._bitmode in (4, 8), f'Bit mode {self._bitmode} is invalid.  It can only be 4 or 8'
# 
#     def command(self, *cmd, exec_time=None, only_low_bits=False):
#         """
#         Sends a command or sequence of commands through to the serial interface.
#         If operating in four bit mode, expands each command from one byte
#         values (8 bits) to two nibble values (4 bits each)
# 
#         :param cmd: A spread of commands.
#         :type cmd: int
#         :param exec_time: Amount of time to wait for the command to finish
#             execution.  If not provided, the device default will be used instead
#         :type exec_time: float
#         :param only_low_bits: If ``True``, only the lowest four bits of the command
#             will be sent.  This is necessary on some devices during initialization
#         :type only_low_bits: bool
#         """
#         cmd = cmd if (self._bitmode == 8 or only_low_bits) else \
#             bytes_to_nibbles(cmd)
#         super(parallel_device, self).command(*cmd)
#         sleep(exec_time or self._exec_time)
# 
#     def data(self, data):
#         """
#         Sends a sequence of bytes through to the serial interface.
#         If operating in four bit mode, expands each byte from a single
#         value (8 bits) to two nibble values (4 bits each)
# 
#         :param data: a sequence of bytes to send to the display
#         :type data: list
#         """
#         data = data if self._bitmode == 8 else \
#             bytes_to_nibbles(data)
#         super(parallel_device, self).data(data)


# Path: tests/test_parallel_device.py
from unittest.mock import Mock, call
from luma.core.device import parallel_device

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2020 Richard Hull and contributors
# See LICENSE.rst for details.

"""
Tests for the :py:class:`luma.core.device.parallel_device` class.
"""



def test_4bit():
    serial = Mock(unsafe=True)
    serial._bitmode = 4
    serial._pulse_time = 1
    pd = parallel_device(serial_interface=serial)

    pd.command(0x10, 0x11, 0xff)
    pd.data([0x41, 0x42, 0x43])

    comm = call(0x01, 0x00, 0x01, 0x01, 0x0f, 0x0f)
    data = call([0x04, 0x01, 0x04, 0x02, 0x04, 0x03])
    serial.command.assert_has_calls([comm])
    serial.data.assert_has_calls([data])


def test_8bit():
    serial = Mock(unsafe=True)
    serial._bitmode = 8
    serial._pulse_time = 1

    pd = parallel_device(serial_interface=serial)