Repository navigation
Conversation
…XN validation, Code39/PZN and Code128 charsets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The existing suite (55 tests) covers one checksum example per barcode type, EAN-13's checksum/no-checksum interplay, GS1-128 symbol sequences, Code 128 build stability, and the writers. Several encoders and the lookup layer had no dedicated tests at all (UPC-A, ITF and Codabar only appeared in the visual
test_manually.py). This PR adds 239 tests covering that missing pure-encoding logic; no production code is changed and no image rendering is asserted (onlybuild()patterns and value-level behaviour).barcode/__init__.pyregistry (test_registry.py) —PROVIDED_BARCODESis exactly the 22 sorted names; every name resolves viaget_barcode_classto its class; aliases (ean→ean13,gtin→ean14,isbn/gs1→isbn13,nw-7→codabar,upc→upca) resolve to the identical class object; lookup is case-insensitive; unknown names (including""and names with stray whitespace) raiseBarcodeNotFoundErrorwith the messageThe barcode '<name>' is not known., with or without a code;getwith a code returns an instance, without one the class, andoptionsare passed through to the constructortest_ean_family.py) — EAN-13: overlong input is trimmed to 12 digits and the checksum recomputed, too-short input raisesNumberOfDigitsError, non-digits and empty input raiseIllegalCharacterError,calculate_checksum(value)for explicit values, the exact 95-modulebuild()pattern, guard-bar fullcode format,to_ascii()output; EAN-8 and EAN-14: checksums for a range of values (including all-zero and all-nine inputs), trimming, length/character errors, build lengths (67 / 102 modules), EAN-8 guard fullcode; JAN: country codes at the 450/459/490/499 boundaries accepted, 460/489/500 rejected withWrongCountryCodeError, and the country check running before the length checktest_upc.py) — checksums for five values, 12-digit input being trimmed with the checksum recomputed (a wrong 12th digit is silently ignored), length/character errors,make_ean=Trueprefixing a0instr()/get_fullcode()while the stored code keeps 12 digits, the exact 95-modulebuild()pattern, andto_ascii()using_for spacestest_itf.py) — odd-length input padded with a leading zero, exact interleavedbuild()patterns for digit pairs, pattern length scaling with pair count, narrow/wide width scaling, andIllegalCharacterErrorfor non-digit input (including empty and separator-containing strings)test_isxn_validation.py) — ISBN-13: hyphen stripping, rejection of non-978/979 prefixes, the 979 fourth-digit rule raising the plainBarcodeError, accepted 979-1 and 979-8 prefixes; ISBN-10: the documented example, the supplied check digit being ignored and always recomputed, hyphen stripping, andXcheck digits for four values; ISSN:Xand numeric check digits, conversion to EAN-13, hyphen handling, andmake_ean()outputtest_code39_pzn.py) — appended checksum characters for a range of inputs, upper-casing of lowercase input,add_checksum=False, building every one of the 43 legal characters framed by the start/stop pattern, illegal-character error paths, and PZN length validation, non-digit rejection, trimming, the checksum-10 rejection, and PZN8's seven-digit formtest_codabar.py) — exactbuild()patterns at default and custom narrow/wide widths, all six special characters ($:/.+-) building, and validation being deferred tobuild(): bad start/end characters raiseBarcodeError, illegal body characters raiseIllegalCharacterError, while the constructor accepts anythingtest_code128_charsets.py) — charset A/B dictionary values and sizes, the charset C switch table (TO_B100,TO_A101, FNC1 102), start/switch tables, andencodedsymbol sequences for digit pairs, start-code folding to START_B, a trailing odd digit switching to charset B, and control characters switching to charset A; plus the illegal-character errortest_charset_tables.py) — EANLEFT_PATTERNshape, C patterns being the bitwise complement of A and B the reverse of C, UPC tables being identical to the EAN A/C tables, ITF's two-of-five property (exactly two wide elements per digit), Code 39 table/map shape and sequential values, Code 128's 106 unique 11-module patterns, and the Codabar table shapetest_errors.py) —BarcodeErrormessage storage/rendering, the four specific errors subclassingBarcodeError, the baseBarcoderaisingNotImplementedErroron instantiation, and the default writer beingSVGWriterBehaviour pinned as-is (possible upstream quirks, documented in the tests rather than "fixed"):
Code39with an illegal character raisesKeyError(notIllegalCharacterError) under the defaultadd_checksum=True, because the checksum is computed before character validation; withadd_checksum=Falsethe properIllegalCharacterErroris raisedCode39.calculate_checksum()sumsself.codeincluding the already-appended checksum character, so calling it after construction returns a different character than the one in the codeCode39("")silently produces the code"0"JANwith a non-numeric prefix raises a plainValueErrorfromint(), not aBarcodeErrorISSNperforms no length validation:ISSN("12345")silently producesissn == "123455"and a meaningless EAN-13 (9771234550029)ISSN.make_ean()returns the check digit verbatim, so it can containX(e.g.977114487500X); the numeric EAN checksum is only applied by the EAN-13 layer1or8, although the error message only mentions 97910 and 97911Code128("")raisesIndexError(in_try_to_optimize), andCODABAR("")raisesIndexErroronbuild()Verification (Python 3.12, package installed with
pip install -e ".[images]", pluspytestandpytest-cov; no new conftest is needed — the tests live in the existingtests/package and run from the repository root):