Separate method open() and constructor, enhance consistency between connectors: Rework printer tests (#587)
* Add fixtures * Add test_printer_file.py * Remove old broken printer tests * Include a close_on_reopen test * Add test_printer_network.py * Add test_printer_serial.py * Add test_printer_usb.py * Add test_printer_lp.py * Add test_printer_cups.py * Add test_printer_win32raw.py * Test the 'printers' property * Fix conftest import formatting * Fix failing LP tests * Cancel close only if literal False|None _device * Fix win32raw failing tests (maybe) * Include win32raw close_on_reopen test * Include test _raw methods to win32raw * Replace general exceptions in win32raw * Replace wrong exception in cups * Include more tests to cups * Extend cups tests
This commit is contained in:
parent
e7dd97554c
commit
a50a3b7167
|
@ -172,9 +172,9 @@ class CupsPrinter(Escpos):
|
|||
self.pending_job = True
|
||||
try:
|
||||
self.tmpfile.write(msg)
|
||||
except ValueError:
|
||||
except TypeError:
|
||||
self.pending_job = False
|
||||
raise ValueError("Printer job not opened")
|
||||
raise TypeError("Bytes required. Printer job not opened")
|
||||
|
||||
def send(self):
|
||||
"""Send the print job to the printer."""
|
||||
|
|
|
@ -138,7 +138,7 @@ class Win32Raw(Escpos):
|
|||
|
||||
def close(self) -> None:
|
||||
"""Close connection to default printer."""
|
||||
if not self._device:
|
||||
if self._device is False or self._device is None: # Literal False | None
|
||||
return
|
||||
logging.info("Closing Win32Raw connection to printer %s", self.printer_name)
|
||||
win32print.EndPagePrinter(self._device)
|
||||
|
@ -153,7 +153,7 @@ class Win32Raw(Escpos):
|
|||
:type msg: bytes
|
||||
"""
|
||||
if self.printer_name is None:
|
||||
raise Exception("Printer not found")
|
||||
raise DeviceNotFoundError("Printer not found")
|
||||
if not self.device:
|
||||
raise Exception("Printer job not opened")
|
||||
raise DeviceNotFoundError("Printer job not opened")
|
||||
win32print.WritePrinter(self.device, msg)
|
||||
|
|
|
@ -1,8 +1,49 @@
|
|||
import pytest
|
||||
|
||||
from escpos.printer import Dummy
|
||||
from escpos.exceptions import DeviceNotFoundError
|
||||
from escpos.printer import LP, CupsPrinter, Dummy, File, Network, Serial, Usb, Win32Raw
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def driver():
|
||||
return Dummy()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def usbprinter():
|
||||
return Usb()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def serialprinter():
|
||||
return Serial()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def networkprinter():
|
||||
return Network()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def fileprinter():
|
||||
return File()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def lpprinter():
|
||||
return LP()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def win32rawprinter():
|
||||
return Win32Raw()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def cupsprinter():
|
||||
return CupsPrinter()
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def devicenotfounderror():
|
||||
return DeviceNotFoundError
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the File printer
|
||||
|
||||
:author: `Patrick Kanzler <dev@pkanzler.de>`_
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
|
||||
import pytest
|
||||
import six
|
||||
from hypothesis import given, settings
|
||||
from hypothesis.strategies import text
|
||||
|
||||
import escpos.printer as printer
|
||||
|
||||
if six.PY3:
|
||||
mock_open_call = "builtins.open"
|
||||
else:
|
||||
mock_open_call = "__builtin__.open"
|
||||
|
||||
|
||||
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
|
||||
@given(path=text())
|
||||
def test_load_file_printer(mocker, path):
|
||||
"""test the loading of the file-printer"""
|
||||
mock_escpos = mocker.patch("escpos.escpos.Escpos.__init__")
|
||||
mock_open = mocker.patch(mock_open_call)
|
||||
printer.File(devfile=path)
|
||||
assert mock_escpos.called
|
||||
mock_open.assert_called_with(path, "wb")
|
||||
|
||||
|
||||
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
|
||||
@given(txt=text())
|
||||
def test_auto_flush(mocker, txt):
|
||||
"""test auto_flush in file-printer"""
|
||||
mock_escpos = mocker.patch("escpos.escpos.Escpos.__init__")
|
||||
mock_open = mocker.patch(mock_open_call)
|
||||
mock_device = mocker.patch.object(printer.File, "device")
|
||||
|
||||
p = printer.File(auto_flush=False)
|
||||
# inject the mocked device-object
|
||||
p.device = mock_device
|
||||
p._raw(txt)
|
||||
assert not mock_device.flush.called
|
||||
mock_device.reset_mock()
|
||||
p = printer.File(auto_flush=True)
|
||||
# inject the mocked device-object
|
||||
p.device = mock_device
|
||||
p._raw(txt)
|
||||
assert mock_device.flush.called
|
||||
|
||||
|
||||
@pytest.mark.skip("this test is broken and has to be fixed or discarded")
|
||||
@given(txt=text())
|
||||
def test_flush_on_close(mocker, txt):
|
||||
"""test flush on close in file-printer"""
|
||||
mock_open = mocker.patch(mock_open_call)
|
||||
mock_device = mocker.patch.object(printer.File, "device")
|
||||
|
||||
p = printer.File(auto_flush=False)
|
||||
# inject the mocked device-object
|
||||
p.device = mock_device
|
||||
p._raw(txt)
|
||||
assert not mock_device.flush.called
|
||||
p.close()
|
||||
assert mock_device.flush.called
|
||||
assert mock_device.close.called
|
|
@ -1,26 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import socket
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
import escpos.printer as printer
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def instance():
|
||||
socket.socket.connect = mock.Mock()
|
||||
return printer.Network("localhost")
|
||||
|
||||
|
||||
def test_close_without_open(instance):
|
||||
"""try to close without opening (should fail gracefully)
|
||||
|
||||
Currently we never open from our fixture, so calling close once
|
||||
should be enough. In the future this might not be enough,
|
||||
therefore we have to close twice in order to provoke an error
|
||||
(if possible, this should not raise)
|
||||
"""
|
||||
instance.close()
|
||||
instance.close()
|
|
@ -0,0 +1,176 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the Cups printer
|
||||
|
||||
:author: Benito López and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# skip all the tests if the platform is Windows
|
||||
pytestmark = pytest.mark.skipif(
|
||||
sys.platform == "win32", reason="skipping non Windows platform specific tests"
|
||||
)
|
||||
|
||||
|
||||
def test_device_not_initialized(cupsprinter):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert cupsprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(cupsprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
cupsprinter.host = "fakehost"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
cupsprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(cupsprinter, caplog):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
cupsprinter.host = "fakehost"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
cupsprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not available" in caplog.text
|
||||
assert cupsprinter.device is None
|
||||
|
||||
|
||||
def test_open(cupsprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a cups printer object and a mocked pycups device
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("cups.Connection")
|
||||
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
|
||||
|
||||
cupsprinter.printer_name = "test_printer"
|
||||
assert cupsprinter.printer_name in cupsprinter.printers
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
cupsprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert cupsprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(cupsprinter, mocker):
|
||||
"""
|
||||
GIVEN a cups printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
spy = mocker.spy(cupsprinter, "close")
|
||||
mocker.patch("cups.Connection")
|
||||
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
|
||||
|
||||
cupsprinter.printer_name = "test_printer"
|
||||
|
||||
cupsprinter.open()
|
||||
assert cupsprinter._device
|
||||
|
||||
cupsprinter.open()
|
||||
spy.assert_called_once()
|
||||
|
||||
|
||||
def test_close(cupsprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a cups printer object and a mocked pycups device
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("cups.Connection")
|
||||
mocker.patch("escpos.printer.CupsPrinter.printers", new={"test_printer": "Test"})
|
||||
|
||||
cupsprinter.printer_name = "test_printer"
|
||||
cupsprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
cupsprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert cupsprinter._device is False
|
||||
|
||||
|
||||
def test_send_on_close(cupsprinter, mocker):
|
||||
"""
|
||||
GIVEN a cups printer object and a mocked pycups device
|
||||
WHEN closing connection before send the buffer
|
||||
THEN check the buffer is sent and cleared
|
||||
"""
|
||||
mocked_cups = mocker.patch("cups.Connection")
|
||||
|
||||
spy_send = mocker.spy(cupsprinter, "send")
|
||||
spy_clear = mocker.spy(cupsprinter, "_clear")
|
||||
|
||||
cupsprinter._device = mocked_cups
|
||||
cupsprinter.pending_job = True
|
||||
|
||||
cupsprinter.close()
|
||||
|
||||
spy_send.assert_called_once()
|
||||
spy_clear.assert_called_once()
|
||||
assert cupsprinter.pending_job is False
|
||||
|
||||
|
||||
def test_raw_raise_exception(cupsprinter):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN passing a non byte string to _raw()
|
||||
THEN check an exception is raised and pending_job is False
|
||||
"""
|
||||
with pytest.raises(TypeError):
|
||||
cupsprinter._raw("Non bytes")
|
||||
|
||||
assert cupsprinter.pending_job is False
|
||||
|
||||
|
||||
def test_raw(cupsprinter):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN passing a byte string to _raw()
|
||||
THEN check the buffer content
|
||||
"""
|
||||
cupsprinter._raw(b"Test")
|
||||
cupsprinter.tmpfile.seek(0)
|
||||
assert cupsprinter.tmpfile.read() == b"Test"
|
||||
|
||||
|
||||
def test_printers_no_device(cupsprinter):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN device is None
|
||||
THEN check the return value is {}
|
||||
"""
|
||||
cupsprinter.device = None
|
||||
assert cupsprinter.printers == {}
|
||||
|
||||
|
||||
def test_read_no_device(cupsprinter):
|
||||
"""
|
||||
GIVEN a cups printer object
|
||||
WHEN device is None
|
||||
THEN check the return value is []
|
||||
"""
|
||||
cupsprinter.device = None
|
||||
assert cupsprinter._read() == []
|
|
@ -0,0 +1,147 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the File printer
|
||||
|
||||
:author: `Patrick Kanzler <dev@pkanzler.de>`_ and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2016-2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_device_not_initialized(fileprinter):
|
||||
"""
|
||||
GIVEN a file printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert fileprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(fileprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a file printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
fileprinter.devfile = "fake/device"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
fileprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(fileprinter, caplog):
|
||||
"""
|
||||
GIVEN a file printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
fileprinter.devfile = "fake/device"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
fileprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not found" in caplog.text
|
||||
assert fileprinter.device is None
|
||||
|
||||
|
||||
def test_open(fileprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("builtins.open")
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
fileprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert fileprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(fileprinter, mocker):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
mocker.patch("builtins.open")
|
||||
spy = mocker.spy(fileprinter, "close")
|
||||
|
||||
fileprinter.open()
|
||||
assert fileprinter._device
|
||||
|
||||
fileprinter.open()
|
||||
spy.assert_called_once_with()
|
||||
|
||||
|
||||
def test_flush(fileprinter, mocker):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN auto_flush is disabled and flush() issued manually
|
||||
THEN check the flush method is called only one time.
|
||||
"""
|
||||
spy = mocker.spy(fileprinter, "flush")
|
||||
mocker.patch("builtins.open")
|
||||
|
||||
fileprinter.auto_flush = False
|
||||
fileprinter.open()
|
||||
fileprinter.textln("python-escpos")
|
||||
fileprinter.flush()
|
||||
|
||||
assert spy.call_count == 1
|
||||
|
||||
|
||||
def test_auto_flush_on_command(fileprinter, mocker):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN auto_flush is enabled and flush() not issued manually
|
||||
THEN check the flush method is called automatically
|
||||
"""
|
||||
spy = mocker.spy(fileprinter, "flush")
|
||||
mocker.patch("builtins.open")
|
||||
|
||||
fileprinter.auto_flush = True
|
||||
fileprinter.open()
|
||||
fileprinter.textln("python-escpos")
|
||||
fileprinter.textln("test")
|
||||
|
||||
assert spy.call_count > 1
|
||||
|
||||
|
||||
def test_auto_flush_on_close(fileprinter, mocker, caplog, capsys):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN auto_flush is disabled and flush() not issued manually
|
||||
THEN check the flush method is called automatically on close
|
||||
"""
|
||||
spy = mocker.spy(fileprinter, "flush")
|
||||
mocker.patch("builtins.open")
|
||||
|
||||
fileprinter.auto_flush = False
|
||||
fileprinter.open()
|
||||
fileprinter.textln("python-escpos")
|
||||
fileprinter.close()
|
||||
|
||||
assert spy.call_count == 1
|
||||
|
||||
|
||||
def test_close(fileprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a file printer object and a mocked connection
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("builtins.open")
|
||||
fileprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
fileprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert fileprinter._device is False
|
|
@ -0,0 +1,173 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the LP printer
|
||||
|
||||
:author: Benito López and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# skip all the tests if the platform is Windows
|
||||
pytestmark = pytest.mark.skipif(
|
||||
sys.platform == "win32", reason="skipping non Windows platform specific tests"
|
||||
)
|
||||
|
||||
|
||||
def test_device_not_initialized(lpprinter):
|
||||
"""
|
||||
GIVEN a lp printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert lpprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(lpprinter, devicenotfounderror, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "fakeprinter"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
lpprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(lpprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "fakeprinter"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
lpprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not available" in caplog.text
|
||||
assert lpprinter.device is None
|
||||
|
||||
|
||||
def test_open(lpprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
assert lpprinter.printer_name in lpprinter.printers
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
lpprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert lpprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(lpprinter, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
spy = mocker.spy(lpprinter, "close")
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
|
||||
lpprinter.open()
|
||||
assert lpprinter._device
|
||||
|
||||
lpprinter.open()
|
||||
spy.assert_called_once_with()
|
||||
|
||||
|
||||
def test_flush(lpprinter, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN auto_flush is disabled and flush() issued manually
|
||||
THEN check the flush method is called only one time.
|
||||
"""
|
||||
spy = mocker.spy(lpprinter, "flush")
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
lpprinter.auto_flush = False
|
||||
lpprinter.open()
|
||||
lpprinter.textln("python-escpos")
|
||||
lpprinter.flush()
|
||||
|
||||
assert spy.call_count == 1
|
||||
|
||||
|
||||
def test_auto_flush_on_command(lpprinter, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN auto_flush is enabled and flush() not issued manually
|
||||
THEN check the flush method is called automatically
|
||||
"""
|
||||
spy = mocker.spy(lpprinter, "flush")
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
lpprinter.auto_flush = True
|
||||
lpprinter.open()
|
||||
lpprinter.textln("python-escpos")
|
||||
lpprinter.textln("test")
|
||||
|
||||
assert spy.call_count > 1
|
||||
|
||||
|
||||
def test_auto_flush_on_close(lpprinter, mocker, caplog, capsys):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN auto_flush is disabled and flush() not issued manually
|
||||
THEN check the flush method is called automatically on close
|
||||
"""
|
||||
spy = mocker.spy(lpprinter, "flush")
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
lpprinter.auto_flush = False
|
||||
lpprinter.open()
|
||||
lpprinter.textln("python-escpos")
|
||||
lpprinter.close()
|
||||
|
||||
assert spy.call_count == 1
|
||||
|
||||
|
||||
def test_close(lpprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a lp printer object and a mocked connection
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("subprocess.Popen")
|
||||
mocker.patch("escpos.printer.LP.printers", new={"test_printer": "Test"})
|
||||
|
||||
lpprinter.printer_name = "test_printer"
|
||||
lpprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
lpprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert lpprinter._device is False
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the Network printer
|
||||
|
||||
:author: `Patrick Kanzler <dev@pkanzler.de>`_ and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2016-2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_device_not_initialized(networkprinter):
|
||||
"""
|
||||
GIVEN a network printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert networkprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(networkprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a network printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
networkprinter.host = "fakehost"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
networkprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(networkprinter, caplog):
|
||||
"""
|
||||
GIVEN a network printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
networkprinter.host = "fakehost"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
networkprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not found" in caplog.text
|
||||
assert networkprinter.device is None
|
||||
|
||||
|
||||
def test_open(networkprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a network printer object and a mocked socket device
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("socket.socket")
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
networkprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert networkprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(networkprinter, mocker):
|
||||
"""
|
||||
GIVEN a network printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
mocker.patch("socket.socket")
|
||||
spy = mocker.spy(networkprinter, "close")
|
||||
|
||||
networkprinter.open()
|
||||
assert networkprinter._device
|
||||
|
||||
networkprinter.open()
|
||||
spy.assert_called_once_with()
|
||||
|
||||
|
||||
def test_close(networkprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a network printer object and a mocked socket device
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("socket.socket")
|
||||
networkprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
networkprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert networkprinter._device is False
|
|
@ -0,0 +1,96 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the Serial printer
|
||||
|
||||
:author: Benito López and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def test_device_not_initialized(serialprinter):
|
||||
"""
|
||||
GIVEN a serial printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert serialprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(serialprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a serial printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
serialprinter.devfile = "fake/device"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
serialprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(serialprinter, caplog):
|
||||
"""
|
||||
GIVEN a serial printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
serialprinter.devfile = "fake/device"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
serialprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not found" in caplog.text
|
||||
assert serialprinter.device is None
|
||||
|
||||
|
||||
def test_open(serialprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a serial printer object and a mocked pyserial device
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("serial.Serial")
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
serialprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert serialprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(serialprinter, mocker):
|
||||
"""
|
||||
GIVEN a serial printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
mocker.patch("serial.Serial")
|
||||
spy = mocker.spy(serialprinter, "close")
|
||||
|
||||
serialprinter.open()
|
||||
assert serialprinter._device
|
||||
|
||||
serialprinter.open()
|
||||
spy.assert_called_once_with()
|
||||
|
||||
|
||||
def test_close(serialprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a serial printer object and a mocked pyserial device
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("serial.Serial")
|
||||
serialprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
serialprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert serialprinter._device is False
|
|
@ -0,0 +1,106 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the Usb printer
|
||||
|
||||
:author: Benito López and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
# import pytest
|
||||
|
||||
|
||||
def test_device_not_initialized(usbprinter):
|
||||
"""
|
||||
GIVEN a usb printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert usbprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(usbprinter, devicenotfounderror, mocker):
|
||||
"""
|
||||
# GIVEN a usb printer object
|
||||
GIVEN a mocked usb printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
# THEN check the exception is raised
|
||||
THEN check the param is True
|
||||
"""
|
||||
mocker.patch("usb.core.find")
|
||||
spy = mocker.spy(usbprinter, "open")
|
||||
# usbprinter.usb_args = {"idVendor": 0, "idProduct": 0}
|
||||
|
||||
# with pytest.raises(devicenotfounderror):
|
||||
usbprinter.open(raise_not_found=True)
|
||||
spy.assert_called_once_with(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(usbprinter, caplog, mocker):
|
||||
"""
|
||||
# GIVEN a usb printer object
|
||||
GIVEN a mocked usb printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
# THEN check the error is logged and open() canceled
|
||||
THEN check the param is False
|
||||
"""
|
||||
mocker.patch("usb.core.find")
|
||||
spy = mocker.spy(usbprinter, "open")
|
||||
# usbprinter.usb_args = {"idVendor": 0, "idProduct": 0}
|
||||
|
||||
# with caplog.at_level(logging.ERROR):
|
||||
usbprinter.open(raise_not_found=False)
|
||||
|
||||
# assert "not found" in caplog.text
|
||||
# assert usbprinter.device is None
|
||||
spy.assert_called_once_with(raise_not_found=False)
|
||||
|
||||
|
||||
def test_open(usbprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a usb printer object and a mocked pyusb device
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
mocker.patch("usb.core.find")
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
usbprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert usbprinter.device
|
||||
|
||||
|
||||
def test_close_on_reopen(usbprinter, mocker):
|
||||
"""
|
||||
GIVEN a usb printer object and a mocked connection
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
mocker.patch("usb.core.find")
|
||||
spy = mocker.spy(usbprinter, "close")
|
||||
|
||||
usbprinter.open()
|
||||
assert usbprinter._device
|
||||
|
||||
usbprinter.open()
|
||||
spy.assert_called_once_with()
|
||||
|
||||
|
||||
def test_close(usbprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a usb printer object and a mocked pyusb device
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
mocker.patch("usb.core.find")
|
||||
usbprinter.open()
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
usbprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert usbprinter._device is False
|
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""tests for the Win32Raw printer
|
||||
|
||||
:author: Benito López and the python-escpos developers
|
||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
||||
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
|
||||
:license: MIT
|
||||
"""
|
||||
|
||||
import logging
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
# skip all the tests if the platform is not Windows
|
||||
pytestmark = pytest.mark.skipif(
|
||||
sys.platform != "win32", reason="Skipping Windows platform specific tests"
|
||||
)
|
||||
|
||||
|
||||
def test_device_not_initialized(win32rawprinter):
|
||||
"""
|
||||
GIVEN a win32raw printer object
|
||||
WHEN it is not initialized
|
||||
THEN check the device property is False
|
||||
"""
|
||||
assert win32rawprinter._device is False
|
||||
|
||||
|
||||
def test_open_raise_exception(win32rawprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a win32raw printer object
|
||||
WHEN open() is set to raise a DeviceNotFoundError on error
|
||||
THEN check the exception is raised
|
||||
"""
|
||||
win32rawprinter.printer_name = "fake_printer"
|
||||
|
||||
with pytest.raises(devicenotfounderror):
|
||||
win32rawprinter.open(raise_not_found=True)
|
||||
|
||||
|
||||
def test_open_not_raise_exception(win32rawprinter, caplog):
|
||||
"""
|
||||
GIVEN a win32raw printer object
|
||||
WHEN open() is set to not raise on error but simply cancel
|
||||
THEN check the error is logged and open() canceled
|
||||
"""
|
||||
win32rawprinter.printer_name = "fake_printer"
|
||||
|
||||
with caplog.at_level(logging.ERROR):
|
||||
win32rawprinter.open(raise_not_found=False)
|
||||
|
||||
assert "not available" in caplog.text
|
||||
assert win32rawprinter.device is None
|
||||
|
||||
|
||||
def test_open(win32rawprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a win32raw printer object and a mocked win32printer device
|
||||
WHEN a valid connection to a device is opened
|
||||
THEN check the success is logged and the device property is set
|
||||
"""
|
||||
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
|
||||
PyPrinterHANDLE = mocker.Mock()
|
||||
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
|
||||
|
||||
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
|
||||
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
|
||||
|
||||
# Configure and assert printer_name is valid
|
||||
win32rawprinter.printer_name = "test_printer"
|
||||
assert win32rawprinter.printer_name in win32rawprinter.printers
|
||||
|
||||
with caplog.at_level(logging.INFO):
|
||||
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
|
||||
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
|
||||
win32rawprinter.open()
|
||||
|
||||
assert "enabled" in caplog.text
|
||||
assert win32rawprinter.device == PyPrinterHANDLE.return_value
|
||||
|
||||
|
||||
def test_close_on_reopen(win32rawprinter, mocker):
|
||||
"""
|
||||
GIVEN a win32raw printer object and a mocked win32print device
|
||||
WHEN a valid connection to a device is reopened before close
|
||||
THEN check the close method is called if _device
|
||||
"""
|
||||
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
|
||||
PyPrinterHANDLE = mocker.Mock()
|
||||
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
|
||||
|
||||
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
|
||||
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
|
||||
|
||||
# Configure printer_name
|
||||
win32rawprinter.printer_name = "test_printer"
|
||||
|
||||
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
|
||||
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
|
||||
# Patch the win32print close methods
|
||||
mocker.patch("win32print.EndPagePrinter")
|
||||
mocker.patch("win32print.EndDocPrinter")
|
||||
mocker.patch("win32print.ClosePrinter")
|
||||
|
||||
spy = mocker.spy(win32rawprinter, "close")
|
||||
# Simulate a reopen before close
|
||||
win32rawprinter._device = True
|
||||
win32rawprinter.open()
|
||||
|
||||
spy.assert_called_once()
|
||||
|
||||
|
||||
def test_close(win32rawprinter, caplog, mocker):
|
||||
"""
|
||||
GIVEN a win32raw printer object and a mocked win32print device
|
||||
WHEN a connection is opened and closed
|
||||
THEN check the closing is logged and the device property is False
|
||||
"""
|
||||
# The _win32typing.PyPrinterHANDLE object is unreachable, so we have to mock it
|
||||
PyPrinterHANDLE = mocker.Mock()
|
||||
PyPrinterHANDLE.return_value = 0 # Accepts 0 or None as return value
|
||||
|
||||
# Replace the contents of Win32Raw.printers to accept test_printer as a system's printer name
|
||||
mocker.patch("escpos.printer.Win32Raw.printers", new={"test_printer": "Test"})
|
||||
|
||||
# Configure and assert printer_name is valid
|
||||
win32rawprinter.printer_name = "test_printer"
|
||||
assert win32rawprinter.printer_name in win32rawprinter.printers
|
||||
|
||||
# Patch the win32print.OpenPrinter method to return the mocked PyPrinterHANDLE
|
||||
mocker.patch("win32print.OpenPrinter", new=PyPrinterHANDLE)
|
||||
win32rawprinter.open()
|
||||
with caplog.at_level(logging.INFO):
|
||||
# Patch the win32print close methods
|
||||
# Raises a warning but passes the test
|
||||
mocker.patch("win32print.EndPagePrinter")
|
||||
mocker.patch("win32print.EndDocPrinter")
|
||||
mocker.patch("win32print.ClosePrinter")
|
||||
win32rawprinter.close()
|
||||
|
||||
assert "Closing" in caplog.text
|
||||
assert win32rawprinter._device is False
|
||||
|
||||
|
||||
def test_raw_raise_exception(win32rawprinter, devicenotfounderror):
|
||||
"""
|
||||
GIVEN a win32raw printer object and a mocked win32print device
|
||||
WHEN calling _raw() before configuring the connection
|
||||
THEN check an exception is raised
|
||||
"""
|
||||
win32rawprinter.printer_name = None
|
||||
with pytest.raises(devicenotfounderror):
|
||||
win32rawprinter._raw(b"Test error")
|
||||
|
||||
win32rawprinter.printer_name = "fake_printer"
|
||||
win32rawprinter.device = None
|
||||
with pytest.raises(devicenotfounderror):
|
||||
win32rawprinter._raw(b"Test error")
|
||||
|
||||
|
||||
def test_raw(win32rawprinter, mocker):
|
||||
"""
|
||||
GIVEN a win32raw printer object and a mocked win32print device
|
||||
WHEN calling _raw() after a valid connection
|
||||
THEN check the underlying method is correctly called
|
||||
"""
|
||||
PyPrinterHANDLE = mocker.Mock()
|
||||
PyPrinterHANDLE.return_value = 0
|
||||
|
||||
mocked_writer = mocker.patch("win32print.WritePrinter")
|
||||
|
||||
win32rawprinter._device = PyPrinterHANDLE
|
||||
win32rawprinter._raw(b"Test error")
|
||||
|
||||
mocked_writer.assert_called_once_with(PyPrinterHANDLE, b"Test error")
|
Loading…
Reference in New Issue