Skip to content

Commit

Permalink
Check control table values (#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
margrietpalm authored Aug 19, 2024
1 parent 86494f6 commit 30be791
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 1 deletion.
3 changes: 2 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Changelog of threedi-modelchecker
2.10.1 (unreleased)
-------------------

- Nothing changed yet.
- Adapt modelchecker to work with schema upgrades for structure control (0.224)
- Add check for control_table.action_table contents


2.10.0 (2024-08-16)
Expand Down
59 changes: 59 additions & 0 deletions threedi_modelchecker/checks/other.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import re
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import List, Literal, NamedTuple
Expand Down Expand Up @@ -1100,3 +1101,61 @@ def get_invalid(self, session):

def description(self) -> str:
return f"{self.table.name}.{self.column} refers to tag ids that are not present in Tags, "


class TableStrCheck(BaseCheck):
def __init__(
self, column, pattern, filters=None, level=CheckLevel.ERROR, error_code=0
):
self.pattern = pattern
super().__init__(
column=column, filters=filters, level=level, error_code=error_code
)

def get_invalid(self, session: Session) -> List[NamedTuple]:
# return mock list in case the table is empty when it shouldn't be
invalids = []
for record in self.to_check(session).all():
if re.match(self.pattern, getattr(record, self.column.name)) is None:
invalids.append(record)
return invalids


class ControlTableActionTableCheckDefault(TableStrCheck):
def __init__(self, level=CheckLevel.ERROR, error_code=0):
# check for action_table for action_type != set_discharge_coefficients
# expected format: multiple rows, separated by \n of "val,val"
super().__init__(
column=models.ControlTable.action_table,
pattern=r"^(-?\d+(\.\d+)?,-?\d+(\.\d+)?\n?)+$",
filters=models.ControlTable.action_type
!= constants.ControlTableActionTypes.set_discharge_coefficients,
level=level,
error_code=error_code,
)

def description(self) -> str:
return (
f"{self.table.name}.{self.column} is not properly formatted."
f"Expected one or more rows of: 'number, number number'"
)


class ControlTableActionTableCheckDischargeCoefficients(TableStrCheck):
def __init__(self, level=CheckLevel.ERROR, error_code=0):
# check for action_table for action_type = set_discharge_coefficients
# expected format: multiple rows, separated by \n of "val,val val"
super().__init__(
column=models.ControlTable.action_table,
pattern=r"^(-?\d+(\.\d+)?,-?\d+(\.\d+)? -?\d+(\.\d+)?\n?)+$",
filters=models.ControlTable.action_type
== constants.ControlTableActionTypes.set_discharge_coefficients,
level=level,
error_code=error_code,
)

def description(self) -> str:
return (
f"{self.table.name}.{self.column} is not properly formatted."
f"Expected one or more rows of: 'number, number'"
)
53 changes: 53 additions & 0 deletions threedi_modelchecker/tests/test_checks_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
ChannelManholeLevelCheck,
ConnectionNodesDistance,
ConnectionNodesLength,
ControlTableActionTableCheckDefault,
ControlTableActionTableCheckDischargeCoefficients,
CorrectAggregationSettingsExist,
CrossSectionLocationCheck,
CrossSectionSameConfigurationCheck,
Expand Down Expand Up @@ -901,3 +903,54 @@ def test_tags_valid(session):
assert len(check.get_invalid(session)) == 1
factories.TagsFactory(id=2, description="bar")
assert len(check.get_invalid(session)) == 0


@pytest.mark.parametrize(
"action_table, valid",
[
("1,2", True),
("1,2\n3,4", True),
("2,3\n3,4\n", True),
("1.0,2", True),
("1,2.1", True),
("1, 2", False),
("1;2", False),
("1,2 3", False),
("1,2,3", False),
],
)
def test_control_table_action_table_check_default(session, action_table, valid):
factories.ControlTableFactory(
action_table=action_table,
action_type=constants.ControlTableActionTypes.set_capacity,
)
check = ControlTableActionTableCheckDefault()
assert (len(check.get_invalid(session)) == 0) == valid


@pytest.mark.parametrize(
"action_table, valid",
[
("1,2 3", True),
("1,2 3\n3,4 5", True),
("2,3 3\n3,4 5\n", True),
("1.0,2 3", True),
("1,2.1 3", True),
("1,2.1 3", True),
("1,2.1 3.3", True),
("1,2", False),
("1, 2 3", False),
("1;2 3", False),
("1,2,3", False),
("1,2 3 4", False),
],
)
def test_control_table_action_table_check_discharge_coefficients(
session, action_table, valid
):
factories.ControlTableFactory(
action_table=action_table,
action_type=constants.ControlTableActionTypes.set_discharge_coefficients,
)
check = ControlTableActionTableCheckDischargeCoefficients()
assert (len(check.get_invalid(session)) == 0) == valid

0 comments on commit 30be791

Please sign in to comment.