Coverage for tests/pex25d/pex25d_fixtures.py: 96%
26 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-17 19:08 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-09-17 19:08 +0000
1#
2# --------------------------------------------------------------------------------
3# SPDX-FileCopyrightText: 2024-2026 Martin Jan Köhler and Harald Pretl
4# Johannes Kepler University, Institute for Integrated Circuits.
5#
6# This file is part of KPEX
7# (see https://github.com/iic-jku/klayout-pex).
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
21# SPDX-License-Identifier: GPL-3.0-or-later
22# --------------------------------------------------------------------------------
23#
25"""
26A small but complete PEX25D file, and the helpers the tests read it with.
28The fixture is deliberately hand-written rather than generated from a PDK: it
29has to stay readable, and a test that fails should point at a record somebody
30can see, not at the output of the builder it is meant to be independent of.
31"""
33from __future__ import annotations
35from typing import *
37from klayout_pex.pex25d.diagnostics import DiagnosticsReport
38from klayout_pex.pex25d.reader import ReadError, read_pex25d_text
40HEADER = """\
41PEX25D 1.0-rc1
42UNITS LENGTH um GRID 0.0001
43META technology testpdk
44META source_cell tiny
45"""
47STACK = """\
48GROUND_PLANE subs Z_OFFSETS -0.4 -0.1
50METAL met1 Z_OFFSETS 1.0 1.4
51METAL met2 Z_OFFSETS 2.0 2.4
52VIA via1 CONNECTS met1 met2
54DIELECTRIC_BACKGROUND air PERMITTIVITY 1.0
55DIELECTRIC_SIMPLE fox WRAPS subs PERMITTIVITY 3.9 BETWEEN subs met1
56DIELECTRIC_CONFORMAL lint WRAPS met1 PERMITTIVITY 7.3 THICKNESS_OVER_WRAPPED 0.1 \\
57 THICKNESS_BESIDE_WRAPPED 0.08 THICKNESS_ON_FIELD 0.0
58DIELECTRIC_SIMPLE ild WRAPS lint PERMITTIVITY 4.1 BETWEEN met1 met2
59"""
61RESISTANCE = """\
62RESISTANCE TEMPERATURE 25.0
63RESISTANCE METAL met1 SHEET 0.125
64RESISTANCE METAL met2 SHEET 0.125
65RESISTANCE VIA via1 PER_CUT 4.5
66"""
68SHAPES = """\
69CONDUCTOR A neta
70CONDUCTOR B netb
71BOX CONDUCTOR A LAYER met1 LL 0.0 0.0 UR 1.0 0.5
72BOX CONDUCTOR A LAYER via1 LL 0.2 0.1 UR 0.4 0.3
73BOX CONDUCTOR A LAYER met2 LL 0.0 0.0 UR 1.0 0.5
74POLYGON CONDUCTOR B LAYER met1 OUTER 2.0 0.0 3.0 0.0 3.0 1.0 2.0 1.0
75TERMINAL t1 CONDUCTOR A LAYER met1 KIND PIN LL 0.0 0.0 UR 0.2 0.5
76DOMAIN_MARGIN X 4.0 Y 4.0 Z 2.0
77"""
79MINIMAL = f"{HEADER}\n{STACK}\n{RESISTANCE}\n{SHAPES}"
81# Everything except the conductors, for tests that supply their own geometry.
82STACK_ONLY = f"{HEADER}\n{STACK}\n"
85def read(text: str,
86 report: Optional[DiagnosticsReport] = None,
87 **kwargs: Any) -> Any:
88 """Read PEX25D text, raising ``ReadError`` on a syntax error as usual."""
89 return read_pex25d_text(text.encode(), '<fixture>', report=report, **kwargs)
92def read_codes(text: str) -> List[str]:
93 """The diagnostic codes reading ``text`` produces, error or not."""
94 report = DiagnosticsReport()
95 try:
96 read(text, report=report)
97 except ReadError:
98 pass
99 return codes(report)
102def codes(report: DiagnosticsReport) -> List[str]:
103 return [d.code for d in report.diagnostics]
106def replacing(old: str, new: str, text: str = MINIMAL) -> str:
107 """The fixture with one line or clause substituted. Fails loudly on a typo."""
108 assert text.count(old) == 1, f"{old!r} appears {text.count(old)} times"
109 return text.replace(old, new)
112def without(line: str, text: str = MINIMAL) -> str:
113 return replacing(f"{line}\n", '', text)