# Path: luma/core/interface/serial.py
# class gpio_cs_spi(spi):
#     """
#     Wraps the `spi` class to allow the Chip Select to be used with any GPIO pin.
#     The gpio pin to use is defined during instantiation with the keyword argument `gpio_CS`.
# 
#     Behaviour is otherwise the same, refer to the documentation on the `spi` class
#     for information on other parameters and raised exceptions.
# 
#     :param gpio_CS: The GPIO pin to connect chip select (CS / CE) to (defaults to None).
#     :type gpio_CS: int
#     """
#     def __init__(self, *args, **kwargs):
#         gpio_CS = kwargs.pop("gpio_CS", None)
#         cs_high = kwargs.pop("cs_high", None)
#         super(gpio_cs_spi, self).__init__(*args, **kwargs)
# 
#         if gpio_CS:
#             self._gpio_CS = gpio_CS
#             self._cs_high = cs_high
#             self._spi.no_cs = True  # disable spidev's handling of the chip select pin
#             self._gpio.setup(self._gpio_CS, self._gpio.OUT, initial=self._gpio.LOW if self._cs_high else self._gpio.HIGH)
# 
#     def _write_bytes(self, *args, **kwargs):
#         if self._gpio_CS:
#             self._gpio.output(self._gpio_CS, self._gpio.HIGH if self._cs_high else self._gpio.LOW)
# 
#         super(gpio_cs_spi, self)._write_bytes(*args, **kwargs)
# 
#         if self._gpio_CS:
#             self._gpio.output(self._gpio_CS, self._gpio.LOW if self._cs_high else self._gpio.HIGH)
# 
#     def cleanup(self):
#         """
#         Close pin if it was set up.
#         """
#         if self._gpio_CS is not None:
#             self._gpio.cleanup(self._gpio_CS)
#         super(gpio_cs_spi, self).cleanup()


import pytest
import luma.core.error
from unittest.mock import Mock, call
from luma.core.interface.serial import gpio_cs_spi
from helpers import get_spidev, rpi_gpio_missing, fib, assert_only_cleans_whats_setup
    gpio.HIGH = 5
    gpio.LOW = 6


def verify_gpio_cs_spi_init(port, device, bus_speed_hz=8000000, dc=24, rst=25, cs=23):
    spidev.open.assert_called_once_with(port, device)
    assert spidev.max_speed_hz == bus_speed_hz
    gpio.setmode.assert_not_called()
    gpio.setup.assert_has_calls([call(dc, gpio.OUT), call(rst, gpio.OUT), call(cs, gpio.OUT, initial=gpio.HIGH)])


def test_init():
    port = 5
    device = 2
    bus_speed = 16000000
    dc = 17
    rst = 11
    cs = 23

    gpio_cs_spi(gpio=gpio, spi=spidev, port=port, device=device, bus_speed_hz=16000000,
        gpio_DC=dc, gpio_RST=rst, gpio_CS=cs)
    verify_gpio_cs_spi_init(port, device, bus_speed, dc, rst, cs)
    gpio.output.assert_has_calls([
        call(rst, gpio.LOW),
        call(rst, gpio.HIGH)
    ])


def test_init_invalid_bus_speed():
    with pytest.raises(AssertionError):

# Path: luma/core/interface/serial.py
# class gpio_cs_spi(spi):
#     """
#     Wraps the `spi` class to allow the Chip Select to be used with any GPIO pin.
#     The gpio pin to use is defined during instantiation with the keyword argument `gpio_CS`.
# 
#     Behaviour is otherwise the same, refer to the documentation on the `spi` class
#     for information on other parameters and raised exceptions.
# 
#     :param gpio_CS: The GPIO pin to connect chip select (CS / CE) to (defaults to None).
#     :type gpio_CS: int
#     """
#     def __init__(self, *args, **kwargs):
#         gpio_CS = kwargs.pop("gpio_CS", None)
#         cs_high = kwargs.pop("cs_high", None)
#         super(gpio_cs_spi, self).__init__(*args, **kwargs)
# 
#         if gpio_CS:
#             self._gpio_CS = gpio_CS
#             self._cs_high = cs_high
#             self._spi.no_cs = True  # disable spidev's handling of the chip select pin
#             self._gpio.setup(self._gpio_CS, self._gpio.OUT, initial=self._gpio.LOW if self._cs_high else self._gpio.HIGH)
# 
#     def _write_bytes(self, *args, **kwargs):
#         if self._gpio_CS:
#             self._gpio.output(self._gpio_CS, self._gpio.HIGH if self._cs_high else self._gpio.LOW)
# 
#         super(gpio_cs_spi, self)._write_bytes(*args, **kwargs)
# 
#         if self._gpio_CS:
#             self._gpio.output(self._gpio_CS, self._gpio.LOW if self._cs_high else self._gpio.HIGH)
# 
#     def cleanup(self):
#         """
#         Close pin if it was set up.
#         """
#         if self._gpio_CS is not None:
#             self._gpio.cleanup(self._gpio_CS)
#         super(gpio_cs_spi, self).cleanup()


# Path: tests/test_gpio_cs_spi.py
import pytest
import luma.core.error
from unittest.mock import Mock, call
from luma.core.interface.serial import gpio_cs_spi
from helpers import get_spidev, rpi_gpio_missing, fib, assert_only_cleans_whats_setup

    gpio.HIGH = 5
    gpio.LOW = 6


def verify_gpio_cs_spi_init(port, device, bus_speed_hz=8000000, dc=24, rst=25, cs=23):
    spidev.open.assert_called_once_with(port, device)
    assert spidev.max_speed_hz == bus_speed_hz
    gpio.setmode.assert_not_called()
    gpio.setup.assert_has_calls([call(dc, gpio.OUT), call(rst, gpio.OUT), call(cs, gpio.OUT, initial=gpio.HIGH)])


def test_init():
    port = 5
    device = 2
    bus_speed = 16000000
    dc = 17
    rst = 11
    cs = 23

    gpio_cs_spi(gpio=gpio, spi=spidev, port=port, device=device, bus_speed_hz=16000000,
        gpio_DC=dc, gpio_RST=rst, gpio_CS=cs)
    verify_gpio_cs_spi_init(port, device, bus_speed, dc, rst, cs)
    gpio.output.assert_has_calls([
        call(rst, gpio.LOW),
        call(rst, gpio.HIGH)
    ])


def test_init_invalid_bus_speed():
    with pytest.raises(AssertionError):

        gpio_cs_spi(gpio=gpio, spi=spidev, port=5, device=2, bus_speed_hz=942312, gpio_CS=23)