1
0
mirror of https://github.com/python-escpos/python-escpos synced 2025-08-24 09:03:34 +00:00

More mypy (#612)

* remove type comment where type is annotated
* move function tests
* remove six from tests
* add none annotations
* add more types
* change mock (so that mypy understands it)
This commit is contained in:
Patrick Kanzler
2023-12-16 23:09:20 +01:00
committed by GitHub
parent 66a2e78e16
commit 0c824cf295
19 changed files with 40 additions and 41 deletions

View File

@@ -0,0 +1,57 @@
#!/usr/bin/python
import pytest
import escpos.printer as printer
from escpos.capabilities import BARCODE_B, Profile
from escpos.exceptions import BarcodeCodeError, BarcodeTypeError
@pytest.mark.parametrize(
"bctype,data,expected",
[
(
"EAN13",
"4006381333931",
b"\x1ba\x01\x1dh@\x1dw\x03\x1df\x00\x1dH\x02\x1dk\x024006381333931\x00",
)
],
)
def test_barcode(bctype, data, expected):
"""should generate different barcode types correctly."""
instance = printer.Dummy()
instance.barcode(data, bctype)
assert instance.output == expected
@pytest.mark.parametrize(
"bctype,supports_b",
[
("invalid", True),
("CODE128", False),
],
)
def test_lacks_support(bctype, supports_b):
"""should raise an error if the barcode type is not supported."""
profile = Profile(features={BARCODE_B: supports_b})
instance = printer.Dummy(profile=profile)
with pytest.raises(BarcodeTypeError):
instance.barcode("test", bctype)
assert instance.output == b""
@pytest.mark.parametrize(
"bctype,data",
[
("EAN13", "AA"),
("CODE128", "{D2354AA"),
],
)
def test_code_check(bctype, data):
"""should raise an error if the barcode code is invalid."""
instance = printer.Dummy()
with pytest.raises(BarcodeCodeError):
instance.barcode(data, bctype)
assert instance.output == b""

View File

@@ -0,0 +1,55 @@
import pytest
from escpos import printer
from escpos.constants import BUZZER
def test_buzzer_function_with_default_params() -> None:
instance = printer.Dummy()
instance.buzzer()
expected = BUZZER + bytes((2, 4))
assert instance.output == expected
@pytest.mark.parametrize(
"times, duration",
[
[1, 1],
[2, 2],
[3, 3],
[4, 4],
[5, 5],
[6, 6],
[7, 7],
[8, 8],
[9, 9],
],
)
def test_buzzer_function(times: int, duration: int) -> None:
instance = printer.Dummy()
instance.buzzer(times, duration)
expected = BUZZER + bytes((times, duration))
assert instance.output == expected
@pytest.mark.parametrize(
"times, duration, expected_message",
[
[0, 0, "times must be between 1 and 9"],
[-1, 0, "times must be between 1 and 9"],
[10, 0, "times must be between 1 and 9"],
[11, 0, "times must be between 1 and 9"],
[3, 0, "duration must be between 1 and 9"],
[3, -1, "duration must be between 1 and 9"],
[3, 10, "duration must be between 1 and 9"],
[3, 11, "duration must be between 1 and 9"],
],
)
def test_buzzer_fuction_with_outrange_values(
times: int, duration: int, expected_message: str
) -> None:
instance = printer.Dummy()
with pytest.raises(ValueError) as e:
instance.buzzer(times, duration)
assert str(e.value) == expected_message

View File

@@ -0,0 +1,14 @@
#!/usr/bin/python
import pytest
import escpos.printer as printer
from escpos.exceptions import CashDrawerError
def test_raise_CashDrawerError() -> None:
"""should raise an error if the sequence is invalid."""
instance = printer.Dummy()
with pytest.raises(CashDrawerError):
# call with sequence that is too long
instance.cashdraw([1, 1, 1, 1, 1, 1])

View File

@@ -0,0 +1,107 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import pytest
import escpos.escpos
@pytest.mark.parametrize(
"bctype,data",
[
("UPC-A", "01234567890"),
("UPC-A", "012345678905"),
("UPC-E", "01234567"),
("UPC-E", "0123456"),
("UPC-E", "012345678905"),
("EAN13", "0123456789012"),
("EAN13", "012345678901"),
("EAN8", "01234567"),
("EAN8", "0123456"),
("CODE39", "ABC-1234"),
("CODE39", "ABC-1234-$$-+A"),
("CODE39", "*WIKIPEDIA*"),
("ITF", "010203040506070809"),
("ITF", "11221133113344556677889900"),
("CODABAR", "A2030405060B"),
("CODABAR", "C11221133113344556677889900D"),
("CODABAR", "D0D"),
("NW7", "A2030405060B"),
("NW7", "C11221133113344556677889900D"),
("NW7", "D0D"),
("CODE93", "A2030405060B"),
("CODE93", "+:$&23-7@$"),
("CODE93", "D0D"),
("CODE128", "{A2030405060B"),
("CODE128", "{C+:$&23-7@$"),
("CODE128", "{B0D"),
("GS1-128", "{A2030405060B"),
("GS1-128", "{C+:$&23-7@$"),
("GS1-128", "{B0D"),
("GS1 DATABAR OMNIDIRECTIONAL", "0123456789123"),
("GS1 DATABAR TRUNCATED", "0123456789123"),
("GS1 DATABAR LIMITED", "0123456789123"),
("GS1 DATABAR EXPANDED", "(9A{A20304+-%&06a0B"),
("GS1 DATABAR EXPANDED", "(1 {C+:&23-7%"),
("GS1 DATABAR EXPANDED", "(00000001234567678"),
],
)
def test_check_valid_barcode(bctype, data):
assert escpos.escpos.Escpos.check_barcode(bctype, data)
@pytest.mark.parametrize(
"bctype,data",
[
("UPC-A", "01234567890123"), # too long
("UPC-A", "0123456789"), # too short
("UPC-A", "72527273-711"), # invalid '-'
("UPC-A", "A12345678901"), # invalid 'A'
("UPC-E", "01234567890123"), # too long
("UPC-E", "012345"), # too short
("UPC-E", "72527-2"), # invalid '-'
("UPC-E", "A123456"), # invalid 'A'
("EAN13", "0123456789"), # too short
("EAN13", "A123456789012"), # invalid 'A'
("EAN13", "012345678901234"), # too long
("EAN8", "012345"), # too short
("EAN8", "A123456789012"), # invalid 'A'
("EAN8", "012345678901234"), # too long
("CODE39", "ALKJ_34"), # invalid '_'
("CODE39", "A" * 256), # too long
("ITF", "010203040"), # odd length
("ITF", "0" * 256), # too long
("ITF", "AB01"), # invalid 'A'
("CODABAR", "010203040"), # no start/stop
("CODABAR", "0" * 256), # too long
("CODABAR", "AB-01F"), # invalid 'B'
("NW7", "010203040"), # no start/stop
("NW7", "0" * 256), # too long
("NW7", "AB-01F"), # invalid 'B'
("CODE93", "é010203040"), # invalid 'é'
("CODE93", "0" * 256), # too long
("CODE128", "010203040"), # missing leading {
("CODE128", "{D2354AA"), # second char not between A-C
("CODE128", "0" * 256), # too long
("GS1-128", "010203040"), # missing leading {
("GS1-128", "{D2354AA"), # second char not between A-C
("GS1-128", "0" * 256), # too long
("GS1 DATABAR OMNIDIRECTIONAL", "01234567891234"), # too long
("GS1 DATABAR OMNIDIRECTIONAL", "012345678912"), # too short
("GS1 DATABAR OMNIDIRECTIONAL", "012345678A1234"), # invalid 'A'
("GS1 DATABAR TRUNCATED", "01234567891234"), # too long
("GS1 DATABAR TRUNCATED", "012345678912"), # too short
("GS1 DATABAR TRUNCATED", "012345678A1234"), # invalid 'A'
("GS1 DATABAR LIMITED", "01234567891234"), # too long
("GS1 DATABAR LIMITED", "012345678912"), # too short
("GS1 DATABAR LIMITED", "012345678A1234"), # invalid 'A'
("GS1 DATABAR LIMITED", "02345678912341"), # invalid start (should be 01)
("GS1 DATABAR EXPANDED", "010203040"), # missing leading (
("GS1-128", "(" + ("0" * 256)), # too long
("GS1 DATABAR EXPANDED", "(a{D2354AA"), # second char not between 0-9
("GS1 DATABAR EXPANDED", "IT will fail"), # first char not '('
],
)
def test_check_invalid_barcode(bctype, data):
assert not escpos.escpos.Escpos.check_barcode(bctype, data)

View File

@@ -0,0 +1,10 @@
import escpos.printer as printer
from escpos.constants import GS
def test_cut_without_feed() -> None:
"""Test cut without feeding paper"""
instance = printer.Dummy()
instance.cut(feed=False)
expected = GS + b"V" + bytes((66,)) + b"\x00"
assert instance.output == expected

View File

@@ -0,0 +1,8 @@
from escpos.printer import Dummy
def test_printer_dummy_clear() -> None:
printer = Dummy()
printer.text("Hello")
printer.clear()
assert printer.output == b""

View File

@@ -0,0 +1,189 @@
#!/usr/bin/env python
""" Image function tests- Check that image print commands are sent correctly.
:author: `Michael Billington <michael.billington@gmail.com>`_
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2016 `Michael Billington <michael.billington@gmail.com>`_
:license: MIT
"""
import pytest
from PIL import Image
import escpos.printer as printer
from escpos.exceptions import ImageWidthError
# Raster format print
def test_bit_image_black() -> None:
"""
Test printing solid black bit image (raster)
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_black.png", impl="bitImageRaster")
assert instance.output == b"\x1dv0\x00\x01\x00\x01\x00\x80"
# Same thing w/ object created on the fly, rather than a filename
instance = printer.Dummy()
im = Image.new("RGB", (1, 1), (0, 0, 0))
instance.image(im, impl="bitImageRaster")
assert instance.output == b"\x1dv0\x00\x01\x00\x01\x00\x80"
def test_bit_image_white() -> None:
"""
Test printing solid white bit image (raster)
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_white.png", impl="bitImageRaster")
assert instance.output == b"\x1dv0\x00\x01\x00\x01\x00\x00"
def test_bit_image_both() -> None:
"""
Test printing black/white bit image (raster)
"""
instance = printer.Dummy()
instance.image("test/resources/black_white.png", impl="bitImageRaster")
assert instance.output == b"\x1dv0\x00\x01\x00\x02\x00\xc0\x00"
def test_bit_image_transparent() -> None:
"""
Test printing black/transparent bit image (raster)
"""
instance = printer.Dummy()
instance.image("test/resources/black_transparent.png", impl="bitImageRaster")
assert instance.output == b"\x1dv0\x00\x01\x00\x02\x00\xc0\x00"
# Column format print
def test_bit_image_colfmt_black() -> None:
"""
Test printing solid black bit image (column format)
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_black.png", impl="bitImageColumn")
assert instance.output == b"\x1b3\x10\x1b*!\x01\x00\x80\x00\x00\x0a\x1b2"
def test_bit_image_colfmt_white() -> None:
"""
Test printing solid white bit image (column format)
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_white.png", impl="bitImageColumn")
assert instance.output == b"\x1b3\x10\x1b*!\x01\x00\x00\x00\x00\x0a\x1b2"
def test_bit_image_colfmt_both() -> None:
"""
Test printing black/white bit image (column format)
"""
instance = printer.Dummy()
instance.image("test/resources/black_white.png", impl="bitImageColumn")
assert (
instance.output == b"\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"
)
def test_bit_image_colfmt_transparent() -> None:
"""
Test printing black/transparent bit image (column format)
"""
instance = printer.Dummy()
instance.image("test/resources/black_transparent.png", impl="bitImageColumn")
assert (
instance.output == b"\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"
)
# Graphics print
def test_graphics_black() -> None:
"""
Test printing solid black graphics
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_black.png", impl="graphics")
assert (
instance.output
== b"\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x80\x1d(L\x02\x0002"
)
def test_graphics_white() -> None:
"""
Test printing solid white graphics
"""
instance = printer.Dummy()
instance.image("test/resources/canvas_white.png", impl="graphics")
assert (
instance.output
== b"\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x00\x1d(L\x02\x0002"
)
def test_graphics_both() -> None:
"""
Test printing black/white graphics
"""
instance = printer.Dummy()
instance.image("test/resources/black_white.png", impl="graphics")
assert (
instance.output
== b"\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"
)
def test_graphics_transparent() -> None:
"""
Test printing black/transparent graphics
"""
instance = printer.Dummy()
instance.image("test/resources/black_transparent.png", impl="graphics")
assert (
instance.output
== b"\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"
)
def test_large_graphics() -> None:
"""
Test whether 'large' graphics that induce a fragmentation are handled correctly.
"""
instance = printer.Dummy()
instance.image(
"test/resources/black_white.png", impl="bitImageRaster", fragment_height=1
)
assert (
instance.output
== b"\x1dv0\x00\x01\x00\x01\x00\xc0\x1dv0\x00\x01\x00\x01\x00\x00"
)
@pytest.fixture
def dummy_with_width() -> printer.Dummy:
instance = printer.Dummy()
instance.profile.profile_data = {"media": {"width": {"pixels": 384}}}
return instance
def test_width_too_large(dummy_with_width: printer.Dummy) -> None:
"""
Test printing an image that is too large in width.
"""
instance = dummy_with_width
with pytest.raises(ImageWidthError):
instance.image(Image.new("RGB", (385, 200)))
instance.image(Image.new("RGB", (384, 200)))
def test_center_image(dummy_with_width: printer.Dummy) -> None:
instance = dummy_with_width
with pytest.raises(ImageWidthError):
instance.image(Image.new("RGB", (385, 200)), center=True)
instance.image(Image.new("RGB", (384, 200)), center=True)

View File

@@ -0,0 +1,32 @@
#!/usr/bin/python
"""tests for line display
:author: `Patrick Kanzler <dev@pkanzler.de>`_
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2017 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import escpos.printer as printer
def test_function_linedisplay_select_on() -> None:
"""test the linedisplay_select function (activate)"""
instance = printer.Dummy()
instance.linedisplay_select(select_display=True)
assert instance.output == b"\x1B\x3D\x02"
def test_function_linedisplay_select_off() -> None:
"""test the linedisplay_select function (deactivate)"""
instance = printer.Dummy()
instance.linedisplay_select(select_display=False)
assert instance.output == b"\x1B\x3D\x01"
def test_function_linedisplay_clear() -> None:
"""test the linedisplay_clear function"""
instance = printer.Dummy()
instance.linedisplay_clear()
assert instance.output == b"\x1B\x40"

View File

@@ -0,0 +1,25 @@
#!/usr/bin/python
"""tests for panel button function
: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 escpos.printer as printer
def test_function_panel_button_on() -> None:
"""test the panel button function (enabling) by comparing output"""
instance = printer.Dummy()
instance.panel_buttons()
assert instance.output == b"\x1B\x63\x35\x00"
def test_function_panel_button_off() -> None:
"""test the panel button function (disabling) by comparing output"""
instance = printer.Dummy()
instance.panel_buttons(False)
assert instance.output == b"\x1B\x63\x35\x01"

View File

@@ -0,0 +1,103 @@
#!/usr/bin/python
"""test native QR code printing
:author: `Michael Billington <michael.billington@gmail.com>`_
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `Michael Billington <michael.billington@gmail.com>`_
:license: MIT
"""
import pytest
import escpos.printer as printer
from escpos.constants import QR_ECLEVEL_H, QR_MODEL_1
def test_defaults() -> None:
"""Test QR code with defaults"""
instance = printer.Dummy()
instance.qr("1234", native=True)
expected = (
b"\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d"
b"(k\x07\x001P01234\x1d(k\x03\x001Q0"
)
assert instance.output == expected
def test_empty() -> None:
"""Test QR printing blank code"""
instance = printer.Dummy()
instance.qr("", native=True)
assert instance.output == b""
def test_ec() -> None:
"""Test QR error correction setting"""
instance = printer.Dummy()
instance.qr("1234", native=True, ec=QR_ECLEVEL_H)
expected = (
b"\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E3\x1d"
b"(k\x07\x001P01234\x1d(k\x03\x001Q0"
)
assert instance.output == expected
def test_size() -> None:
"""Test QR box size"""
instance = printer.Dummy()
instance.qr("1234", native=True, size=7)
expected = (
b"\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x07\x1d(k\x03\x001E0\x1d"
b"(k\x07\x001P01234\x1d(k\x03\x001Q0"
)
assert instance.output == expected
def test_model() -> None:
"""Test QR model"""
instance = printer.Dummy()
instance.qr("1234", native=True, model=QR_MODEL_1)
expected = (
b"\x1d(k\x04\x001A1\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d"
b"(k\x07\x001P01234\x1d(k\x03\x001Q0"
)
assert instance.output == expected
def test_invalid_ec() -> None:
"""Test invalid QR error correction"""
instance = printer.Dummy()
with pytest.raises(ValueError):
instance.qr("1234", native=True, ec=-1)
def test_invalid_size() -> None:
"""Test invalid QR size"""
instance = printer.Dummy()
with pytest.raises(ValueError):
instance.qr("1234", native=True, size=0)
def test_invalid_model() -> None:
"""Test invalid QR model"""
instance = printer.Dummy()
with pytest.raises(ValueError):
instance.qr("1234", native=True, model="Hello")
def test_image_invalid_model() -> None:
"""Test unsupported QR model as image"""
instance = printer.Dummy()
with pytest.raises(ValueError):
instance.qr("1234", native=False, model=QR_MODEL_1)
@pytest.fixture
def instance():
return printer.Dummy()
def test_center_not_implementer(instance: printer.Dummy) -> None:
with pytest.raises(NotImplementedError):
instance.qr("test", center=True, native=True)

View File

@@ -0,0 +1,99 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""tests for the non-native part of qr()
:author: `Patrick Kanzler <dev@pkanzler.de>`_
:organization: `python-escpos <https://github.com/python-escpos>`_
:copyright: Copyright (c) 2023 `python-escpos <https://github.com/python-escpos>`_
:license: MIT
"""
import warnings
import mock
import pytest
from PIL import Image
from escpos.printer import Dummy
def test_image() -> None:
"""Test QR as image"""
instance = Dummy()
image_arguments = {
"high_density_vertical": True,
"high_density_horizontal": True,
"impl": "bitImageRaster",
"fragment_height": 960,
"center": False,
}
instance.qr("1", native=False, image_arguments=image_arguments, size=1)
print(instance.output)
expected = (
b"\x1bt\x00\n"
b"\x1dv0\x00\x03\x00\x17\x00\x00\x00\x00\x7f\x1d\xfcAu\x04]\x1dt]et"
b"]%tAI\x04\x7fU\xfc\x00 \x00}\xca\xa8h\xdf u\x95\x80x/ \x0b\xf4\x98\x00"
b"T\x90\x7fzxA\x00\xd0]zp]o ]u\x80Ao(\x7fd\x90\x00\x00\x00"
b"\n\n"
)
assert instance.output == expected
@mock.patch("escpos.printer.Dummy.image", spec=Dummy)
def test_type_of_object_passed_to_image_function(img_function):
"""
Test the type of object that is passed to the image function during non-native qr-printing.
The type should be PIL.Image
"""
d = Dummy()
d.qr("LoremIpsum")
args, kwargs = img_function.call_args
assert isinstance(args[0], Image.Image)
@mock.patch("escpos.printer.Dummy.image", spec=Dummy)
def test_parameter_image_arguments_passed_to_image_function(img_function):
"""Test the parameter passed to non-native qr printing."""
d = Dummy()
d.qr(
"LoremIpsum",
native=False,
image_arguments={
"impl": "bitImageColumn",
"high_density_vertical": False,
"center": True,
},
)
args, kwargs = img_function.call_args
assert "impl" in kwargs
assert kwargs["impl"] == "bitImageColumn"
assert "high_density_vertical" in kwargs
assert kwargs["high_density_vertical"] is False
assert "center" in kwargs
assert kwargs["center"]
@pytest.fixture
def instance():
return Dummy()
def test_center(instance):
"""Test printing qr codes."""
instance.qr("LoremIpsum", center=True)
def test_deprecated_arguments(instance):
"""Test deprecation warning."""
with warnings.catch_warnings(record=True) as w:
# cause all warnings to always be triggered
warnings.simplefilter("always")
instance.qr(
"LoremIpsum",
impl="bitImageRaster",
image_arguments={"impl": "bitImageColumn"},
)
assert issubclass(w[-1].category, DeprecationWarning)
assert "deprecated" in str(w[-1].message)

View File

@@ -0,0 +1,374 @@
from typing import Optional
import pytest
import escpos.printer as printer
from escpos.constants import SET_FONT, TXT_NORMAL, TXT_SIZE, TXT_STYLE
from escpos.exceptions import SetVariableError
def test_default_values_with_default() -> None:
"""Default test, please copy and paste this block to test set method calls"""
instance = printer.Dummy()
instance.set_with_default()
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_default_values() -> None:
"""Default test"""
instance = printer.Dummy()
instance.set()
assert instance.output == b""
# Size tests
def test_set_size_2h() -> None:
instance = printer.Dummy()
instance.set_with_default(double_height=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2h"], # Double height text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_2h_no_default() -> None:
instance = printer.Dummy()
instance.set(double_height=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2h"], # Double height text size
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_2w() -> None:
instance = printer.Dummy()
instance.set_with_default(double_width=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2w"], # Double width text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_2w_no_default() -> None:
instance = printer.Dummy()
instance.set(double_width=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2w"], # Double width text size
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_2x() -> None:
instance = printer.Dummy()
instance.set_with_default(double_height=True, double_width=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2x"], # Double text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_2x_no_default() -> None:
instance = printer.Dummy()
instance.set(double_width=True, double_height=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["2x"], # Quad area text size
)
assert instance.output == b"".join(expected_sequence)
def test_set_size_custom() -> None:
instance = printer.Dummy()
instance.set_with_default(custom_size=True, width=8, height=7)
expected_sequence = (
TXT_SIZE, # Custom text size, no normal reset
bytes((TXT_STYLE["width"][8] + TXT_STYLE["height"][7],)),
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
@pytest.mark.parametrize("width", [1, 8])
@pytest.mark.parametrize("height", [1, 8])
def test_set_size_custom_no_default(width: int, height: int) -> None:
instance = printer.Dummy()
instance.set(custom_size=True, width=width, height=height)
expected_sequence = (
TXT_SIZE, # Custom text size, no normal reset
bytes((TXT_STYLE["width"][width] + TXT_STYLE["height"][height],)),
)
assert instance.output == b"".join(expected_sequence)
@pytest.mark.parametrize("width", [None, 0, 9, 10, 4444])
@pytest.mark.parametrize("height", [None, 0, 9, 10, 4444])
def test_set_size_custom_invalid_input(
width: Optional[int], height: Optional[int]
) -> None:
instance = printer.Dummy()
with pytest.raises(SetVariableError):
instance.set(custom_size=True, width=width, height=height)
# Flip
def test_set_flip() -> None:
instance = printer.Dummy()
instance.set_with_default(flip=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][True], # Flip ON
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_flip_no_default() -> None:
instance = printer.Dummy()
instance.set(flip=True)
expected_sequence = (TXT_STYLE["flip"][True],) # Flip ON
assert instance.output == b"".join(expected_sequence)
# Smooth
def test_smooth() -> None:
instance = printer.Dummy()
instance.set_with_default(smooth=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][True], # Smooth ON
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
# Type
def test_set_bold() -> None:
instance = printer.Dummy()
instance.set_with_default(bold=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][True], # Bold ON
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_underline() -> None:
instance = printer.Dummy()
instance.set_with_default(underline=1)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][1], # Underline ON, type 1
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_set_underline2() -> None:
instance = printer.Dummy()
instance.set_with_default(underline=2)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][2], # Underline ON, type 2
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
# Align
def test_align_center() -> None:
instance = printer.Dummy()
instance.set_with_default(align="center")
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["center"], # Align center
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
def test_align_right() -> None:
instance = printer.Dummy()
instance.set_with_default(align="right")
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["right"], # Align right
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
# Densities
def test_densities() -> None:
for density in range(8):
instance = printer.Dummy()
instance.set_with_default(density=density)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["density"][density], # Custom density from 0 to 8
TXT_STYLE["invert"][False], # Inverted OFF
)
assert instance.output == b"".join(expected_sequence)
# Invert
def test_invert() -> None:
instance = printer.Dummy()
instance.set_with_default(invert=True)
expected_sequence = (
TXT_NORMAL,
TXT_STYLE["size"]["normal"], # Normal text size
TXT_STYLE["flip"][False], # Flip OFF
TXT_STYLE["smooth"][False], # Smooth OFF
TXT_STYLE["bold"][False], # Bold OFF
TXT_STYLE["underline"][0], # Underline OFF
SET_FONT(b"\x00"), # Default font
TXT_STYLE["align"]["left"], # Align left
TXT_STYLE["invert"][True], # Inverted ON
)
assert instance.output == b"".join(expected_sequence)

View File

@@ -0,0 +1,26 @@
#!/usr/bin/python
import barcode.errors
import pytest
import escpos.printer as printer
@pytest.fixture
def instance():
return printer.Dummy()
def test_soft_barcode_ean8_invalid(instance: printer.Dummy) -> None:
"""test with an invalid barcode"""
with pytest.raises(barcode.errors.BarcodeError):
instance.barcode("1234", "ean8", force_software=True)
def test_soft_barcode_ean8(instance: printer.Dummy) -> None:
"""test with a valid ean8 barcode"""
instance.barcode("1234567", "ean8", force_software=True)
def test_soft_barcode_ean8_nocenter(instance: printer.Dummy) -> None:
instance.barcode("1234567", "ean8", align_ct=False, force_software=True)

View File

@@ -0,0 +1,62 @@
#!/usr/bin/python
"""tests for the text printing function
: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 hypothesis.strategies as st
import mock
from hypothesis import given
from escpos.printer import Dummy
def get_printer() -> Dummy:
return Dummy(magic_encode_args={"disabled": True, "encoding": "CP437"})
@given(text=st.text())
def test_text(text: str):
"""Test that text() calls the MagicEncode object."""
instance = get_printer()
with mock.patch.object(instance.magic, "write") as write:
instance.text(text)
write.assert_called_with(text)
def test_block_text() -> None:
printer = get_printer()
printer.block_text(
"All the presidents men were eating falafel for breakfast.", font="a"
)
assert (
printer.output == b"All the presidents men were eating falafel\nfor breakfast."
)
def test_textln() -> None:
printer = get_printer()
printer.textln("hello, world")
assert printer.output == b"hello, world\n"
def test_textln_empty() -> None:
printer = get_printer()
printer.textln()
assert printer.output == b"\n"
def test_ln() -> None:
printer = get_printer()
printer.ln()
assert printer.output == b"\n"
def test_multiple_ln() -> None:
printer = get_printer()
printer.ln(3)
assert printer.output == b"\n\n\n"

View File

@@ -0,0 +1,27 @@
import pytest
from escpos.printer import Dummy
def test_line_spacing_code_gen() -> None:
printer = Dummy()
printer.line_spacing(10)
assert printer.output == b"\x1b3\n"
def test_line_spacing_rest() -> None:
printer = Dummy()
printer.line_spacing()
assert printer.output == b"\x1b2"
def test_line_spacing_error_handling() -> None:
printer = Dummy()
with pytest.raises(ValueError):
printer.line_spacing(99, divisor=44)
with pytest.raises(ValueError):
printer.line_spacing(divisor=80, spacing=86)
with pytest.raises(ValueError):
printer.line_spacing(divisor=360, spacing=256)
with pytest.raises(ValueError):
printer.line_spacing(divisor=180, spacing=256)