vize_l2 0.580.0

L2 - the Davinci semantic IR (codename Disegno): the neutral op family every input dialect lowers into
Documentation
#![expect(
    clippy::panic_in_result_fn,
    reason = "complete native differential assertions"
)]

use super::{Allocator, Law, producer};
use crate::{lang::js::JsxMarkupIssueKind, op::Op, walk::NodeRef};
use alloc::vec::Vec;
use serde_json::{Value, json};

pub(super) fn dom(ops: &[Op<'_>]) -> Result<Value, &'static str> {
    let mut nodes = Vec::new();
    for op in ops {
        nodes.push(match op {
            Op::Element(element) => {
                assert_eq!(element.bindings.len(), 0);
                assert_eq!(element.namespace, crate::op::Namespace::Html);
                let attributes: Vec<_> = element.attributes.iter().map(|a| json!([a.name, a.value.unwrap_or("")])).collect();
                json!({"kind":"element", "tag":element.tag, "namespace":"http://www.w3.org/1999/xhtml", "attributes":attributes, "children":dom(&element.children.ops)?})
            }
            Op::Text(text) => json!({"kind":"text", "value":text.content}),
            _ => return Err("non-static op"),
        });
    }
    Ok(Value::Array(nodes))
}

#[test]
fn original_canonical_nodes_match_complete_pinned_mounted_dom_and_independent_source_spans() -> Law
{
    let oracle: Value = serde_json::from_str(include_str!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/fixtures/jsx-formatting-whitespace/oracle.json"
    )))
    .map_err(|_| "oracle json")?;
    let inputs: Value = serde_json::from_str(include_str!(concat!(
        env!("CARGO_MANIFEST_DIR"),
        "/tests/fixtures/jsx-formatting-whitespace/cases.json"
    )))
    .map_err(|_| "input json")?;
    let cases = inputs
        .get("cases")
        .and_then(Value::as_array)
        .ok_or("inputs")?;
    let outputs = oracle
        .get("cases")
        .and_then(Value::as_array)
        .ok_or("outputs")?;
    assert_eq!(cases.len(), 15);
    assert_eq!(outputs.len(), cases.len());
    for typescript in [false, true] {
        for (input, output) in cases.iter().zip(outputs) {
            assert_eq!(input.get("id"), output.get("id"));
            let source = input
                .get("source")
                .and_then(Value::as_str)
                .ok_or("source")?;
            let arena = Allocator::default();
            let result = producer(&arena, source, typescript)?.finish_markup();
            if input.get("admit").and_then(Value::as_bool) == Some(false) {
                let rejected = match result {
                    Err(rejected) => rejected,
                    Ok(_) => return Err("unsupported normalized text admitted"),
                };
                assert_eq!(
                    rejected
                        .issues()
                        .iter()
                        .map(|issue| issue.kind)
                        .collect::<Vec<_>>(),
                    [JsxMarkupIssueKind::ValueNormalization]
                );
                assert_eq!(Value::Array(rejected.issues().iter().map(|issue| json!({"kind":"value-normalization","start":issue.span.start,"end":issue.span.end})).collect()), *output.get("refusal").ok_or("whole refusal packet")?);
                assert_eq!(
                    rejected
                        .owner()
                        .ok_or("retained refused owner")?
                        .file()
                        .artifact()
                        .node_count(),
                    0
                );
                continue;
            }
            let native = result.map_err(|_| "formatted static markup rejected")?;
            let artifact = native.file().artifact();
            assert_eq!(
                dom(&artifact.root().ops)?,
                *output.get("dom").ok_or("complete DOM")?
            );
            let mut spans = Vec::new();
            artifact
                .visit_nodes(&mut |_, node| {
                    let kind = match node {
                        NodeRef::Op(Op::Element(_)) => "element",
                        NodeRef::Op(Op::Text(_)) => "text",
                        _ => "unexpected",
                    };
                    let span = node.span();
                    spans.push(json!({"kind":kind,"start":span.start,"end":span.end}));
                })
                .map_err(|_| "node accounting")?;
            assert_eq!(
                Value::Array(spans),
                *output
                    .get("sourceOps")
                    .ok_or("independent original spans")?
            );
            assert_eq!(
                artifact.node_count() as usize,
                output
                    .get("sourceOps")
                    .and_then(Value::as_array)
                    .ok_or("node count")?
                    .len()
            );
            assert!(core::ptr::eq(artifact.source(), source));
        }
    }
    Ok(())
}