def test_block_class(): """Test block parsing""" # Set up block1_def = ("y1 1 2 45\n" "y2 2 3 50") block1 = ".subckt block1 1 2 n3 n12\n" \ + block1_def + "\n" \ + ".ends block1" block2_def = ("y3 4 5 100\n" "y4 3 4 whatever") block2 = ".subckt block2 1 2 n3 n12\n" \ + block2_def + "\n" \ ".ends block2" elems1 = "y6 2 4 90\n" \ + "yLEM45 1 2 64" elems2 = "ys1 s1 1 10\n" \ + "ys2 s2 3 10k\n" \ + "ys3 s2 s1 1M\n" \ + "x1 1=1 2=2 n3=3 n12=4 name=BLocK1" block_str = block1 + "\n\t" + elems1 + "\n" + block2 + "\n\n" + elems2 block_repr1 = block1 + "\n" + block2 + "\n" + elems1 + "\n" + elems2 block_repr2 = block2 + "\n" + block1 + "\n" + elems1 + "\n" + elems2 block_defs = block_str.split('\n') elem = Element(definition='yN1 4 new_node 324k') elem_duplicate = Element(definition='y56 2 3 43k') # Test 1: Instantiation flatten_block = Block('test', ('1', 'n2', 'node3'), block_defs) block = Block('test', ('n1', 'n2', 'node3'), block_defs) # Test 2: Parsing correctness assert len(block.blocks) == 2, 'Incorrect number of blocks detected.' assert len(block.elements) == 6, 'Block elements not fully populated.' b1 = block.blocks.get('block1') b2 = block.blocks.get('block2') b1_instance = block.elements[block.elements.index('x1')] assert b1, 'Nested block key failure.' assert b2, 'Nested block key failure.' assert b1.name == 'block1', "Nested block name parsing failed." assert b2.name == 'block2', "Nested block name parsing failed." assert b1.definition == block1_def.lower(), "Nested block def generation failed." assert b2.definition == block2_def.lower(), "Nested block def generation failed." assert str(b1).strip() == block1.lower(), 'Nested block to string conv failed.' assert b1_instance.block.name == 'block1', "Block instance failed." assert block.definition == block_repr1.lower() or \ block.definition == block_repr2.lower(),\ 'Top level block-string conv. failed.' # Test 3: Block manipulation es3 = block.element('yS3') assert es3 is not None and es3.name == 'ys3', 'Element search failed.' block.add(elem) assert elem in block.elements, 'Element addition failed.' assert elem.name in block.elements, 'Element membership by name failed.' assert elem in block.graph[elem.nodes[0]], 'Element addition failed.' assert elem in block.graph[elem.nodes[1]], 'Element addition failed.' try: block.add(elem_duplicate) except ValueError: pass block.remove(elem) assert elem not in block.elements, 'Element removal failed.' assert elem not in block.graph[elem.nodes[0]], 'Element removal failed.' assert block.graph.get(elem.nodes[1]) is None, 'Element removal failed.' block.add_block(block) assert block in block.blocks, 'Programmatic block addition failed.' block.add(block.instance('xTest', n1='n5', n2='n6', node3='n7')) assert 'xtest' in block.elements, 'Programmatic instance addition failed.' block.remove_block(block) assert block.name not in block.blocks, 'Programmatic block removal failed.' assert 'xtest' not in block.elements, 'Programmatic instance removal failed.' block.short('s2', 's1') assert 's2' not in block.graph, 'Shorted node not removed from block.' assert 'ys3' not in block.elements, 'Shorted elements not removed.' assert len(block.graph['s1']) == 2, 'Incorrect element union after short.' # Test 5: block flattening flatten_block.flatten() assert 'x1' not in flatten_block.elements, 'Flattened block instance not removed.' assert len(flatten_block.blocks) == 0, 'Block defs not removed after flattening.' assert 'yblock1x1y1' in flatten_block.elements, 'Block instance not expanded.' assert 'yblock1x1y2' in flatten_block.elements, 'Block instance not expanded.' assert 'block1x13' in flatten_block.graph, 'Internal block node not flattened.' # Test 6: block search assert flatten_block.element('y6') == 'y6', 'Single element block retreival failed.' assert len(flatten_block.elements_like('y')) == 7, 'Multiple element retreival failed.'