Compare commits
No commits in common. "master" and "v3.1" have entirely different histories.
10
.github/workflows/pythonpackage-windows.yml
vendored
10
.github/workflows/pythonpackage-windows.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5.2.0
|
uses: actions/setup-python@v5.0.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@ -44,14 +44,12 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
ESCPOS_CAPABILITIES_FILE: D:\a\python-escpos\python-escpos\capabilities-data\dist\capabilities.json
|
ESCPOS_CAPABILITIES_FILE: D:\a\python-escpos\python-escpos\capabilities-data\dist\capabilities.json
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v3
|
||||||
env:
|
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
|
directory: ./coverage/reports/
|
||||||
env_vars: OS,PYTHON
|
env_vars: OS,PYTHON
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
files: ./coverage.xml
|
files: ./coverage.xml,!./cache
|
||||||
exclude: "**/.mypy_cache"
|
|
||||||
flags: unittests
|
flags: unittests
|
||||||
name: coverage-tox-${{ matrix.python-version }}
|
name: coverage-tox-${{ matrix.python-version }}
|
||||||
verbose: true
|
verbose: true
|
||||||
|
10
.github/workflows/pythonpackage.yml
vendored
10
.github/workflows/pythonpackage.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: 'recursive'
|
submodules: 'recursive'
|
||||||
- name: Set up Python ${{ matrix.python-version }}
|
- name: Set up Python ${{ matrix.python-version }}
|
||||||
uses: actions/setup-python@v5.2.0
|
uses: actions/setup-python@v5.0.0
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: ${{ matrix.python-version }}
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@ -54,14 +54,12 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
ESCPOS_CAPABILITIES_FILE: /home/runner/work/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
|
ESCPOS_CAPABILITIES_FILE: /home/runner/work/python-escpos/python-escpos/capabilities-data/dist/capabilities.json
|
||||||
- name: Upload coverage to Codecov
|
- name: Upload coverage to Codecov
|
||||||
uses: codecov/codecov-action@v4
|
uses: codecov/codecov-action@v3
|
||||||
env:
|
|
||||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
|
||||||
with:
|
with:
|
||||||
|
directory: ./coverage/reports/
|
||||||
env_vars: OS,PYTHON
|
env_vars: OS,PYTHON
|
||||||
fail_ci_if_error: true
|
fail_ci_if_error: true
|
||||||
files: ./coverage.xml
|
files: ./coverage.xml,!./cache
|
||||||
exclude: "**/.mypy_cache"
|
|
||||||
flags: unittests
|
flags: unittests
|
||||||
name: coverage-tox-${{ matrix.python-version }}
|
name: coverage-tox-${{ matrix.python-version }}
|
||||||
verbose: true
|
verbose: true
|
||||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -12,7 +12,7 @@
|
|||||||
"editor.formatOnPaste": true,
|
"editor.formatOnPaste": true,
|
||||||
"python.formatting.provider": "black",
|
"python.formatting.provider": "black",
|
||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.organizeImports": "explicit"
|
"source.organizeImports": true
|
||||||
},
|
},
|
||||||
"python.testing.unittestEnabled": false,
|
"python.testing.unittestEnabled": false,
|
||||||
"python.testing.pytestEnabled": true,
|
"python.testing.pytestEnabled": true,
|
||||||
|
@ -1,18 +1,6 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
202x-xx-xx - Version 3.x - ""
|
|
||||||
-------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
changes
|
|
||||||
^^^^^^^
|
|
||||||
|
|
||||||
|
|
||||||
contributors
|
|
||||||
^^^^^^^^^^^^
|
|
||||||
|
|
||||||
|
|
||||||
2023-12-17 - Version 3.1 - "Rubric Of Ruin"
|
2023-12-17 - Version 3.1 - "Rubric Of Ruin"
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
This is the minor release of the new version 3.1.
|
This is the minor release of the new version 3.1.
|
||||||
|
@ -100,4 +100,4 @@ Disclaimer
|
|||||||
|
|
||||||
None of the vendors cited in this project agree or endorse any of the
|
None of the vendors cited in this project agree or endorse any of the
|
||||||
patterns or implementations.
|
patterns or implementations.
|
||||||
Their names are used only to maintain context.
|
Its names are used only to maintain context.
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit e3bf6056ee75cf70ffaccb925081fffa7ad6ced5
|
Subproject commit 4006299c0fa82bc4d4c297663628346ce3eff6c5
|
@ -91,7 +91,6 @@ docstrings
|
|||||||
ean
|
ean
|
||||||
Ean
|
Ean
|
||||||
encodable
|
encodable
|
||||||
Errno
|
|
||||||
fff
|
fff
|
||||||
fullimage
|
fullimage
|
||||||
io
|
io
|
||||||
@ -125,7 +124,6 @@ Todo
|
|||||||
traceback
|
traceback
|
||||||
udev
|
udev
|
||||||
usb
|
usb
|
||||||
USBTimeoutError
|
|
||||||
usec
|
usec
|
||||||
virtualenvs
|
virtualenvs
|
||||||
whitespaces
|
whitespaces
|
||||||
|
@ -213,14 +213,6 @@ If something is wrong, an ``CharCodeError`` will be raised.
|
|||||||
After you have manually set the codepage the printer won't change it anymore.
|
After you have manually set the codepage the printer won't change it anymore.
|
||||||
You can revert to normal behavior by setting charcode to ``AUTO``.
|
You can revert to normal behavior by setting charcode to ``AUTO``.
|
||||||
|
|
||||||
Resolving bus timeout issues during printing images
|
|
||||||
---------------------------------------------------
|
|
||||||
|
|
||||||
If an error message such as "USBTimeoutError: [Errno 110] Operation timed out" occurs,
|
|
||||||
setting a sleep time between printing fragments can help.
|
|
||||||
|
|
||||||
This can be done with the :meth:`.set_sleep_in_fragment()` method.
|
|
||||||
|
|
||||||
Advanced Usage: Print from binary blob
|
Advanced Usage: Print from binary blob
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@ blinker==1.6.2
|
|||||||
click==8.1.3
|
click==8.1.3
|
||||||
Flask==2.3.2
|
Flask==2.3.2
|
||||||
itsdangerous==2.1.2
|
itsdangerous==2.1.2
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.2
|
||||||
MarkupSafe==2.1.2
|
MarkupSafe==2.1.2
|
||||||
Pillow==10.3.0
|
Pillow==10.0.1
|
||||||
pycups==2.0.1
|
pycups==2.0.1
|
||||||
pypng==0.20220715.0
|
pypng==0.20220715.0
|
||||||
pyserial==3.5
|
pyserial==3.5
|
||||||
@ -17,4 +17,4 @@ PyYAML==6.0
|
|||||||
qrcode==7.4.2
|
qrcode==7.4.2
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
typing_extensions==4.5.0
|
typing_extensions==4.5.0
|
||||||
Werkzeug==3.0.3
|
Werkzeug==3.0.1
|
@ -209,38 +209,6 @@ ESCPOS_COMMANDS: List[Dict[str, Any]] = [
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"parser": {
|
|
||||||
"name": "software_columns",
|
|
||||||
"help": "Print a list of texts arranged into columns",
|
|
||||||
},
|
|
||||||
"defaults": {
|
|
||||||
"func": "software_columns",
|
|
||||||
},
|
|
||||||
"arguments": [
|
|
||||||
{
|
|
||||||
"option_strings": ("--text_list",),
|
|
||||||
"help": "list of texts to print",
|
|
||||||
"nargs": "+",
|
|
||||||
"type": str,
|
|
||||||
"required": True,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"option_strings": ("--widths",),
|
|
||||||
"help": "list of column widths",
|
|
||||||
"nargs": "+",
|
|
||||||
"type": int,
|
|
||||||
"required": True,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"option_strings": ("--align",),
|
|
||||||
"help": "list of column alignments",
|
|
||||||
"nargs": "+",
|
|
||||||
"type": str,
|
|
||||||
"required": True,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"parser": {
|
"parser": {
|
||||||
"name": "cut",
|
"name": "cut",
|
||||||
|
@ -76,18 +76,7 @@ class Config:
|
|||||||
|
|
||||||
if "printer" in config:
|
if "printer" in config:
|
||||||
self._printer_config = config["printer"]
|
self._printer_config = config["printer"]
|
||||||
printer_name = self._printer_config.pop("type")
|
self._printer_name = self._printer_config.pop("type").title()
|
||||||
class_names = {
|
|
||||||
"usb": "Usb",
|
|
||||||
"serial": "Serial",
|
|
||||||
"network": "Network",
|
|
||||||
"file": "File",
|
|
||||||
"dummy": "Dummy",
|
|
||||||
"cupsprinter": "CupsPrinter",
|
|
||||||
"lp": "LP",
|
|
||||||
"win32raw": "Win32Raw",
|
|
||||||
}
|
|
||||||
self._printer_name = class_names.get(printer_name.lower(), printer_name)
|
|
||||||
|
|
||||||
if not self._printer_name or not hasattr(printer, self._printer_name):
|
if not self._printer_name or not hasattr(printer, self._printer_name):
|
||||||
raise exceptions.ConfigSyntaxError(
|
raise exceptions.ConfigSyntaxError(
|
||||||
|
@ -12,7 +12,6 @@ This module contains the abstract base class :py:class:`Escpos`.
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
|
||||||
import warnings
|
import warnings
|
||||||
from abc import ABCMeta, abstractmethod # abstract base class support
|
from abc import ABCMeta, abstractmethod # abstract base class support
|
||||||
from re import match as re_match
|
from re import match as re_match
|
||||||
@ -108,8 +107,6 @@ SW_BARCODE_NAMES = {
|
|||||||
for name in barcode.PROVIDED_BARCODES
|
for name in barcode.PROVIDED_BARCODES
|
||||||
}
|
}
|
||||||
|
|
||||||
Alignment = Union[Literal["center", "left", "right"], str]
|
|
||||||
|
|
||||||
|
|
||||||
class Escpos(object, metaclass=ABCMeta):
|
class Escpos(object, metaclass=ABCMeta):
|
||||||
"""ESC/POS Printer object.
|
"""ESC/POS Printer object.
|
||||||
@ -124,9 +121,6 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
# object -> The connection object (Usb(), Serial(), Network(), etc.)
|
# object -> The connection object (Usb(), Serial(), Network(), etc.)
|
||||||
_device: Union[Literal[False], Literal[None], object] = False
|
_device: Union[Literal[False], Literal[None], object] = False
|
||||||
|
|
||||||
# sleep time in fragments:
|
|
||||||
_sleep_in_fragment_ms: int = 0
|
|
||||||
|
|
||||||
def __init__(self, profile=None, magic_encode_args=None, **kwargs) -> None:
|
def __init__(self, profile=None, magic_encode_args=None, **kwargs) -> None:
|
||||||
"""Initialize ESCPOS Printer.
|
"""Initialize ESCPOS Printer.
|
||||||
|
|
||||||
@ -182,21 +176,6 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def set_sleep_in_fragment(self, sleep_time_ms: int) -> None:
|
|
||||||
"""Configures the currently active sleep time after sending a fragment.
|
|
||||||
|
|
||||||
If during printing an image an issue like "USBTimeoutError: [Errno 110]
|
|
||||||
Operation timed out" occurs, setting this value to roughly 300
|
|
||||||
milliseconds can help resolve the issue.
|
|
||||||
|
|
||||||
:param sleep_time_ms: sleep time in milliseconds
|
|
||||||
"""
|
|
||||||
self._sleep_in_fragment_ms = sleep_time_ms
|
|
||||||
|
|
||||||
def _sleep_in_fragment(self) -> None:
|
|
||||||
"""Sleeps the preconfigured time after sending a fragment."""
|
|
||||||
time.sleep(self._sleep_in_fragment_ms / 1000)
|
|
||||||
|
|
||||||
def image(
|
def image(
|
||||||
self,
|
self,
|
||||||
img_source,
|
img_source,
|
||||||
@ -265,7 +244,6 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
impl=impl,
|
impl=impl,
|
||||||
fragment_height=fragment_height,
|
fragment_height=fragment_height,
|
||||||
)
|
)
|
||||||
self._sleep_in_fragment()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
if impl == "bitImageRaster":
|
if impl == "bitImageRaster":
|
||||||
@ -919,115 +897,6 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
col_count = self.profile.get_columns(font) if columns is None else columns
|
col_count = self.profile.get_columns(font) if columns is None else columns
|
||||||
self.text(textwrap.fill(txt, col_count))
|
self.text(textwrap.fill(txt, col_count))
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _padding(
|
|
||||||
text: str,
|
|
||||||
width: int,
|
|
||||||
align: Alignment = "center",
|
|
||||||
) -> str:
|
|
||||||
"""Add fill space to meet the width.
|
|
||||||
|
|
||||||
The align parameter sets the alignment of the text in space.
|
|
||||||
"""
|
|
||||||
align = align.lower()
|
|
||||||
if align == "center":
|
|
||||||
text = f"{text:^{width}}"
|
|
||||||
elif align == "left":
|
|
||||||
text = f"{text:<{width}}"
|
|
||||||
elif align == "right":
|
|
||||||
text = f"{text:>{width}}"
|
|
||||||
|
|
||||||
return text
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _truncate(text: str, width: int, placeholder: str = ".") -> str:
|
|
||||||
"""Truncate an string at a max width or leave it untouched.
|
|
||||||
|
|
||||||
Add a placeholder at the end of the output text if it has been truncated.
|
|
||||||
"""
|
|
||||||
ph_len = len(placeholder)
|
|
||||||
max_len = width - ph_len
|
|
||||||
return f"{text[:max_len]}{placeholder}" if len(text) > width else text
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _repeat_last(iterable, max_iterations: int = 1000):
|
|
||||||
"""Iterate over the items of a list repeating the last one until max_iterations."""
|
|
||||||
i = 0
|
|
||||||
while i < max_iterations:
|
|
||||||
try:
|
|
||||||
yield iterable[i]
|
|
||||||
except IndexError:
|
|
||||||
yield iterable[-1]
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
def _rearrange_into_cols(self, text_list: list, widths: list[int]) -> list:
|
|
||||||
"""Wrap and convert a list of strings into an array of text columns.
|
|
||||||
|
|
||||||
Set the width of each column by passing a list of widths.
|
|
||||||
Wrap if possible and|or truncate strings longer than its column width.
|
|
||||||
Reorder the wrapped items into an array of text columns.
|
|
||||||
"""
|
|
||||||
n_cols = len(text_list)
|
|
||||||
wrapped = [
|
|
||||||
textwrap.wrap(text, widths[i], break_long_words=False)
|
|
||||||
for i, text in enumerate(text_list)
|
|
||||||
]
|
|
||||||
max_len = max(*[len(text_group) for text_group in wrapped])
|
|
||||||
text_colums = []
|
|
||||||
for i in range(max_len):
|
|
||||||
row = ["" for _ in range(n_cols)]
|
|
||||||
for j, item in enumerate(wrapped):
|
|
||||||
if i in range(len(item)):
|
|
||||||
row[j] = self._truncate(item[i], widths[j])
|
|
||||||
text_colums.append(row)
|
|
||||||
return text_colums
|
|
||||||
|
|
||||||
def _add_padding_into_cols(
|
|
||||||
self,
|
|
||||||
text_list: list[str],
|
|
||||||
widths: list[int],
|
|
||||||
align: list[Alignment],
|
|
||||||
) -> list:
|
|
||||||
"""Add padding, width and alignment into the items of a list of strings."""
|
|
||||||
return [
|
|
||||||
self._padding(text, widths[i], align[i]) for i, text in enumerate(text_list)
|
|
||||||
]
|
|
||||||
|
|
||||||
def software_columns(
|
|
||||||
self,
|
|
||||||
text_list: list,
|
|
||||||
widths: Union[list[int], int],
|
|
||||||
align: Union[list[Alignment], Alignment],
|
|
||||||
) -> None:
|
|
||||||
"""Print a list of strings arranged horizontally in columns.
|
|
||||||
|
|
||||||
:param text_list: list of strings, each item in the list will be printed as a column.
|
|
||||||
|
|
||||||
:param widths: width of each column by passing a list of widths,
|
|
||||||
or a single total width to arrange columns of the same size.
|
|
||||||
If the list of width items is shorter than the list of strings then
|
|
||||||
the last width of the list will be applied till the last string (column).
|
|
||||||
|
|
||||||
:param align: alignment of the text into each column by passing a list of alignments,
|
|
||||||
or a single alignment for all the columns.
|
|
||||||
If the list of alignment items is shorter than the list of strings then
|
|
||||||
the last alignment of the list will be applied till the last string (column).
|
|
||||||
"""
|
|
||||||
n_cols = len(text_list)
|
|
||||||
|
|
||||||
if isinstance(widths, int):
|
|
||||||
widths = [round(widths / n_cols)]
|
|
||||||
widths = list(self._repeat_last(widths, max_iterations=n_cols))
|
|
||||||
|
|
||||||
if isinstance(align, str):
|
|
||||||
align = [align]
|
|
||||||
align = list(self._repeat_last(align, max_iterations=n_cols))
|
|
||||||
|
|
||||||
columns = self._rearrange_into_cols(text_list, widths)
|
|
||||||
for row in columns:
|
|
||||||
padded = self._add_padding_into_cols(row, widths, align)
|
|
||||||
self.textln("".join(padded))
|
|
||||||
|
|
||||||
def set(
|
def set(
|
||||||
self,
|
self,
|
||||||
align: Optional[str] = None,
|
align: Optional[str] = None,
|
||||||
@ -1065,8 +934,8 @@ class Escpos(object, metaclass=ABCMeta):
|
|||||||
:param double_width: doubles the width of the text
|
:param double_width: doubles the width of the text
|
||||||
:param custom_size: uses custom size specified by width and height
|
:param custom_size: uses custom size specified by width and height
|
||||||
parameters. Cannot be used with double_width or double_height.
|
parameters. Cannot be used with double_width or double_height.
|
||||||
:param width: requires custom_size=True, text width multiplier when custom_size is used, decimal range 1-8
|
:param width: text width multiplier when custom_size is used, decimal range 1-8
|
||||||
:param height: requires custom_size=True, text height multiplier when custom_size is used, decimal range 1-8
|
:param height: text height multiplier when custom_size is used, decimal range 1-8
|
||||||
:param density: print density, value from 0-8, if something else is supplied the density remains unchanged
|
:param density: print density, value from 0-8, if something else is supplied the density remains unchanged
|
||||||
:param invert: True enables white on black printing
|
:param invert: True enables white on black printing
|
||||||
:param smooth: True enables text smoothing. Effective on 4x4 size text and larger
|
:param smooth: True enables text smoothing. Effective on 4x4 size text and larger
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
I doubt that this currently works correctly.
|
I doubt that this currently works correctly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import types
|
|
||||||
import typing
|
|
||||||
|
|
||||||
jaconv: typing.Optional[types.ModuleType]
|
|
||||||
try:
|
try:
|
||||||
import jaconv
|
import jaconv
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""tests for software_columns
|
|
||||||
|
|
||||||
:author: Benito López and the python-escpos developers
|
|
||||||
:organization: `python-escpos <https://github.com/python-escpos>`_
|
|
||||||
:copyright: Copyright (c) 2024 `python-escpos <https://github.com/python-escpos>`_
|
|
||||||
:license: MIT
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
|
||||||
def test_rearrange_into_cols(driver) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN a list of columnable text
|
|
||||||
WHEN the column width is different for each column and some strings exceed the max width
|
|
||||||
THEN check the strings are properly wrapped, truncated and rearranged into some columns
|
|
||||||
"""
|
|
||||||
|
|
||||||
output = driver._rearrange_into_cols(
|
|
||||||
text_list=["fits", "row1 row2", "truncate and wrap"], widths=[4, 5, 6]
|
|
||||||
)
|
|
||||||
assert output == [["fits", "row1", "trunc."], ["", "row2", "and"], ["", "", "wrap"]]
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_padding_into_cols(driver) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN a list of strings
|
|
||||||
WHEN adding padding and different alignments to each string
|
|
||||||
THEN check the strings are correctly padded and aligned
|
|
||||||
"""
|
|
||||||
|
|
||||||
output = driver._add_padding_into_cols(
|
|
||||||
text_list=["col1", "col2", "col3"],
|
|
||||||
widths=[6, 6, 6],
|
|
||||||
align=["center", "left", "right"],
|
|
||||||
)
|
|
||||||
assert output == [" col1 ", "col2 ", " col3"]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("text_list", ["", [], None])
|
|
||||||
@pytest.mark.parametrize("widths", [30.5, "30", None])
|
|
||||||
@pytest.mark.parametrize("align", ["invalid_align_name", "", None])
|
|
||||||
def test_software_columns_invalid_args(driver, text_list, widths, align) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN a dummy printer object
|
|
||||||
WHEN non valid params are passed
|
|
||||||
THEN check raise exception
|
|
||||||
"""
|
|
||||||
bad_text_list = {"text_list": text_list, "widths": 5, "align": "left"}
|
|
||||||
bad_widths = {"text_list": ["valid"], "widths": widths, "align": "left"}
|
|
||||||
bad_align = {"text_list": ["valid"], "widths": 5, "align": align}
|
|
||||||
|
|
||||||
bad_args = [bad_text_list, bad_widths, bad_align]
|
|
||||||
for kwargs in bad_args:
|
|
||||||
with pytest.raises(Exception):
|
|
||||||
driver.software_columns(**kwargs)
|
|
||||||
driver.close()
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"text_list",
|
|
||||||
[
|
|
||||||
["col1", "col2", "col3"],
|
|
||||||
["wrap this string", "wrap this string", "wrap this string"],
|
|
||||||
["truncate_this_string", "truncate_this_string", "truncate_this_string"],
|
|
||||||
],
|
|
||||||
)
|
|
||||||
@pytest.mark.parametrize("widths", [[10, 10, 10], [10], 30])
|
|
||||||
@pytest.mark.parametrize("align", [["center", "left", "right"], ["center"], "center"])
|
|
||||||
def test_software_columns_valid_args(driver, text_list, widths, align) -> None:
|
|
||||||
"""
|
|
||||||
GIVEN a dummy printer object
|
|
||||||
WHEN valid params are passed
|
|
||||||
THEN check no errors
|
|
||||||
"""
|
|
||||||
driver.software_columns(text_list=text_list, widths=widths, align=align)
|
|
||||||
driver.close()
|
|
@ -7,8 +7,7 @@
|
|||||||
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
|
:copyright: Copyright (c) 2016 `python-escpos <https://github.com/python-escpos>`_
|
||||||
:license: MIT
|
:license: MIT
|
||||||
"""
|
"""
|
||||||
import types
|
|
||||||
import typing
|
|
||||||
|
|
||||||
import hypothesis.strategies as st
|
import hypothesis.strategies as st
|
||||||
import pytest
|
import pytest
|
||||||
@ -112,7 +111,6 @@ class TestMagicEncode:
|
|||||||
assert driver.output == b"\x1bt\x00? ist teuro."
|
assert driver.output == b"\x1bt\x00? ist teuro."
|
||||||
|
|
||||||
|
|
||||||
jaconv: typing.Optional[types.ModuleType]
|
|
||||||
try:
|
try:
|
||||||
import jaconv
|
import jaconv
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user