use everett::Circuit;
fn parse_ok(src: &str) -> Circuit {
Circuit::from_qasm(src).unwrap_or_else(|e| panic!("expected parse to succeed: {e}\n{src}"))
}
#[test]
fn bell() {
let c = parse_ok(
r#"OPENQASM 3.0;
include "stdgates.inc";
qubit[2] q;
bit[2] c;
h q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
"#,
);
assert_eq!(c.num_qubits(), 2);
assert_eq!(c.num_classical(), 2);
assert_eq!(c.len(), 4);
}
#[test]
fn rotations_with_pi_expressions() {
let c = parse_ok(
r#"OPENQASM 3.0;
include "stdgates.inc";
qubit[1] q;
rx(pi/2) q[0];
ry(-pi/4) q[0];
rz(2*pi) q[0];
p(pi) q[0];
"#,
);
assert_eq!(c.len(), 4);
}
#[test]
fn arrow_and_assignment_measure_forms() {
let arrow = parse_ok("OPENQASM 3.0;\nqubit[1] q;\nbit[1] c;\nmeasure q[0] -> c[0];\n");
let assign = parse_ok("OPENQASM 3.0;\nqubit[1] q;\nbit[1] c;\nc[0] = measure q[0];\n");
assert_eq!(arrow.len(), 1);
assert_eq!(assign.len(), 1);
}
#[test]
fn ctrl_modifier_and_multi_control() {
let c = parse_ok(
r#"OPENQASM 3.0;
include "stdgates.inc";
qubit[3] q;
ctrl @ x q[0], q[1];
ctrl(2) @ x q[0], q[1], q[2];
"#,
);
assert_eq!(c.len(), 2);
}
#[test]
fn gate_definitions_are_skipped() {
let c = parse_ok(
r#"OPENQASM 3.0;
include "stdgates.inc";
gate mygate q { h q; }
qubit[1] q;
h q[0];
"#,
);
assert_eq!(c.len(), 1);
}
#[test]
fn classical_control_if() {
let c = parse_ok(
r#"OPENQASM 3.0;
include "stdgates.inc";
qubit[1] q;
bit[1] c;
c[0] = measure q[0];
if (c[0] == 1) x q[0];
"#,
);
assert_eq!(c.len(), 2);
}
#[test]
fn line_and_block_comments() {
let c = parse_ok(
r#"OPENQASM 3.0;
// a line comment
include "stdgates.inc";
qubit[1] q; /* trailing block comment */
/* multi
line
comment */
h q[0];
"#,
);
assert_eq!(c.len(), 1);
}
#[test]
fn version_line_is_optional() {
let c = parse_ok("qubit[1] q;\nh q[0];\n");
assert_eq!(c.len(), 1);
}
#[test]
fn alternate_register_names_accepted() {
let c = parse_ok(
r"OPENQASM 3.0;
qubit[2] qreg;
bit[2] creg;
h qreg[0];
cx qreg[0], qreg[1];
creg[0] = measure qreg[0];
",
);
assert_eq!(c.num_qubits(), 2);
assert_eq!(c.len(), 3);
}