Automatically choose correct barcode function.

Tests for barcode function.
This commit is contained in:
Michael Elsdörfer 2016-08-30 12:53:31 +02:00
parent a07f84a5bc
commit 5fa89ff685
3 changed files with 76 additions and 14 deletions

View File

@ -15,6 +15,9 @@ class NotSupported(Exception):
pass pass
BARCODE_B = 'barcodeB'
class BaseProfile(object): class BaseProfile(object):
"""This respresents a printer profile. """This respresents a printer profile.
@ -43,6 +46,11 @@ class BaseProfile(object):
font = self.get_font(font) font = self.get_font(font)
return self.fonts[six.text_type(font)]['columns'] return self.fonts[six.text_type(font)]['columns']
def supports(self, feature):
"""Return true/false for the given feature.
"""
return self.features.get(feature)
def get_profile(name=None, **kwargs): def get_profile(name=None, **kwargs):
"""Get the profile by name; if no name is given, return the """Get the profile by name; if no name is given, return the
@ -84,10 +92,11 @@ def clean(s):
# For users, who want to provide their profile # For users, who want to provide their profile
class Profile(get_profile_class('default')): class Profile(get_profile_class('default')):
def __init__(self, columns=None): def __init__(self, columns=None, features={}):
super(Profile, self).__init() super(Profile, self).__init__()
self.columns = columns self.columns = columns
self.features = features
def get_columns(self, font): def get_columns(self, font):
if self.columns is not None: if self.columns is not None:

View File

@ -23,7 +23,7 @@ from .exceptions import *
from abc import ABCMeta, abstractmethod # abstract base class support from abc import ABCMeta, abstractmethod # abstract base class support
from escpos.image import EscposImage from escpos.image import EscposImage
from escpos.capabilities import get_profile from escpos.capabilities import get_profile, BARCODE_B
@six.add_metaclass(ABCMeta) @six.add_metaclass(ABCMeta)
@ -293,7 +293,8 @@ class Escpos(object):
else: else:
raise CharCodeError() raise CharCodeError()
def barcode(self, code, bc, height=64, width=3, pos="BELOW", font="A", align_ct=True, function_type="A"): def barcode(self, code, bc, height=64, width=3, pos="BELOW", font="A",
align_ct=True, function_type=None):
""" Print Barcode """ Print Barcode
This method allows to print barcodes. The rendering of the barcode is done by the printer and therefore has to This method allows to print barcodes. The rendering of the barcode is done by the printer and therefore has to
@ -364,14 +365,40 @@ class Escpos(object):
issued. issued.
:type align_ct: bool :type align_ct: bool
:param function_type: Choose between ESCPOS function type A or B, depending on printer support and desired :param function_type: Choose between ESCPOS function type A or B,
barcode. depending on printer support and desired barcode. If not given,
the printer will attempt to automatically choose the correct
function based on the current profile.
*default*: A *default*: A
:raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`, :raises: :py:exc:`~escpos.exceptions.BarcodeSizeError`,
:py:exc:`~escpos.exceptions.BarcodeTypeError`, :py:exc:`~escpos.exceptions.BarcodeTypeError`,
:py:exc:`~escpos.exceptions.BarcodeCodeError` :py:exc:`~escpos.exceptions.BarcodeCodeError`
""" """
if function_type is None:
# Choose the function type automatically.
if bc in BARCODE_TYPES['A']:
function_type = 'A'
else:
if bc in BARCODE_TYPES['B']:
if not self.profile.supports(BARCODE_B):
raise BarcodeTypeError((
"Barcode type '{bc} not supported for "
"the current printer profile").format(bc=bc))
function_type = 'B'
else:
raise BarcodeTypeError((
"Barcode type '{bc} is not valid").format(bc=bc))
bc_types = BARCODE_TYPES[function_type.upper()]
if bc.upper() not in bc_types.keys():
raise BarcodeTypeError((
"Barcode type '{bc}' not valid for barcode function type "
"{function_type}").format(
bc=bc,
function_type=function_type,
))
# Align Bar Code() # Align Bar Code()
if align_ct: if align_ct:
self._raw(TXT_ALIGN_CT) self._raw(TXT_ALIGN_CT)
@ -400,14 +427,6 @@ class Escpos(object):
else: # DEFAULT POSITION: BELOW else: # DEFAULT POSITION: BELOW
self._raw(BARCODE_TXT_BLW) self._raw(BARCODE_TXT_BLW)
bc_types = BARCODE_TYPES[function_type.upper()]
if bc.upper() not in bc_types.keys():
# TODO: Raise a better error, or fix the message of this error type
raise BarcodeTypeError("Barcode type {bc} not valid for barcode function type {function_type}".format(
bc=bc,
function_type=function_type,
))
self._raw(bc_types[bc.upper()]) self._raw(bc_types[bc.upper()])
if function_type.upper() == "B": if function_type.upper() == "B":

View File

@ -0,0 +1,34 @@
#!/usr/bin/python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import escpos.printer as printer
from escpos.constants import BARCODE_TYPE_A, BARCODE_TYPE_B
from escpos.capabilities import Profile, BARCODE_B
from escpos.exceptions import BarcodeTypeError
import pytest
@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):
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):
profile = Profile(features={BARCODE_B: supports_b})
instance = printer.Dummy(profile=profile)
with pytest.raises(BarcodeTypeError):
instance.barcode('test', bctype)
assert instance.output == ''