Skip to content

Commit

Permalink
Add support for station names surrounded by double quotes
Browse files Browse the repository at this point in the history
Refs: #537
  • Loading branch information
tim-vd-aardweg committed Apr 17, 2023
1 parent 8f6b1f2 commit 039ad37
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
4 changes: 2 additions & 2 deletions hydrolib/core/dflowfm/xyn/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ def _validate_name(cls, value):
if str_is_empty_or_none(value):
raise ValueError("Name cannot be empty.")

if "'" in value:
if "'" in value or '"' in value:
raise ValueError(
"Name cannot contain single quotes except at the start and end."
"Name cannot contain single or double quotes except at the start and end."
)

return value
Expand Down
14 changes: 11 additions & 3 deletions hydrolib/core/dflowfm/xyn/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,20 @@ def parse(filepath: Path) -> Dict:
Raises:
ValueError: if a line in the file cannot be parsed
or if the name contains whitespace while not surrounded with
single quotes.
single or double quotes.
"""

def is_surrounded_by_quotes(name: str) -> bool:
def is_surrounded_by_single_quotes(name: str) -> bool:
return name.startswith("'") and name.endswith("'")

def is_surrounded_by_double_quotes(name: str) -> bool:
return name.startswith('"') and name.endswith('"')

def is_surrounded_by_quotes(name: str) -> bool:
return is_surrounded_by_single_quotes(
name
) or is_surrounded_by_double_quotes(name)

def may_contain_whitespace(name: str) -> bool:
return is_surrounded_by_quotes(name)

Expand Down Expand Up @@ -58,7 +66,7 @@ def contains_whitespace_while_not_allowed(name: str) -> bool:

if contains_whitespace_while_not_allowed(n):
raise ValueError(
f"Error parsing XYN file '{filepath}', line {linenr+1}. Name `{n}` contains whitespace, so should be enclosed in single quotes."
f"Error parsing XYN file '{filepath}', line {linenr+1}. Name `{n}` contains whitespace, so should be enclosed in quotes."
)

if is_surrounded_by_quotes(n):
Expand Down
39 changes: 30 additions & 9 deletions tests/dflowfm/test_xyn.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def test_parse_xyn_file(self):
file_content = """
*This is a comment and should not be parsed.
1.1 2.2 'ObservationPoint_2D_01'
3.3 4.4 'ObservationPoint_2D_02'
3.3 4.4 "ObservationPoint_2D_02"
"""

expected_result = {
Expand All @@ -31,30 +31,50 @@ def test_parse_xyn_file(self):

with create_temp_file(file_content, "test.xyn") as xyn_file:
parsed_contents = XYNParser.parse(xyn_file)
assert expected_result == parsed_contents
assert expected_result == parsed_contents

def test_parse_xyn_file_with_quoted_name_removes_quotes(self):
def test_parse_xyn_file_with_single_quoted_name_removes_quotes_and_keeps_whitespace(
self,
):
file_content = """
1.1 2.2 'ObservationPoint_2D_01'
1.1 2.2 'ObservationPoint 2D 01'
"""

expected_result = {
"points": [
{"x": "1.1", "y": "2.2", "n": "ObservationPoint_2D_01"},
{"x": "1.1", "y": "2.2", "n": "ObservationPoint 2D 01"},
]
}

with create_temp_file(file_content, "test.xyn") as xyn_file:
parsed_contents = XYNParser.parse(xyn_file)
assert expected_result == parsed_contents

def test_parse_xyn_file_with_double_quoted_name_removes_quotes_and_keeps_whitespace(
self,
):
file_content = """
1.1 2.2 "ObservationPoint 2D 01"
"""

expected_result = {
"points": [
{"x": "1.1", "y": "2.2", "n": "ObservationPoint 2D 01"},
]
}

with create_temp_file(file_content, "test.xyn") as xyn_file:
parsed_contents = XYNParser.parse(xyn_file)
assert expected_result == parsed_contents

assert expected_result == parsed_contents

def test_parse_xyn_file_with_too_many_columns_raises_error(self):
name = "'ObservationPoint_2D_01' This is too much content"
file_content = f"1.1 2.2 {name}"

with pytest.raises(ValueError) as error:
with create_temp_file(file_content, "test.xyn") as xyn_file:
expected_message = f"Error parsing XYN file '{xyn_file}', line 1. Name `{name}` contains whitespace, so should be enclosed in single quotes."
expected_message = f"Error parsing XYN file '{xyn_file}', line 1. Name `{name}` contains whitespace, so should be enclosed in quotes."
_ = XYNParser.parse(xyn_file)

assert expected_message in str(error.value)
Expand All @@ -79,7 +99,7 @@ def test_serialize_xyn_point(self):

with open(xyn_file) as file:
file_content = file.readlines()
assert file_content == expected_file_content
assert file_content == expected_file_content


class TestXYNModel:
Expand Down Expand Up @@ -131,7 +151,8 @@ class TestXYNPoint:
@pytest.mark.parametrize(
("name"),
[
pytest.param("'nameWithQuote", id="Name with quote"),
pytest.param("nameWith'SingleQuote", id="Name with single quote"),
pytest.param('nameWith"DoubleQuote', id="Name with double quote"),
pytest.param(None, id="None value"),
pytest.param("", id="Empty string"),
pytest.param(" ", id="Whitespace only"),
Expand Down

0 comments on commit 039ad37

Please sign in to comment.