Coverage for tests / tests_config / tests_description / test_config_blocks.py: 100%
69 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-09 16:40 +0100
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-09 16:40 +0100
1# SPDX-FileCopyrightText: Copyright INRIA
2#
3# SPDX-License-Identifier: LGPL-3.0-only
4#
5# Copyright INRIA
6#
7# This file is part of PhysioBlocks, a library mostly developed by the
8# [Ananke project-team](https://team.inria.fr/ananke) at INRIA.
9#
10# Authors:
11# - Colin Drieu
12# - Dominique Chapelle
13# - François Kimmig
14# - Philippe Moireau
15#
16# PhysioBlocks is free software: you can redistribute it and/or modify it under the
17# terms of the GNU Lesser General Public License as published by the Free Software
18# Foundation, version 3 of the License.
19#
20# PhysioBlocks is distributed in the hope that it will be useful, but WITHOUT ANY
21# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
23#
24# You should have received a copy of the GNU Lesser General Public License along with
25# PhysioBlocks. If not, see <https://www.gnu.org/licenses/>.
27from dataclasses import dataclass
28from typing import Any
29from unittest.mock import patch
31import pytest
33from physioblocks.computing.models import Block, ModelComponent
34from physioblocks.computing.quantities import Quantity
35from physioblocks.configuration import Configuration
36from physioblocks.configuration.constants import (
37 BLOCK_FLUX_TYPE_ITEM_ID,
38 MODEL_COMPONENT_TYPE_ITEM_ID,
39 SUBMODEL_ITEM_ID,
40)
41from physioblocks.configuration.description.blocks import (
42 PARAMETERS_ITEM_ID,
43 load_block_description_config,
44 save_block_description_config,
45)
46from physioblocks.description.blocks import (
47 BLOCK_DESCRIPTION_TYPE_ID,
48 ID_SEPARATOR,
49 MODEL_DESCRIPTION_TYPE_ID,
50 BlockDescription,
51 ModelComponentDescription,
52)
54BLOCK_A_ID = "block_a"
55BLOCK_A_TYPE_ID = "BlockA"
56MODEL_B_TYPE_ID = "ModelComponentB"
57SUBMODEL_KEY = "submodel"
58PARAM_LOCAL_ID_A = "a"
59PARAM_LOCAL_ID_B = "b"
60PARAM_LOCAL_ID_C = "c"
61PARAM_GLOBAL_ID_A = "param_a"
62PARAM_GLOBAL_ID_B = "param_b"
63PARAM_GLOBAL_ID_C = "param_c"
64TIME_GLOBAL_ID = "time"
65FLUX_TYPE = "flux"
68@dataclass
69class BlockA(Block):
70 a: Quantity[Any]
71 b: Quantity[Any]
72 c: Quantity[Any]
75@dataclass
76class ModelComponentB(ModelComponent):
77 a: Quantity[Any]
78 b: Quantity[Any]
79 c: Quantity[Any]
82@pytest.fixture
83def ref_block_desc():
84 block_desc = BlockDescription(
85 BLOCK_A_ID,
86 BlockA,
87 FLUX_TYPE,
88 {
89 PARAM_LOCAL_ID_A: PARAM_GLOBAL_ID_A,
90 PARAM_LOCAL_ID_B: PARAM_GLOBAL_ID_B,
91 },
92 )
93 block_desc.add_submodel(
94 SUBMODEL_KEY,
95 ModelComponentDescription(
96 SUBMODEL_KEY,
97 ModelComponentB,
98 {
99 PARAM_LOCAL_ID_A: PARAM_GLOBAL_ID_C,
100 PARAM_LOCAL_ID_B: PARAM_GLOBAL_ID_A,
101 },
102 ),
103 )
104 return block_desc
107@pytest.fixture
108def ref_config() -> Configuration:
109 config = Configuration(BLOCK_DESCRIPTION_TYPE_ID)
110 config[MODEL_COMPONENT_TYPE_ITEM_ID] = BLOCK_A_TYPE_ID
111 config[BLOCK_FLUX_TYPE_ITEM_ID] = FLUX_TYPE
112 config[PARAMETERS_ITEM_ID] = {}
113 config[PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_A] = PARAM_GLOBAL_ID_A
114 config[PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_B] = PARAM_GLOBAL_ID_B
115 submodel_config = Configuration(MODEL_DESCRIPTION_TYPE_ID)
116 submodel_config[MODEL_COMPONENT_TYPE_ITEM_ID] = MODEL_B_TYPE_ID
117 submodel_config[PARAMETERS_ITEM_ID] = {}
118 submodel_config[PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_A] = PARAM_GLOBAL_ID_C
119 submodel_config[PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_B] = PARAM_GLOBAL_ID_A
120 config[SUBMODEL_ITEM_ID] = {SUBMODEL_KEY: submodel_config}
121 return config
124@pytest.fixture
125def saved_config_ref(ref_config: Configuration) -> Configuration:
126 config = ref_config
127 config[MODEL_COMPONENT_TYPE_ITEM_ID] = BLOCK_A_TYPE_ID
128 config[PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_C] = ID_SEPARATOR.join(
129 [BLOCK_A_ID, PARAM_LOCAL_ID_C]
130 )
131 config[SUBMODEL_ITEM_ID][SUBMODEL_KEY][PARAMETERS_ITEM_ID][PARAM_LOCAL_ID_C] = (
132 ID_SEPARATOR.join([BLOCK_A_ID, SUBMODEL_KEY, PARAM_LOCAL_ID_C])
133 )
134 return config
137@patch(
138 "physioblocks.registers.type_register.__type_register",
139 new={
140 BLOCK_DESCRIPTION_TYPE_ID: BlockDescription,
141 BlockDescription: BLOCK_DESCRIPTION_TYPE_ID,
142 MODEL_DESCRIPTION_TYPE_ID: ModelComponentDescription,
143 ModelComponentDescription: MODEL_DESCRIPTION_TYPE_ID,
144 BLOCK_A_TYPE_ID: BlockA,
145 BlockA: BLOCK_A_TYPE_ID,
146 MODEL_B_TYPE_ID: ModelComponentB,
147 ModelComponentB: MODEL_B_TYPE_ID,
148 },
149)
150def test_get_block_config(
151 saved_config_ref: Configuration, ref_block_desc: BlockDescription
152):
153 configuration = save_block_description_config(ref_block_desc)
154 assert saved_config_ref == configuration
157@patch(
158 "physioblocks.registers.type_register.__type_register",
159 new={
160 BLOCK_DESCRIPTION_TYPE_ID: BlockDescription,
161 BlockDescription: BLOCK_DESCRIPTION_TYPE_ID,
162 MODEL_DESCRIPTION_TYPE_ID: ModelComponentDescription,
163 ModelComponentDescription: MODEL_DESCRIPTION_TYPE_ID,
164 BLOCK_A_TYPE_ID: BlockA,
165 BlockA: BLOCK_A_TYPE_ID,
166 MODEL_B_TYPE_ID: ModelComponentB,
167 ModelComponentB: MODEL_B_TYPE_ID,
168 },
169)
170def test_configure_block(ref_config: Configuration, ref_block_desc: BlockDescription):
171 block_desc = load_block_description_config(ref_config, BLOCK_A_ID, BlockDescription)
172 assert isinstance(block_desc, BlockDescription)
173 assert block_desc.global_ids == ref_block_desc.global_ids
174 assert (
175 block_desc.submodels[SUBMODEL_KEY].global_ids
176 == ref_block_desc.submodels[SUBMODEL_KEY].global_ids
177 )