"""Tests for the SES indent writer and identifier quoting.""" from __future__ import annotations from freeroute.ses.indent import Identifier, IndentWriter def test_nested_scopes_indent_by_two_spaces(): out = IndentWriter() out.start_scope(new_line=False) out.write("session x") out.start_scope() out.write("routes") out.end_scope() out.end_scope() assert out.getvalue() == "(session x\n (routes\n )\n)" def test_new_line_uses_current_indent(): out = IndentWriter() out.start_scope(new_line=False) out.write("a") out.new_line() out.write("(b)") out.end_scope() assert out.getvalue() == "(a\n (b)\n)" def test_plain_name_not_quoted(): ident = Identifier() assert ident.format("Top") == "Top" assert ident.format("U1") == "U1" assert ident.format("F.Cu") == "F.Cu" # '.' is not reserved def test_reserved_chars_force_quotes(): ident = Identifier() assert ident.format("NET_A") == '"NET_A"' # underscore reserved assert ident.format("a-b") == '"a-b"' # hyphen reserved assert ident.format("with space") == '"with space"' assert ident.format("Via[0-1]_600:300_um") == '"Via[0-1]_600:300_um"' def test_leading_digit_forces_quotes(): ident = Identifier() assert ident.format("2layer") == '"2layer"' assert ident.format("-3x") == '"-3x"' def test_non_ascii_forces_quotes(): ident = Identifier() assert ident.format("Паяльная") == '"Паяльная"' def test_surrounding_quotes_stripped_before_reprocessing(): ident = Identifier() # already-quoted plain name comes back unquoted assert ident.format('"Top"') == "Top" def test_embedded_quote_removed(): ident = Identifier() assert ident.format('a"b') == "ab"