Skip to content

Commit 2ed2478

Browse files
Add DNA circuit coverage tests
Co-authored-by: quantumdynamics927-dotcom <247722560+quantumdynamics927-dotcom@users.noreply.github.com> Agent-Logs-Url: https://github.com/quantumdynamics927-dotcom/QPyth/sessions/428f0007-0052-4ed8-bde2-e3cf330ab687
1 parent 27477be commit 2ed2478

1 file changed

Lines changed: 105 additions & 0 deletions

File tree

tests/test_dna_circuits.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55

66
import pytest
77

8+
import quantumpytho.modules.dna_circuits as dna_circuits
89
from quantumpytho.modules.dna_circuits import (
910
get_available_dna_circuit_ids,
1011
get_available_dna_circuits,
1112
get_available_dna_sequences,
1213
get_dna_circuit_preview,
1314
get_dna_sequence,
1415
load_dna_circuit,
16+
load_dna_circuit_metadata,
1517
load_qasm_circuit_file,
18+
run_dna_circuit_explorer,
1619
summarize_dna_circuit,
1720
validate_qasm_file,
1821
)
@@ -43,6 +46,14 @@ def test_load_dna_circuit_parses_qasm():
4346
assert circuit.num_clbits == 21
4447

4548

49+
def test_load_dna_circuit_metadata_reads_bundled_json():
50+
"""Bundled metadata should be readable without summary normalization."""
51+
metadata = load_dna_circuit_metadata("dna_helix_10bp")
52+
53+
assert metadata["qubits"] == 21
54+
assert metadata["config"]["base_pairs"] == 10
55+
56+
4657
def test_load_stealth_dna_circuit_parses_qasm():
4758
"""Bundled 34bp stealth QASM should parse into a large Qiskit circuit."""
4859
circuit = load_dna_circuit("stealth_dna_34bp")
@@ -64,6 +75,16 @@ def test_summarize_dna_circuit_normalizes_metadata():
6475
assert summary.sequences["strand1"] == "GTAGGTAAGC"
6576

6677

78+
def test_dna_summary_to_dict_is_json_safe():
79+
"""Normalized summaries should serialize into simple Python data."""
80+
summary = summarize_dna_circuit("dna_helix_10bp")
81+
payload = summary.to_dict()
82+
83+
assert payload["circuit_id"] == "dna_helix_10bp"
84+
assert payload["sequences"] == summary.sequences
85+
assert payload["geometry"] == summary.geometry
86+
87+
6788
def test_summarize_stealth_dna_circuit_preserves_large_asset_metadata():
6889
"""Large stealth asset should preserve curated metadata and parsed metrics."""
6990
summary = summarize_dna_circuit("stealth_dna_34bp")
@@ -95,6 +116,21 @@ def test_stealth_circuit_preview_contains_named_registers():
95116
assert "qreg bridge[34];" in preview
96117

97118

119+
def test_validate_qasm_file_rejects_missing_file(tmp_path: Path):
120+
"""Missing QASM files should raise a helpful error."""
121+
with pytest.raises(FileNotFoundError, match="not found"):
122+
validate_qasm_file(tmp_path / "missing.qasm")
123+
124+
125+
def test_validate_qasm_file_rejects_invalid_header(tmp_path: Path):
126+
"""Non-OpenQASM files should be rejected before parsing."""
127+
invalid_qasm = tmp_path / "invalid.qasm"
128+
invalid_qasm.write_text("qreg q[1];", encoding="utf-8")
129+
130+
with pytest.raises(ValueError, match="not valid OpenQASM"):
131+
validate_qasm_file(invalid_qasm)
132+
133+
98134
def test_validate_qasm_file_rejects_empty_file(tmp_path: Path):
99135
"""Empty QASM placeholders should be rejected clearly."""
100136
empty_qasm = tmp_path / "empty.qasm"
@@ -113,6 +149,12 @@ def test_available_dna_sequences_contains_blueprint_and_library_entries():
113149
assert "lib_acgt" in record_ids
114150

115151

152+
def test_get_dna_sequence_unknown_record_raises_keyerror():
153+
"""Sequence lookup should fail clearly for unknown ids."""
154+
with pytest.raises(KeyError, match="Unknown DNA sequence record"):
155+
get_dna_sequence("missing-record")
156+
157+
116158
def test_get_dna_sequence_blueprint_is_normalized():
117159
"""Blueprint sequence should be normalized by stripping separators."""
118160
record = get_dna_sequence("seq_3")
@@ -122,6 +164,41 @@ def test_get_dna_sequence_blueprint_is_normalized():
122164
assert record.phi_scaling == pytest.approx(0.7232610426788172)
123165

124166

167+
def test_dna_sequence_to_dict_is_json_safe():
168+
"""Sequence records should serialize into simple Python data."""
169+
record = get_dna_sequence("seq_3")
170+
payload = record.to_dict()
171+
172+
assert payload["record_id"] == "seq_3"
173+
assert payload["sequence"] == record.sequence
174+
assert payload["metadata"] == record.metadata
175+
176+
177+
def test_load_dna_circuit_metadata_raises_for_missing_bundled_file(
178+
monkeypatch: pytest.MonkeyPatch, tmp_path: Path
179+
):
180+
"""Missing bundled metadata files should raise a clear error."""
181+
monkeypatch.setattr(dna_circuits, "_data_dir", lambda: tmp_path)
182+
183+
with pytest.raises(FileNotFoundError, match="DNA metadata file not found"):
184+
load_dna_circuit_metadata("dna_helix_10bp")
185+
186+
187+
def test_load_dna_circuit_rejects_unknown_asset():
188+
"""Unknown bundled circuit ids should fail clearly."""
189+
with pytest.raises(KeyError, match="Unknown DNA circuit asset"):
190+
load_dna_circuit("missing-circuit")
191+
192+
193+
def test_load_qasm_circuit_file_rejects_unsupported_openqasm_version(tmp_path: Path):
194+
"""Unknown OpenQASM versions should fail before import."""
195+
qasm_path = tmp_path / "sample.qasm"
196+
qasm_path.write_text("OPENQASM 4.0;\nqubit q;\n", encoding="utf-8")
197+
198+
with pytest.raises(ValueError, match="Unsupported OpenQASM version"):
199+
load_qasm_circuit_file(qasm_path)
200+
201+
125202
def test_load_qasm_circuit_file_handles_openqasm3_optional_dependency(tmp_path: Path):
126203
"""OpenQASM 3 loading should either parse or fail with an install hint."""
127204
qasm3_path = tmp_path / "sample.qasm"
@@ -136,3 +213,31 @@ def test_load_qasm_circuit_file_handles_openqasm3_optional_dependency(tmp_path:
136213
else:
137214
circuit = load_qasm_circuit_file(qasm3_path)
138215
assert circuit.num_qubits == 1
216+
217+
218+
def test_run_dna_circuit_explorer_allows_quit(
219+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
220+
):
221+
"""CLI explorer should return cleanly when the user quits."""
222+
monkeypatch.setattr("builtins.input", lambda _: "q")
223+
224+
run_dna_circuit_explorer()
225+
226+
output = capsys.readouterr().out
227+
assert "[DNA-Inspired Circuit Explorer]" in output
228+
assert "Returning to main menu..." in output
229+
230+
231+
def test_run_dna_circuit_explorer_uses_default_selection(
232+
monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]
233+
):
234+
"""Blank input should select the first bundled DNA circuit."""
235+
monkeypatch.setattr("builtins.input", lambda _: "")
236+
monkeypatch.setattr(dna_circuits.importlib.util, "find_spec", lambda _: None)
237+
238+
run_dna_circuit_explorer()
239+
240+
output = capsys.readouterr().out
241+
assert "OpenQASM 3 import support: install qiskit_qasm3_import" in output
242+
assert "Name: DNA Helix 10bp" in output
243+
assert "QASM preview:" in output

0 commit comments

Comments
 (0)