qec-code 0.3.0

Rust primitives for constructing and analyzing quantum error-correcting codes
Documentation
#[cfg(feature = "cli")]
use std::process::{Command, Output};

use qec_code::family_verifier::verify_family_manifest_text;

const MANIFEST_TEXT: &str = include_str!("fixtures/family_manifest/manifest.v1.json");

#[cfg(feature = "cli")]
fn qec_code_bin() -> &'static str {
    env!("CARGO_BIN_EXE_qec-code")
}

#[cfg(feature = "cli")]
fn run_qec_code(args: &[&str]) -> Output {
    Command::new(qec_code_bin())
        .args(args)
        .output()
        .expect("qec-code binary should run")
}

#[cfg(feature = "cli")]
fn line_count(stdout: &str, prefix: &str) -> usize {
    stdout
        .lines()
        .filter(|line| line.starts_with(prefix))
        .count()
}

#[cfg(feature = "cli")]
fn family_ids(stdout: &str) -> Vec<&str> {
    stdout
        .lines()
        .filter(|line| {
            line.starts_with("PASS ") || line.starts_with("DEFERRED ") || line.starts_with("FAIL ")
        })
        .map(|line| line.split_whitespace().nth(1).unwrap())
        .collect()
}

fn mutate_generalized_bicycle(mutate: impl FnOnce(&mut serde_json::Value)) -> String {
    mutate_family("generalized_bicycle", mutate)
}

fn mutate_family(family_id: &str, mutate: impl FnOnce(&mut serde_json::Value)) -> String {
    let mut value: serde_json::Value = serde_json::from_str(MANIFEST_TEXT).unwrap();
    let family = value["families"]
        .as_array_mut()
        .unwrap()
        .iter_mut()
        .find(|entry| entry["family_id"] == family_id)
        .unwrap();
    mutate(family);
    format!("{}\n", serde_json::to_string_pretty(&value).unwrap())
}

fn mutate_manifest(mutate: impl FnOnce(&mut serde_json::Value)) -> String {
    let mut value: serde_json::Value = serde_json::from_str(MANIFEST_TEXT).unwrap();
    mutate(&mut value);
    format!("{}\n", serde_json::to_string_pretty(&value).unwrap())
}

#[test]
#[cfg(feature = "cli")]
fn verify_families_cli_reports_12_pass_and_2_deferred() {
    let output = run_qec_code(&["code", "css", "verify-families"]);

    assert!(output.status.success());
    assert_eq!(output.stderr, b"");

    let stdout = String::from_utf8(output.stdout).unwrap();
    assert_eq!(line_count(&stdout, "PASS "), 12);
    assert_eq!(line_count(&stdout, "DEFERRED "), 2);
    assert_eq!(line_count(&stdout, "FAIL "), 0);
    assert!(stdout.ends_with("SUMMARY PASS supported=12 deferred=2 failed=0\n"));
    assert_eq!(
        family_ids(&stdout),
        vec![
            "directional",
            "quantum_tanner",
            "generalized_bicycle",
            "la_cross",
            "random_hgp",
            "lifted_product",
            "hyperbolic_5_5",
            "coprime_bb",
            "toric_3d",
            "color_666",
            "surface",
            "shor_like",
            "random_two_block",
            "perturbed_hgp",
        ]
    );

    for line in stdout.lines().filter(|line| line.starts_with("PASS ")) {
        for required in [
            " params=",
            " n=",
            " checks=h_x:",
            " ranks=rank_x:",
            " k=",
            " row_weights=h_x:",
            " orthogonal=true",
            " provenance=",
        ] {
            assert!(line.contains(required), "line missing {required:?}: {line}");
        }
    }
    assert!(stdout.contains(
        "DEFERRED hyperbolic_5_5 tracking_issue=#571 contract=qec-code/doc/hyperbolic_5_5_contract.md"
    ));
    assert!(stdout.contains(
        "DEFERRED perturbed_hgp tracking_issue=#572 contract=qec-code/doc/perturbed_hgp_contract.md"
    ));
}

#[test]
fn verify_families_cli_fails_on_mutated_rank() {
    let text = mutate_generalized_bicycle(|family| {
        family["expected"]["rank_x"] = serde_json::json!(5);
    });

    let report = verify_family_manifest_text(&text);

    assert_eq!(report.failed, 1);
    assert!(
        report
            .output
            .contains("FAIL generalized_bicycle expected rank_x=5 actual rank_x=4")
    );
    assert!(
        report
            .output
            .ends_with("SUMMARY FAIL supported=12 deferred=2 failed=1")
    );
}

#[test]
fn verify_families_cli_fails_when_supported_target_is_planned() {
    let text = mutate_generalized_bicycle(|family| {
        family["availability"] = serde_json::json!("planned");
    });

    let report = verify_family_manifest_text(&text);

    assert_eq!(report.failed, 1);
    assert!(report.output.contains(
        "FAIL generalized_bicycle disposition=supported availability=planned expected=available"
    ));
    assert!(
        report
            .output
            .ends_with("SUMMARY FAIL supported=12 deferred=2 failed=1")
    );
}

#[test]
fn verify_families_cli_fails_when_deferred_family_is_missing() {
    let mut value: serde_json::Value = serde_json::from_str(MANIFEST_TEXT).unwrap();
    value["families"]
        .as_array_mut()
        .unwrap()
        .retain(|entry| entry["family_id"] != "perturbed_hgp");
    let text = format!("{}\n", serde_json::to_string_pretty(&value).unwrap());

    let report = verify_family_manifest_text(&text);

    assert!(report.failed > 0);
    assert!(
        report
            .output
            .contains("FAIL manifest missing family_id=perturbed_hgp")
    );
    assert!(
        report
            .output
            .contains("SUMMARY FAIL supported=12 deferred=1")
    );
}

#[test]
fn verify_families_cli_fails_when_family_is_duplicated() {
    let mut value: serde_json::Value = serde_json::from_str(MANIFEST_TEXT).unwrap();
    let duplicate = value["families"]
        .as_array()
        .unwrap()
        .iter()
        .find(|entry| entry["family_id"] == "directional")
        .unwrap()
        .clone();
    value["families"].as_array_mut().unwrap().push(duplicate);
    let text = format!("{}\n", serde_json::to_string_pretty(&value).unwrap());

    let report = verify_family_manifest_text(&text);

    assert!(report.failed > 0);
    assert!(
        report
            .output
            .contains("FAIL manifest duplicate family_id=directional")
    );
    assert!(
        report
            .output
            .contains("SUMMARY FAIL supported=13 deferred=2")
    );
}

#[test]
fn verify_families_cli_fails_on_mutated_deferred_contract() {
    let text = mutate_family("hyperbolic_5_5", |family| {
        family["research_contracts"] =
            serde_json::json!(["qec-code/doc/wrong_hyperbolic_contract.md"]);
    });

    let report = verify_family_manifest_text(&text);

    assert_eq!(report.failed, 1);
    assert!(report.output.contains(
        "FAIL hyperbolic_5_5 expected contract=qec-code/doc/hyperbolic_5_5_contract.md actual contract=qec-code/doc/wrong_hyperbolic_contract.md"
    ));
    assert!(
        report
            .output
            .ends_with("SUMMARY FAIL supported=12 deferred=2 failed=1")
    );
}

#[test]
fn verify_families_cli_reports_catalog_and_metadata_failure_boundaries() {
    let cases = [
        (
            "invalid JSON",
            "{".to_owned(),
            "FAIL manifest invalid_json=",
        ),
        (
            "unexpected deferred family",
            mutate_manifest(|manifest| {
                let mut unknown = manifest["families"]
                    .as_array()
                    .unwrap()
                    .iter()
                    .find(|entry| entry["family_id"] == "hyperbolic_5_5")
                    .unwrap()
                    .clone();
                unknown["family_id"] = serde_json::json!("unknown_deferred");
                unknown["research_contracts"] =
                    serde_json::json!(["qec-code/doc/unknown_deferred_contract.md"]);
                manifest["families"].as_array_mut().unwrap().push(unknown);
            }),
            "FAIL unknown_deferred unknown deferred family",
        ),
        (
            "supported not_applicable availability",
            mutate_generalized_bicycle(|family| {
                family["availability"] = serde_json::json!("not_applicable");
            }),
            "FAIL generalized_bicycle disposition=supported availability=not_applicable expected=available",
        ),
        (
            "missing positive success case",
            mutate_generalized_bicycle(|family| {
                family["executable_cases"] = serde_json::json!([]);
            }),
            "FAIL generalized_bicycle missing positive success case",
        ),
        (
            "positive success case missing request",
            mutate_generalized_bicycle(|family| {
                family["executable_cases"][0]["request"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle positive success case missing request",
        ),
        (
            "construction rejection",
            mutate_generalized_bicycle(|family| {
                family["executable_cases"][0]["request"]["order"] = serde_json::json!(0);
            }),
            "FAIL generalized_bicycle construction=invalid CSS construction generalized_bicycle: order must be nonzero",
        ),
        (
            "requested family id mismatch",
            mutate_generalized_bicycle(|family| {
                family["family_id"] = serde_json::json!("generalized_bicycle_alias");
            }),
            "FAIL generalized_bicycle_alias expected requested_family_id=generalized_bicycle_alias actual requested_family_id=generalized_bicycle",
        ),
        (
            "missing callable constructor",
            mutate_generalized_bicycle(|family| {
                family["callable_constructor"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle missing callable_constructor",
        ),
        (
            "provenance mismatch",
            mutate_generalized_bicycle(|family| {
                family["callable_constructor"]["rust_path"] = serde_json::json!("Wrong::Path");
            }),
            "FAIL generalized_bicycle expected provenance=Wrong::Path actual provenance=CssFamilySpec::GeneralizedBicycle",
        ),
        (
            "missing expected stats",
            mutate_generalized_bicycle(|family| {
                family["expected"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle missing expected stats",
        ),
        (
            "missing row weight summary",
            mutate_generalized_bicycle(|family| {
                family["row_weight_summary"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle missing row_weight_summary",
        ),
        (
            "h_x row weight mismatch",
            mutate_generalized_bicycle(|family| {
                family["row_weight_summary"]["h_x"][0]["count"] = serde_json::json!(6);
            }),
            "FAIL generalized_bicycle expected row_weights_h_x=[w4=6] actual row_weights_h_x=[w4=5]",
        ),
        (
            "h_z row weight mismatch",
            mutate_generalized_bicycle(|family| {
                family["row_weight_summary"]["h_z"][0]["count"] = serde_json::json!(6);
            }),
            "FAIL generalized_bicycle expected row_weights_h_z=[w4=6] actual row_weights_h_z=[w4=5]",
        ),
        (
            "d_x mismatch",
            mutate_generalized_bicycle(|family| {
                family["expected"]["d_x"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle expected d_x=None actual d_x=Some(3)",
        ),
        (
            "d_z mismatch",
            mutate_generalized_bicycle(|family| {
                family["expected"]["d_z"] = serde_json::Value::Null;
            }),
            "FAIL generalized_bicycle expected d_z=None actual d_z=Some(3)",
        ),
        (
            "deferred available availability",
            mutate_family("hyperbolic_5_5", |family| {
                family["availability"] = serde_json::json!("available");
            }),
            "FAIL hyperbolic_5_5 disposition=deferred availability=available expected=not_applicable",
        ),
        (
            "missing deferred research contract",
            mutate_family("hyperbolic_5_5", |family| {
                family["research_contracts"] = serde_json::json!([]);
            }),
            "FAIL hyperbolic_5_5 expected exactly one research_contract",
        ),
    ];

    for (label, text, expected) in cases {
        let report = verify_family_manifest_text(&text);

        assert!(report.failed > 0, "{label} should fail verification");
        assert!(
            report.output.contains(expected),
            "{label} missing {expected:?} in report:\n{}",
            report.output
        );
    }
}