Skip to content

Commit

Permalink
Merge pull request #14 from opengisch/validconfigvariable
Browse files Browse the repository at this point in the history
Variables as toppings
  • Loading branch information
signedav authored Dec 10, 2024
2 parents 15eee63 + 55d571d commit 9871d4f
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 17 deletions.
8 changes: 1 addition & 7 deletions tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@ with a database, so your own postgres installation is not affected at all.

To run the tests, go to the main directory of the project and do

```sh
export QGIS_TEST_VERSION=latest # See https://hub.docker.com/r/qgis/qgis/tags/
export GITHUB_WORKSPACE=$PWD # only for local execution
docker run -v ${GITHUB_WORKSPACE}:/usr/src -w /usr/src opengisch/qgis:${QGIS_TEST_VERSION} sh -c 'xvfb-run pytest-3'
```

In one line, removing all containers.
```sh
QGIS_TEST_VERSION=latest GITHUB_WORKSPACE=$PWD docker run -v ${GITHUB_WORKSPACE}:/usr/src -w /usr/src opengisch/qgis:${QGIS_TEST_VERSION} sh -c 'xvfb-run pytest-3'
docker run -v $PWD:/usr/src -w /usr/src opengisch/qgis:latest sh -c 'xvfb-run pytest-3'
```
36 changes: 30 additions & 6 deletions tests/test_toppingmaker.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class ToppingMakerTest(unittest.TestCase):
def setUpClass(cls):
"""Run before all tests."""
cls.basetestpath = tempfile.mkdtemp()
cls.testdata_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "testdata"
)
cls.projecttopping_test_path = os.path.join(cls.basetestpath, "projecttopping")

def test_target(self):
Expand Down Expand Up @@ -143,9 +146,11 @@ def test_parse_project_with_mapthemes(self):
# check variables
variables = project_topping.variables
# Anyway in practice no spaces should be used to be able to access them in the expressions like @first_variable
assert variables.get("First Variable") == "This is a test value."
assert variables.get("First Variable")
assert variables.get("First Variable")["value"] == "This is a test value."
# QGIS is currently (3.29) not able to store structures in the project file. Still...
assert variables.get("Variable with Structure") == [
assert variables.get("Variable with Structure")
assert variables.get("Variable with Structure")["value"] == [
"Not",
"The",
"Normal",
Expand Down Expand Up @@ -416,11 +421,18 @@ def test_generate_files(self):
"Case",
]
foundVariableWithStructure = True
if variable_key == "Validation Path Variable":
assert (
projecttopping_data["variables"][variable_key]
== "freddys_projects/this_specific_project/generic/freddys_validConfig.ini"
)
foundVariableWithPath = True
variable_count += 1

assert variable_count == 2
assert variable_count == 3
assert foundFirstVariable
assert foundVariableWithStructure
assert foundVariableWithPath

# check transaction mode
with open(projecttopping_file_path) as yamlfile:
Expand Down Expand Up @@ -471,12 +483,13 @@ def test_generate_files(self):

countchecked = 0

# there should be 21 toppingfiles:
# there should be 22 toppingfiles:
# - one project topping
# - 2 x 3 qlr files (two times since the layers are multiple times in the tree)
# - 2 x 6 qml files (one layers with 3 styles, one layer with 2 styles and one layer with one style - and two times since the layers are multiple times in the tree)
# - 2 qpt template files
assert len(target.toppingfileinfo_list) == 21
# - 1 generic file (validation.ini) what is created by variable
assert len(target.toppingfileinfo_list) == 22

for toppingfileinfo in target.toppingfileinfo_list:
self.print_info(toppingfileinfo["path"])
Expand Down Expand Up @@ -703,6 +716,11 @@ def _make_project_and_export_settings(self):
QgsExpressionContextUtils.setProjectVariable(
project, "Variable with Structure", ["Not", "The", "Normal", 815, "Case"]
)
QgsExpressionContextUtils.setProjectVariable(
project,
"Validation Path Variable",
os.path.join(self.testdata_path, "validConfig.ini"),
)

# create layouts
layout = QgsPrintLayout(project)
Expand Down Expand Up @@ -788,7 +806,13 @@ def _make_project_and_export_settings(self):
export_settings.mapthemes = ["French Theme", "Robot Theme"]

# define the custom variables to export
export_settings.variables = ["First Variable", "Variable with Structure"]
export_settings.variables = [
"First Variable",
"Variable with Structure",
"Validation Path Variable",
]
# content of this variable should be exported as toppingfile
export_settings.path_variables = ["Validation Path Variable"]

# define the layouts to export
export_settings.layouts = ["Layout One", "Layout Three"]
Expand Down
7 changes: 7 additions & 0 deletions tests/testdata/validConfig.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
["PARAMETER"]
validation="on"
additionalModels="SH_ProjektdatenDB_Naturschutz_V1_0_AddChecks"

["SH_ProjektdatenDB_Naturschutz_V1_0_AddChecks.SH_ProjektdatenDB_Naturschutz_V1_0_Validierung.v_Mitarbeitende.checkNameDuplikate"]
multiplicity="on"
type="on"
2 changes: 2 additions & 0 deletions toppingmaker/exportsettings.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ def __init__(self):
self.mapthemes = []
# keys of custom variables to be exported
self.variables = []
# list of variable keys that are defined as paths and should be resolved
self.path_variables = []
# names of layouts
self.layouts = []

Expand Down
40 changes: 36 additions & 4 deletions toppingmaker/projecttopping.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ProjectTopping(QObject):
LAYERDEFINITION_TYPE = "layerdefinition"
LAYERSTYLE_TYPE = "layerstyle"
LAYOUTTEMPLATE_TYPE = "layouttemplate"
GENERIC_TYPE = "generic"

class TreeItemProperties:
"""
Expand Down Expand Up @@ -414,19 +415,50 @@ def make_items(
class Variables(dict):
"""
A dict object of dict items describing a variable according to the variable keys listed in the ExportSettings passed on parsing the QGIS project.
The items have the keys 'name' and (optional) 'ispath' for the case that it's a path that needs to be resolved for the topping.
To define what variables are paths this needs to be set in the ExportSettings path_variables.
"""

def make_items(
self,
project: QgsProject,
export_settings: ExportSettings,
):

self.clear()
for variable_key in export_settings.variables:
variable_item = {}

variable_value = QgsExpressionContextUtils.projectScope(
project
).variable(variable_key)
self[variable_key] = variable_value or None

# if it's defined as path variable, we have to expose it as toppingfile
if variable_key in export_settings.path_variables:
path = variable_value
if project.homePath() and not os.path.isabs(variable_value):
# if it's a saved project and the path is not absolute, make it absolute
path = os.path.join(
variable_value, project.homePath(), variable_value
)
variable_item["value"] = path
variable_item["ispath"] = True
else:
variable_item["value"] = variable_value

self[variable_key] = variable_item or None

def resolved_dict(self, target: Target):
resolved_items = {}
for variable_key in self.keys():
resolved_value = self[variable_key].get("value")
if self[variable_key].get("ispath", False):
resolved_value = target.toppingfile_link(
ProjectTopping.GENERIC_TYPE,
self[variable_key].get("value"),
)
resolved_items[variable_key] = resolved_value
return resolved_items

class Properties(dict):
"""
Expand Down Expand Up @@ -613,9 +645,9 @@ def _projecttopping_dict(self, target: Target):
mapthemes_dict = dict(self.mapthemes)
if mapthemes_dict:
projecttopping_dict["mapthemes"] = mapthemes_dict
variables_dict = dict(self.variables)
if variables_dict:
projecttopping_dict["variables"] = variables_dict
variables_resolved_dict = self.variables.resolved_dict(target)
if variables_resolved_dict:
projecttopping_dict["variables"] = variables_resolved_dict
properties_dict = dict(self.properties)
if properties_dict:
projecttopping_dict["properties"] = properties_dict
Expand Down

0 comments on commit 9871d4f

Please sign in to comment.