Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test/81 definition of testcases #88

Merged
merged 21 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
786e6bb
test: Added new way of testing acceptance scenarios
Carsopre Oct 16, 2023
7ad4a90
test: Created new (work in progress) acceptance tests
Carsopre Oct 16, 2023
5a092b4
test: Added logic to compare reference images
Carsopre Oct 16, 2023
7c4c9ca
test: fixed test cases for TestReinforcementProfileBuilderFactory
Carsopre Oct 16, 2023
fca2d2b
chore: Fixed failing tests
Carsopre Oct 17, 2023
e7f2ebf
Added new surrounding files
peterdgr Oct 17, 2023
006ee16
test: Moved tests cases into a different directory
Carsopre Oct 17, 2023
f6b22ac
Merge branch 'test/81-definition-of-testcases' of https://github.com/…
Carsopre Oct 17, 2023
5fa5ede
test: Test case generation fixed
Carsopre Oct 17, 2023
dcf999c
test: Fixed failing tests
Carsopre Oct 17, 2023
7a7104e
Acceptance test scenarios added
peterdgr Oct 17, 2023
1db10df
test: Moved `reinforcement_profile_cases.py` logic into fixture for b…
Carsopre Oct 18, 2023
0c60bca
fix: We now replace not-provided values from a KoswatScenario when ca…
Carsopre Oct 18, 2023
c62287b
test: We now generate only one folder for results
Carsopre Oct 18, 2023
1dbe681
test: Fixed failing test
Carsopre Oct 18, 2023
63e394b
test: acceptance tests data extended
peterdgr Oct 18, 2023
3bcc0e5
Merge branch 'test/81-definition-of-testcases' of https://github.com/…
peterdgr Oct 18, 2023
031ace9
chore: Moved logic to normalize koswat scenario from default values
Carsopre Oct 18, 2023
4c8bdf7
Test: case_dijk1_1a_dh_with_default_layers added
peterdgr Oct 18, 2023
c02fbfc
Test: added missing data
peterdgr Oct 18, 2023
fef60e3
chore: Processed review remarks
Carsopre Oct 18, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations
from dataclasses import dataclass
import math

from koswat.calculations.protocols import ReinforcementProfileProtocol
from koswat.dike.profile.koswat_input_profile_base import KoswatInputProfileBase


@dataclass
class CofferDamInputProfile(KoswatInputProfileBase, ReinforcementProfileProtocol):
length_coffer_dam: float
length_coffer_dam: float = math.nan
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations
from dataclasses import dataclass
import math

from koswat.calculations.protocols import ReinforcementInputProfileProtocol
from koswat.dike.profile.koswat_input_profile_base import KoswatInputProfileBase


@dataclass
class PipingWallInputProfile(KoswatInputProfileBase, ReinforcementInputProfileProtocol):
length_piping_wall: float
length_piping_wall: float = math.nan
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from dataclasses import dataclass
from koswat.calculations.protocols import ReinforcementInputProfileProtocol
from koswat.dike.profile.koswat_input_profile_base import KoswatInputProfileBase


@dataclass
class SoilInputProfile(KoswatInputProfileBase, ReinforcementInputProfileProtocol):
pass
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from __future__ import annotations
from dataclasses import dataclass
import math

from koswat.calculations.protocols import ReinforcementProfileProtocol
from koswat.dike.profile.koswat_input_profile_base import KoswatInputProfileBase


@dataclass
class StabilityWallInputProfile(KoswatInputProfileBase, ReinforcementProfileProtocol):
length_stability_wall: float
length_stability_wall: float = math.nan
25 changes: 9 additions & 16 deletions koswat/configuration/settings/koswat_scenario.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,20 @@
from __future__ import annotations
from dataclasses import dataclass

import math

from koswat.configuration.koswat_config_protocol import KoswatConfigProtocol


@dataclass
class KoswatScenario(KoswatConfigProtocol):
scenario_name: str
scenario_section: str
d_h: float
d_s: float
d_p: float
kruin_breedte: float
buiten_talud: float

def __init__(self) -> None:
self.scenario_name = ""
self.scenario_section = ""
self.d_h = math.nan
self.d_s = math.nan
self.d_p = math.nan
self.kruin_breedte = math.nan
self.buiten_talud = math.nan
scenario_name: str = ""
scenario_section: str = ""
d_h: float = math.nan
d_s: float = math.nan
d_p: float = math.nan
kruin_breedte: float = math.nan
buiten_talud: float = math.nan

def is_valid(self) -> bool:
return (
Expand Down
4 changes: 4 additions & 0 deletions koswat/cost_report/io/csv/summary_matrix_csv_fom_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ def location_as_row(
_location_as_row.extend(_m_values)
return _location_as_row

if not any(available_locations):
logging.warning("No locations specified for the report.")
return [[]]

# Initiate locations matrix.
# Note: Not the most efficient way, but I want to keep the reports with only
# the locations that support one (or more) profile reinforcements.
Expand Down
25 changes: 14 additions & 11 deletions koswat/dike/profile/koswat_input_profile_base.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
from __future__ import annotations
from dataclasses import dataclass
import math

from koswat.dike.koswat_input_profile_protocol import KoswatInputProfileProtocol


@dataclass
class KoswatInputProfileBase(KoswatInputProfileProtocol):
dike_section: str
buiten_maaiveld: float
buiten_talud: float
buiten_berm_hoogte: float
buiten_berm_breedte: float
kruin_hoogte: float
kruin_breedte: float
binnen_talud: float
binnen_berm_hoogte: float
binnen_berm_breedte: float
binnen_maaiveld: float
dike_section: str = ""
buiten_maaiveld: float = math.nan
buiten_talud: float = math.nan
buiten_berm_hoogte: float = math.nan
buiten_berm_breedte: float = math.nan
kruin_hoogte: float = math.nan
kruin_breedte: float = math.nan
binnen_talud: float = math.nan
binnen_berm_hoogte: float = math.nan
binnen_berm_breedte: float = math.nan
binnen_maaiveld: float = math.nan
9 changes: 5 additions & 4 deletions koswat/dike/surroundings/wrapper/surroundings_wrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import List

from shapely.geometry import Point

from koswat.dike.surroundings.buildings_polderside.koswat_buildings_polderside import (
Expand Down Expand Up @@ -60,7 +58,7 @@ def __init__(self) -> None:
self.roads_class_unknown_dikeside = None

@property
def locations(self) -> List[PointSurroundings]:
def locations(self) -> list[PointSurroundings]:
"""
Each location represents 1 meter in a real scale map.

Expand All @@ -71,7 +69,7 @@ def locations(self) -> List[PointSurroundings]:
return []
return self.buldings_polderside.points

def get_locations_after_distance(self, distance: float) -> List[Point]:
def get_locations_after_distance(self, distance: float) -> list[Point]:
"""
Gets all locations which are safe from buildings in a radius of `distance`.

Expand All @@ -87,4 +85,7 @@ def is_at_safe_distance(point_surroundings: PointSurroundings) -> bool:
return True
return distance < point_surroundings.distance_to_buildings[0]

if not self.buldings_polderside:
return []

return list(filter(is_at_safe_distance, self.buldings_polderside.points))
29 changes: 28 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pytest = "^7.2.1"
pytest-cov = "^3.0.0"
coverage = "^6.4.4"
teamcity-messages = "^1.32"
opencv-python = "^4.8.1.78"

[tool.poetry.group.dev.dependencies]
black = "^22.8.0"
Expand Down
Empty file.
44 changes: 44 additions & 0 deletions tests/acceptance_scenarios/acceptance_test_scenario_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from tests.acceptance_scenarios.acceptance_test_scenario_dataclasses import (
AcceptanceTestScenarioCombinations,
)
from tests.acceptance_scenarios.koswat_input_profile_base_cases import (
AcceptanceTestInputProfileCases,
)
from tests.acceptance_scenarios.koswat_scenario_test_cases import (
Dijk1ScenarioCases,
ScenarioCases,
)
from tests.acceptance_scenarios.layers_cases import LayersCases

acceptance_test_combinations = [
AcceptanceTestScenarioCombinations(
profile_case=AcceptanceTestInputProfileCases.profile_dijk1,
layers_cases=[LayersCases.with_acceptance_criteria],
scenario_cases=[
Dijk1ScenarioCases.s1a_dh,
Dijk1ScenarioCases.s1b_ds,
Dijk1ScenarioCases.s1c_dp,
Dijk1ScenarioCases.s1d_dhds,
Dijk1ScenarioCases.s1e_dhdp,
Dijk1ScenarioCases.s1f_dsdp,
Dijk1ScenarioCases.s1g_dhdsdp,
Dijk1ScenarioCases.s2a_dh,
Dijk1ScenarioCases.s2b_ds,
Dijk1ScenarioCases.s2c_dp,
Dijk1ScenarioCases.s2d_dhds,
Dijk1ScenarioCases.s2e_dhdp,
Dijk1ScenarioCases.s2f_dsdp,
Dijk1ScenarioCases.s2g_dhdsdp,
],
),
AcceptanceTestScenarioCombinations(
profile_case=AcceptanceTestInputProfileCases.profile_dijk2,
layers_cases=[LayersCases.with_acceptance_criteria],
scenario_cases=[ScenarioCases.default],
),
AcceptanceTestScenarioCombinations(
profile_case=AcceptanceTestInputProfileCases.profile_dijk3,
layers_cases=[LayersCases.with_acceptance_criteria],
scenario_cases=[ScenarioCases.default],
),
]
80 changes: 80 additions & 0 deletions tests/acceptance_scenarios/acceptance_test_scenario_dataclasses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path

import pytest

from koswat.configuration.settings.koswat_scenario import KoswatScenario
from koswat.dike.koswat_profile_protocol import KoswatProfileProtocol
from koswat.dike.profile.koswat_input_profile_base import KoswatInputProfileBase
from itertools import product
from koswat.dike.profile.koswat_profile import KoswatProfileBase

from koswat.dike.profile.koswat_profile_builder import KoswatProfileBuilder
from tests import test_data


@dataclass
class LayersTestCase:
layers_dict: dict
case_name: str


@dataclass
class AcceptanceTestScenario:
profile_case: KoswatProfileProtocol
scenario_case: KoswatScenario
layer_case: LayersTestCase

@property
def case_name(self) -> str:
return "case_{}_{}_{}".format(
self.profile_case.input_data.dike_section,
self.scenario_case.scenario_name,
self.layer_case.case_name,
)

@property
def reference_data_dir(self) -> Path:
return test_data.joinpath("acceptance_reference_data", self.case_name)


@dataclass
class AcceptanceTestScenarioCombinations:
profile_case: KoswatInputProfileBase
layers_cases: list[LayersTestCase]
scenario_cases: list[KoswatScenario]

def get_test_cases(self) -> list[pytest.param]:
def to_pytest_case(
test_scenario: tuple[KoswatInputProfileBase, LayersTestCase, KoswatScenario]
) -> pytest.param:
_profile_case, _layer_case, _scenario_case = test_scenario
_input_profile_case = KoswatProfileBuilder.with_data(
dict(
input_profile_data=_profile_case,
layers_data=_layer_case.layers_dict,
profile_type=KoswatProfileBase,
)
).build()
_test_case = AcceptanceTestScenario(
profile_case=_input_profile_case,
layer_case=_layer_case,
scenario_case=_scenario_case,
)
return pytest.param(_test_case, id=_test_case.case_name)

_cases = [
[self.profile_case],
self.layers_cases,
self.scenario_cases,
]
return list(map(to_pytest_case, product(*_cases)))

@staticmethod
def get_all_cases(
list_combinations: list[AcceptanceTestScenarioCombinations],
) -> list[pytest.param]:
# Gets all cases available.
# Python trick by using the `sum` operator to flatten lists.
return sum(map(lambda x: x.get_test_cases(), list_combinations), [])
6 changes: 6 additions & 0 deletions tests/acceptance_scenarios/cases_protocol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from typing import Protocol
import pytest


class CasesProtocol(Protocol):
cases: list[pytest.param]
30 changes: 30 additions & 0 deletions tests/acceptance_scenarios/initial_characteristic_points_cases.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest
from tests.acceptance_scenarios.cases_protocol import CasesProtocol
from shapely.geometry.point import Point


class InitialPointsLookup(CasesProtocol):
default = [
Point(-18.0, 0.0),
Point(-18.0, 0.0),
Point(-18.0, 0.0),
Point(0.0, 6.0),
Point(5.0, 6.0),
Point(23.0, 0.0),
Point(23.0, 0.0),
Point(23.0, 0.0),
]
calc_profile_scenario_2 = [
Point(-24, 0),
Point(-24, 0),
Point(-24, 0),
Point(2, 6.5),
Point(7, 6.5),
Point(28.60, 2.6),
Point(82.60, 2.6),
Point(97, 0),
]
cases = [
pytest.param(default, id="Default initial profile."),
pytest.param(calc_profile_scenario_2, id="Scenario 2 calculated profile."),
]
Loading