def test_init(self): # Success qpath = HubitQueryPath("lines[:].tanks[:].vol_outlet_flow") mpaths = [ "lines[IDX_LINE].tanks[0@IDX_TANK].vol_outlet_flow", "lines[IDX_LINE].tanks[1@IDX_TANK].vol_outlet_flow", "lines[IDX_LINE].tanks[2@IDX_TANK].vol_outlet_flow", ] mpaths = [HubitModelPath(mpath) for mpath in mpaths] # Use a dummy tree. It will not be used since the path normalization is bypassed tree = DummyLengthTree() cmps = get_mock_components(mpaths) _QueryExpansion(qpath, mpaths, tree, cmps) # mpaths cannot have different index contexts qpath = HubitQueryPath("lines[:].tanks[:].vol_outlet_flow") mpaths = [ "lines[IDX_LINE].tanks[0@IDX_TANK].vol_outlet_flow", "lines[IDX_LINE].tanks[1@IDX_OTHER].vol_outlet_flow", ] mpaths = [HubitModelPath(mpath) for mpath in mpaths] cmps = get_mock_components(mpaths) with pytest.raises(HubitModelQueryError): _QueryExpansion(qpath, mpaths, tree, cmps) # No mpaths i.e. no provider qpath = HubitQueryPath("lines[:].tanks[:].vol_outlet_flow") mpaths = [] cmps = get_mock_components(mpaths) with pytest.raises(HubitModelQueryError): _QueryExpansion(qpath, mpaths, tree, cmps)
def _get_qexp(): path = HubitModelPath( "lines[IDX_LINE].tanks[0@IDX_TANK].vol_outlet_flow") yml_input = """ lines: - tanks: - tank1: 1 - tank2: 2 - tank3: 3 - tanks: - tank1: 1 - tank2: 2 - tank3: 3 - tank4: 4 """ input_data = yaml.load(yml_input, Loader=yaml.FullLoader) tree = LengthTree.from_data(path, input_data) qpath = HubitQueryPath("lines[:].tanks[:].vol_outlet_flow") mpaths = [ "lines[IDX_LINE].tanks[0@IDX_TANK].vol_outlet_flow", "lines[IDX_LINE].tanks[1@IDX_TANK].vol_outlet_flow", "lines[IDX_LINE].tanks[2@IDX_TANK].vol_outlet_flow", ] mpaths = [HubitModelPath(mpath) for mpath in mpaths] cmps = get_mock_components(mpaths) qexp = _QueryExpansion(qpath, mpaths, tree, cmps) return qexp
def test_paths_between_specifiers_tailed(self): path = HubitModelPath( "segments[IDX_SEG].layers[IDX_LAY].test.positions[IDX_POS].attr") paths = path.paths_between_specifiers() # Last element is empty since there are no attribute after IDX_POS expected_paths = ["segments", "layers", "test.positions", "attr"] self.assertSequenceEqual(expected_paths, paths)
def test_none_like_2(self): """ Get a nested list corresponding to a tree with only node element per nested list """ # yml_input = """ segments: - layers: - dummy1: 0.1 dummy2: dummy_value test: positions: - 1 """ input_data = yaml.load(yml_input, Loader=yaml.FullLoader) # Point to all elements path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") tree = LengthTree.from_data(path, input_data) # print(tree) # print(tree.to_list()) result = tree.none_like() print(result) # expected_result = [None] # self.assertListEqual(result, expected_result) path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[IDX_POS]") tree = LengthTree.from_data(path, input_data) # print(tree) # print(tree.to_list()) result = tree.none_like() print(result)
def test_remove_braces(self): path = HubitModelPath("segs[:@IDX_SEG].walls[IDX_WALL].heat_flow") result = path.remove_braces() expected_result = "segs.walls.heat_flow" self.assertEqual(result, expected_result) result = path.field_names() expected_result = ["segs", "walls", "heat_flow"] self.assertSequenceEqual(result, expected_result)
def test_get_paths(self): cfg = { "path": "dummy", "func_name": "dummy", "provides_results": [ { "name": "attr", "path": "list[IDX].attr.path2" }, ], "consumes_input": [ { "name": "attr1", "path": "shared.input.attr.path1" }, { "name": "attr2", "path": "shared.input.attr.path2" }, ], "consumes_results": [ { "name": "attr3", "path": "shared.input.attr.path3" }, { "name": "attr4", "path": "shared.input.attr.path4" }, ], } cmp = HubitModelComponent.from_cfg(cfg, 0) result = set(cmp.consumes_input_paths) expected_result = set([ HubitModelPath("shared.input.attr.path1"), HubitModelPath("shared.input.attr.path2"), ]) assert result == expected_result result = set(cmp.consumes_results_paths) expected_result = set([ HubitModelPath("shared.input.attr.path3"), HubitModelPath("shared.input.attr.path4"), ]) assert result == expected_result result = set(cmp.provides_results_paths) expected_result = set([ HubitModelPath("list[IDX].attr.path2"), ]) assert result == expected_result
def test_expand_mpath6(self): """As test 8 but the consumed path only subscribes to element 1 of the (leftmost) items. Thus, the expansion leads to a flat list corresponding to the (rightmost) items """ input_data = { "items_a": [ { "attr": { "items": [{ "path": 2 }, { "path": 1 }] } }, { "attr": { "items": [{ "path": 3 }, { "path": 4 }] } }, ], "some_number": 33, } path_consumed_for_name = { "attrs": HubitModelPath("items_a[1@IDX1].attr.items[:@IDX2].path"), "number": HubitModelPath("some_number"), } expected_result = { "attrs": ["items_a[1].attr.items[0].path", "items_a[1].attr.items[1].path"], "number": ["some_number"], } tree_for_name = { name: LengthTree.from_data(path, input_data, prune=True) for name, path in path_consumed_for_name.items() } tree_for_name["attrs"].prune_from_path(path_consumed_for_name["attrs"]) result = { name: tree.expand_path(path_consumed_for_name[name]) for name, tree in tree_for_name.items() } self.assertDictEqual(expected_result, result)
def test_expand_mpath5(self): """Expand subscription path with two wildcards gives a nested list""" input_data = { "items": [ { "attr": { "items": [{ "path": 2 }, { "path": 1 }] } }, { "attr": { "items": [{ "path": 3 }, { "path": 4 }] } }, ], "some_number": 33, } path_consumed_for_name = { "attrs": HubitModelPath("items[:@IDX1].attr.items[:@IDX2].path"), "number": HubitModelPath("some_number"), } expected_result = { "attrs": [ ["items[0].attr.items[0].path", "items[0].attr.items[1].path"], ["items[1].attr.items[0].path", "items[1].attr.items[1].path"], ], "number": ["some_number"], } tree_for_name = { name: LengthTree.from_data(path, input_data) for name, path in path_consumed_for_name.items() } result = { name: tree.prune_from_path(path_consumed_for_name[name]).expand_path( path_consumed_for_name[name]) for name, tree in tree_for_name.items() } self.assertDictEqual(expected_result, result)
def test_bindings_from_idxs_1(self): """ Substitute idxids with idxs. Second index ID contains a wildcard and should be left as is """ bindings = [ HubitBinding.from_cfg( { "name": "outer_temperature_all_layers", "path": "segments[IDX_SEG].layers[:@IDX_LAY].outer_temperature", } ) ] idxval_for_idxid = {"IDX_SEG": "0"} path_for_name = _Worker.bindings_from_idxs(bindings, idxval_for_idxid) expected_path_for_name = { "outer_temperature_all_layers": HubitModelPath( "segments[0@IDX_SEG].layers[:@IDX_LAY].outer_temperature" ) } self.assertDictEqual(path_for_name, expected_path_for_name) self.assertTrue( all([type(item) == HubitModelPath for item in path_for_name.values()]) )
def setUp(self): # lengths = [['IDX_SEG', 2], # ['IDX_LAY', [3, 4]], # ['IDX_POS', [[1, 3, 2], [5, 1, 2, 4]]]] seg_nodes = LengthNode(2) lay_nodes = LengthNode(3), LengthNode(4) pos_lay0_nodes = ( LengthNode(1), LengthNode(3), LengthNode(2), ) pos_lay1_nodes = ( LengthNode(5), LengthNode(1), LengthNode(2), LengthNode(4), ) seg_nodes.set_children(lay_nodes) lay_nodes[0].set_children(pos_lay0_nodes) lay_nodes[1].set_children(pos_lay1_nodes) nodes = [seg_nodes] nodes.extend(lay_nodes) nodes.extend(pos_lay0_nodes) nodes.extend(pos_lay1_nodes) level_names = "IDX_SEG", "IDX_LAY", "IDX_POS" self.tree = LengthTree(nodes, level_names) self.template_path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]")
def test_get_bindings(self): """ Get bindings for query where model path is fully specified """ bindings = [ HubitBinding.from_cfg( { "name": "inflow", "path": "inlets[0@IDX_INLET].tanks[2@IDX_TANK].inflow", } ) ] # The query path mathces the model path querypath = HubitQueryPath("inlets[0].tanks[2].inflow") path_for_name, idxval_for_idxid = _Worker.get_bindings(bindings, querypath) expected_idxval_for_idxid = {"IDX_INLET": "0", "IDX_TANK": "2"} self.assertDictEqual(expected_idxval_for_idxid, idxval_for_idxid) expected_path_for_name = { "inflow": HubitModelPath("inlets[0@IDX_INLET].tanks[2@IDX_TANK].inflow") } self.assertDictEqual(expected_path_for_name, path_for_name) querypath = HubitQueryPath("inlets.1.tanks.2.inflow") with self.assertRaises(HubitWorkerError): _Worker.get_bindings(bindings, querypath)
def test_6(self): """ Get bindings for query with two location IDs and component bindings with one index ID and one index wildcard. The index wildcard is left as is since it is handled by the expansion """ bindings = [ HubitBinding.from_cfg( { "name": "k_therm", "path": "segments[IDX_SEG].layers[:@IDX_LAY].k_therm", } ) ] querystring = HubitQueryPath("segments[0].layers[0].k_therm") path_for_name, _ = _Worker.get_bindings(bindings, querystring) # This is what will be provided for the query: The attribute 'k_therm' # for all layers for the specific index ID _IDX=0 # expected_path_for_name = {"k_therm": "segments.0.layers.:.k_therm"} expected_path_for_name = { "k_therm": HubitModelPath("segments[0@IDX_SEG].layers[:@IDX_LAY].k_therm") } self.assertDictEqual(expected_path_for_name, path_for_name) self.assertTrue( all([type(item) == HubitModelPath for item in path_for_name.values()]) )
def test_expand_mpath3(self): """Prune tree before expanding. Two indices vary so expanded paths is 2D """ # 1 + 3 + 2 values for segment 0 expected_paths = [ [ "segments[0].layers[0].test.positions[0]", ], [ "segments[0].layers[1].test.positions[0]", "segments[0].layers[1].test.positions[1]", "segments[0].layers[1].test.positions[2]", ], [ "segments[0].layers[2].test.positions[0]", "segments[0].layers[2].test.positions[1]", ], ] mpath = HubitModelPath( "segments[0@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") pruned_tree = self.tree.prune_from_path(mpath, inplace=False) paths = pruned_tree.expand_path(mpath) self.assertSequenceEqual(paths, expected_paths)
def test_expand_path2(self): """Expand path""" paths = ( HubitModelPath("segments[:@IDX_SEG].layers[:@IDX_LAY].test"), HubitQueryPath("segments[:].layers[:].test"), ) # path = "segments.:@IDX_SEG.layers.:@IDX_LAY.test" seg_node = LengthNode(2) lay_nodes = LengthNode(2), LengthNode(2) seg_node.set_children(lay_nodes) nodes = [seg_node] nodes.extend(lay_nodes) level_names = "IDX_SEG", "IDX_LAY" tree = LengthTree(nodes, level_names) # 2 values for segment 0 and 2 values for segment 1 expected_paths = [ [ "segments[0].layers[0].test", "segments[0].layers[1].test", ], [ "segments[1].layers[0].test", "segments[1].layers[1].test", ], ] for path in paths: with self.subTest(path=path): expanded_paths = tree.prune_from_path(path).expand_path(path) self.assertSequenceEqual(expanded_paths, expected_paths)
def test_validate_tree_fail(self): qexp = TestQueryExpansion._get_qexp() # Tree corresponds to something 'segments[IDX_SEG].layers[IDX_LAY]' # while qexp was decomposed for the identifier 'IDX_TANK' path = HubitModelPath("segments[IDX_SEG].layers[:@IDX_LAY]") yml_input = """ segments: - layers: - thickness: 0.1 # [m] material: brick - thickness: 0.1 material: brick - layers: - thickness: 0.15 material: concrete - thickness: 0.1 material: concrete """ input_data = yaml.load(yml_input, Loader=yaml.FullLoader) qexp.tree = LengthTree.from_data(path, input_data) with pytest.raises(HubitError): qexp._validate_tree()
def test_validate_tree(self): qexp = TestQueryExpansion._get_qexp() qexp._validate_tree() # DummyTree passes validation path = HubitModelPath("segments.layers.positions") qexp.tree = LengthTree.from_data(path, {}) qexp._validate_tree()
def test_expand_mpath4(self): """Prune tree before expanding. One index varies so expanded paths is 1D """ print(self.tree) path = HubitModelPath( "segments[0@IDX_SEG].layers[:@IDX_LAY].test.positions[1@IDX_POS]") # path = HubitModelPath("segments[0].layers[:@IDX_LAY].test.positions[1]") template_path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") self.tree.prune_from_path(path) # 1 + 3 + 2 values for segment 0 expected_paths = [ "segments[0].layers[1].test.positions[1]", "segments[0].layers[2].test.positions[1]", ] paths = self.tree.expand_path(path) self.assertSequenceEqual(paths, expected_paths)
def test_new_with_index(self): # Replace only first occurrence path = HubitModelPath("segments[1].lay1ers[1]") path = path.new_with_index("1", "11") assert path == HubitModelPath("segments[11].lay1ers[1]") # Do not change a match in the field name (1 in lay1ers) path = HubitModelPath("segments[2].lay1ers[1]") path = path.new_with_index("1", "11") print(path) assert path == HubitModelPath("segments[2].lay1ers[11]")
def test_2a(self): """Outside bounds top level index""" path = HubitModelPath( "segments[2@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") with self.assertRaises(HubitIndexError) as context: self.tree.prune_from_path(path) path = HubitQueryPath("segments[2].layers[:].test.positions[:]") with self.assertRaises(HubitIndexError) as context: self.tree.prune_from_path(path)
def test_from_data1(self): """Extract lengths from input for path""" yml_input = """ segments: - layers: - thickness: 0.1 # [m] material: brick test: positions: [1, ] - thickness: 0.02 material: air test: positions: [1, 2, 3] - thickness: 0.1 material: brick test: positions: [1, 3] inside: temperature: 320. outside: temperature: 273. - layers: - thickness: 0.15 material: concrete test: positions: [1, 2, 3, 4, 5] - thickness: 0.025 material: EPS test: positions: [1,] - thickness: 0.1 material: concrete test: positions: [1, 2,] - thickness: 0.001 material: paint test: positions: [1, 2, 3, 4] inside: temperature: 300. outside: temperature: 273. """ input_data = yaml.load(yml_input, Loader=yaml.FullLoader) # path = "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]" path = HubitModelPath( "segments[IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") tree = LengthTree.from_data(path, input_data) tree_as_list = tree.to_list() # print(tree_as_list) # TODO test paths in this case # path = "segments[:@IDX_SEG].layers[:@IDX_LAY].test" expected_lengths = [2, [3, 4], [[1, 3, 2], [5, 1, 2, 4]]] self.assertSequenceEqual(expected_lengths, tree_as_list)
def test_expand_mpath1(self): """Expand to full template path""" path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") # 1 + 3 + 2 values for segment 0 and 5 + 1 + 2 + 4 values for segment 1 # All all 18 elements expected_paths = [ [ # IDX_SEG element 0 has 3 IDX_LAY elements [ # IDX_LAY element 0 has 1 IDX_POS elements "segments[0].layers[0].test.positions[0]" ], [ # IDX_LAY element 1 has 3 IDX_POS elements "segments[0].layers[1].test.positions[0]", "segments[0].layers[1].test.positions[1]", "segments[0].layers[1].test.positions[2]", ], [ # IDX_LAY element 2 has 2 IDX_POS elements "segments[0].layers[2].test.positions[0]", "segments[0].layers[2].test.positions[1]", ], ], [ # IDX_SEG element 1 has 4 IDX_LAY elements [ # IDX_LAY element 0 has 5 IDX_POS elements "segments[1].layers[0].test.positions[0]", "segments[1].layers[0].test.positions[1]", "segments[1].layers[0].test.positions[2]", "segments[1].layers[0].test.positions[3]", "segments[1].layers[0].test.positions[4]", ], [ # IDX_LAY element 0 has 1 IDX_POS elements "segments[1].layers[1].test.positions[0]", ], [ # IDX_LAY element 0 has 2 IDX_POS elements "segments[1].layers[2].test.positions[0]", "segments[1].layers[2].test.positions[1]", ], [ # IDX_LAY element 0 has 4 IDX_POS elements "segments[1].layers[3].test.positions[0]", "segments[1].layers[3].test.positions[1]", "segments[1].layers[3].test.positions[2]", "segments[1].layers[3].test.positions[3]", ], ], ] paths = self.tree.prune_from_path(path, inplace=False).expand_path(path) self.assertSequenceEqual(paths, expected_paths) # Cannot expand without pruning with self.assertRaises(HubitError) as context: paths = self.tree.expand_path(path)
def test_5(self): """Two indices fixed""" expected_lengths = [1, 4, [1, 1, 1, 1]] path = HubitModelPath( "segments[1@IDX_SEG].layers[:@IDX_LAY].test.positions[0@IDX_POS]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths) path = HubitQueryPath("segments[1].layers[:].test.positions[0]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths)
def test_4(self): """In bounds for all bottom-most paths.""" expected_lengths = [2, [3, 4], [[1, 1, 1], [1, 1, 1, 1]]] path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions[0@IDX_POS]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths) path = HubitQueryPath("segments[:].layers[:].test.positions[0]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths)
def test_3(self): """Middle index fixed""" expected_lengths = [2, [1, 1], [[3], [1]]] path = HubitModelPath( "segments[:@IDX_SEG].layers[1@IDX_LAY].test.positions[:@IDX_POS]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths) path = HubitQueryPath("segments[:].layers[1].test.positions[:]") pruned_tree = self.tree.prune_from_path(path) self.assertListEqual(pruned_tree.to_list(), expected_lengths)
def test_is_path_described_model_paths(self): print(self.tree) # Path with no ranges is not described by a LengthTree assert not self.tree.is_path_described(HubitModelPath("i.dont.exist")) assert self.tree.is_path_described( HubitModelPath( "segments[0@IDX_SEG].layers[0@IDX_LAY].test.positions[0@IDX_POS]" )) assert not self.tree.is_path_described( HubitModelPath( "segments[0@IDX_SEG].layers[0@IDX_LAY].test.positions[1@IDX_POS]" )) # Wrong index context assert not self.tree.is_path_described( HubitModelPath( "segments[0@IDX_WRONG].layers[0@IDX_LAY].test.positions[0@IDX_POS]" ))
def test_2(self): """Top level index fixed to 1""" expected_lengths = [1, 4, [5, 1, 2, 4]] path = HubitModelPath( "segments[1@IDX_SEG].layers[:@IDX_LAY].test.positions[:@IDX_POS]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths) path = HubitQueryPath("segments[1].layers[:].test.positions[:]") pruned_tree = self.tree.prune_from_path(path, inplace=False) self.assertListEqual(pruned_tree.to_list(), expected_lengths)
def test_filter_mpaths_for_qpath_index_ranges(self): qpath = HubitQueryPath("sites[0].lines[0].tanks[:].Q_yield") mpaths = [ HubitModelPath( "sites[0@IDX_SITE].lines[0@IDX_LINE].tanks[IDX_TANK].Q_yield"), HubitModelPath( "sites[0@IDX_SITE].lines[0@IDX_LINE].tanks[IDX_TANK].Q_yield"), HubitModelPath( "sites[0@IDX_SITE].lines[1@IDX_LINE].tanks[IDX_TANK].Q_yield"), ] # Index scpoe for each mpath index_scopes = [ { "IDX_TANK": PathIndexRange("0") }, { "IDX_TANK": PathIndexRange("1:") }, { "IDX_TANK": PathIndexRange(":") }, ] tree, _ = _get_data() pruned_tree = tree.prune_from_path(qpath, inplace=False) result = _QueryExpansion._filter_mpaths_for_qpath_index_ranges( qpath, mpaths, index_scopes, pruned_tree, ) expected_result = [ mpath.set_range_for_idxid(index_scope) for mpath, index_scope in zip(mpaths[:2], index_scopes[:2]) ] assert result == expected_result
def test_6(self): """Out of bounds for all paths The tree is modified even when an error is raised if inplace=True Thats is OK since Hubit will raise an error and stop execution """ path = HubitModelPath( "segments[:@IDX_SEG].layers[:@IDX_LAY].test.positions1[7@IDX_POS]") with self.assertRaises(HubitIndexError) as context: self.tree.prune_from_path(path, inplace=False) path = HubitQueryPath("segments[:].layers[:].test.positions1[7]") with self.assertRaises(HubitIndexError) as context: self.tree.prune_from_path(path, inplace=False)
def test_path_match(self): # Match qpath = HubitQueryPath("segs[42].walls[3].temps") mpath = HubitModelPath("segs[IDX1].walls[IDX1].temps") assert qpath.path_match(mpath) # Match mpath = HubitModelPath("segs[:@IDX1].walls[IDX1].temps") assert qpath.path_match(mpath) # No match: different field names mpath = HubitModelPath("seg[:@IDX1].wall[IDX1].temp") assert not qpath.path_match(mpath) # No match: different field count qpath = HubitQueryPath("segs[42].walls[3].temps") mpath = HubitModelPath("segs[IDX1].walls[IDX1]") assert not qpath.path_match(mpath) # No match: different brace count qpath = HubitQueryPath("segs[42].walls[3].temps") mpath = HubitModelPath("segs.walls[IDX1].temps") assert not qpath.path_match(mpath) # No match: no intersection for second index qpath = HubitQueryPath("segs[42].walls[3].temps") mpath = HubitModelPath("segs[IDX1].walls[43@IDX2].temps") assert not qpath.path_match(mpath) ### Negative index in query # Match: negative index in query qpath = HubitQueryPath("segs[42].walls[-1].temps") mpath = HubitModelPath("segs[IDX1].walls[IDX1].temps") assert qpath.path_match(mpath) # Match: negative index in query mpath = HubitModelPath("segs[IDX1].walls[:@IDX1].temps") assert qpath.path_match(mpath) # No match: negative index in query. Index 12 might be the last index, i.e. math -1 but we cannot guarantee it mpath = HubitModelPath("segs[IDX1].walls[12@IDX1].temps") assert not qpath.path_match(mpath)
def test_bindings_from_idxs_0(self): """ Substitute idxids with idxs """ bindings = [{"name": "heat_flux", "path": "segments[IDX_SEG].heat_flux"}] bindings = [HubitBinding.from_cfg(binding) for binding in bindings] idxval_for_idxid = {"IDX_SEG": "3"} path_for_name = _Worker.bindings_from_idxs(bindings, idxval_for_idxid) expected_path_for_name = { "heat_flux": HubitModelPath("segments[3@IDX_SEG].heat_flux") } self.assertDictEqual(path_for_name, expected_path_for_name) self.assertTrue( all([type(item) == HubitModelPath for item in path_for_name.values()]) )