Add tiered .asc parser with companion netlist resolution
Implement three-tier resolution for LTspice .asc schematic files: 1. Companion netlist - finds .net/.cir/.sp beside the .asc (automatic) 2. LTspice generation - invokes LTspice binary (opt-in via --generate-netlist) 3. Metadata-only fallback - extracts component refs/values without connectivity Safety: DataCompleteness enum forces callers to check completeness. CLI blocks diagram generation on METADATA_ONLY with clear remediation. Metadata enrichment is additive-only with protected field guards. Also: update project URLs to Gitea, add .asc usage docs to README, fix pre-existing ruff warning in test_single_module.py.
This commit is contained in:
parent
ad03798b4d
commit
08c92bfefb
9 changed files with 833 additions and 61 deletions
|
|
@ -128,3 +128,75 @@ class TestCLIFiltering:
|
|||
)
|
||||
assert result.exit_code == 0
|
||||
assert "X1:" not in result.output
|
||||
|
||||
|
||||
class TestCLIAscInput:
|
||||
"""Tests for .asc file input through the CLI."""
|
||||
|
||||
def test_asc_with_companion_works(self):
|
||||
"""simple_board.asc has companion .net — full pipeline should work."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
[str(FIXTURES / "simple_board.asc"), "-s", "amplifier_board"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "connectors:" in result.output
|
||||
assert "amplifier_board" in result.output
|
||||
|
||||
def test_asc_companion_resolution_in_stderr(self):
|
||||
"""CLI should report which .net was resolved to stderr."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
[str(FIXTURES / "simple_board.asc"), "-s", "amplifier_board"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "simple_board.net" in result.stderr
|
||||
|
||||
def test_asc_without_companion_errors(self):
|
||||
"""standalone.asc has no companion .net — diagram generation should fail."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, [str(FIXTURES / "standalone.asc")])
|
||||
assert result.exit_code != 0
|
||||
assert "connectivity" in result.output.lower() or "connectivity" in (
|
||||
getattr(result, "stderr", "") or ""
|
||||
).lower()
|
||||
|
||||
def test_asc_without_companion_shows_remediation(self):
|
||||
"""Error message should tell the user how to fix it."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(main, [str(FIXTURES / "standalone.asc")])
|
||||
assert result.exit_code != 0
|
||||
stderr = result.stderr
|
||||
assert "--generate-netlist" in stderr or "--list-components" in stderr
|
||||
|
||||
def test_asc_list_components_on_metadata_only(self):
|
||||
"""--list-components should work even without connectivity."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
[str(FIXTURES / "standalone.asc"), "--list-components"],
|
||||
)
|
||||
# Should succeed (exit 0) — inspection doesn't need connectivity
|
||||
assert result.exit_code == 0
|
||||
|
||||
def test_asc_list_subcircuits_with_companion(self):
|
||||
"""--list-subcircuits through .asc with companion works."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
[str(FIXTURES / "simple_board.asc"), "--list-subcircuits"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "amplifier_board" in result.output
|
||||
|
||||
def test_asc_dry_run_with_companion(self):
|
||||
"""--dry-run through .asc with companion produces summary."""
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(
|
||||
main,
|
||||
[str(FIXTURES / "simple_board.asc"), "-s", "amplifier_board", "--dry-run"],
|
||||
)
|
||||
assert result.exit_code == 0
|
||||
assert "Mode: single" in result.output
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue