Skip to content

Commit

Permalink
Merge pull request #304 from jodal/ignore-separator-chars
Browse files Browse the repository at this point in the history
Ignore redundant separator characters
  • Loading branch information
jodal authored Aug 3, 2024
2 parents 569e540 + 875dded commit 6a5cc5e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 26 deletions.
19 changes: 7 additions & 12 deletions src/biip/gs1/_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ def parse(
A message object with one or more element strings.
Raises:
ParseError: If a fixed-length field ends with a separator character.
ValueError: If the ``separator_char`` isn't exactly 1 character long.
ParseError: If the parsing fails.
"""
value = value.strip()
element_strings: List[GS1ElementString] = []
Expand All @@ -83,17 +84,11 @@ def parse(

rest = rest[len(element_string) :]

if rest.startswith(tuple(separator_chars)):
if element_string.ai.fnc1_required:
rest = rest[1:]
else:
separator_char = rest[0]
msg = (
f"Element String {element_string.as_hri()!r} has fixed length "
"and should not end with a separator character. "
f"Separator character {separator_char!r} found in {value!r}."
)
raise ParseError(msg)
# Separator characters are accepted inbetween any element string,
# even if the AI doesn't require it. See GS1 General Specifications,
# section 7.8.6 for details.
while rest.startswith(tuple(separator_chars)):
rest = rest[1:]

return cls(value=value, element_strings=element_strings)

Expand Down
30 changes: 16 additions & 14 deletions tests/gs1/test_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,20 +150,22 @@ def test_parse_fails_if_unparsed_data_left(value: str, error: str) -> None:
assert str(exc_info.value) == error


def test_parse_fails_if_fixed_length_field_ends_with_separator_char() -> None:
# 15... is a fixed length date.
# \x1d is the default separator character in an illegal position.
# 10... is any other field.
value = "15210526\x1d100329"

with pytest.raises(ParseError) as exc_info:
GS1Message.parse(value)

assert str(exc_info.value) == (
r"Element String '(15)210526' has fixed length and "
r"should not end with a separator character. "
r"Separator character '\x1d' found in '15210526\x1d100329'."
)
@pytest.mark.parametrize(
("value", "expected_hri"),
[
# A separator at the end of the string is never needed.
("15210526100329\x1d", "(15)210526(10)0329"),
# 15... is a fixed length date, and should not end with a separator.
("15210526\x1d100329", "(15)210526(10)0329"),
# Double separator chars are ignored.
(
"0107032069804988100329\x1d\x1d15210526",
"(01)07032069804988(10)0329(15)210526",
),
],
)
def test_parse_ignores_redundant_separator_chars(value: str, expected_hri: str) -> None:
assert GS1Message.parse(value).as_hri() == expected_hri


def test_parse_strips_surrounding_whitespace() -> None:
Expand Down

0 comments on commit 6a5cc5e

Please sign in to comment.