"""Tests for the S-expression tree parser.""" from __future__ import annotations import pytest from freeroute.dsn.sexp import SExp, parse from freeroute.dsn.tokenizer import DsnSyntaxError, Token def test_parse_simple_head_and_values(): tree = parse("(resolution um 10)") assert tree.head == "resolution" vals = tree.values() assert [v.text for v in vals] == ["um", "10"] def test_nested_children(): tree = parse("(structure (layer Top (type signal)) (layer Bot (type signal)))") assert tree.head == "structure" layers = tree.children("layer") assert len(layers) == 2 assert isinstance(layers[0], SExp) assert layers[0].values()[0].text == "Top" type_scope = layers[0].child("type") assert type_scope is not None assert type_scope.values()[0].text == "signal" def test_child_missing_returns_none(): tree = parse("(a (b 1))") assert tree.child("nope") is None def test_values_skips_nested_lists(): tree = parse("(net NET_A (pins U1-1 R2-2))") assert [v.text for v in tree.values()] == ["NET_A"] pins = tree.child("pins") assert pins is not None assert [v.text for v in pins.values()] == ["U1-1", "R2-2"] def test_leaf_items_are_tokens(): tree = parse("(a 1 2)") assert all(isinstance(it, Token) for it in tree.items) def test_unbalanced_raises(): with pytest.raises(DsnSyntaxError): parse("(a (b )") def test_trailing_token_raises(): with pytest.raises(DsnSyntaxError): parse("(a) (b)") def test_no_toplevel_list_raises(): with pytest.raises(DsnSyntaxError): parse("just atoms no parens")