Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/facett

facett-arrow/tests/matrix.rs

//! **The functional matrix cell for facett-arrow** — the crate emitted NO
//! testmatrix row of either aspect (see
//! `.nornir/docs/test-matrix-inventory-history.md`).
//!
//! `facett-arrow` is an ADAPTER, not a pane: its contract is "an Arrow
//! `RecordBatch` becomes something facett can actually DRAW". So the oracle is
//! not a count — it is the adapter's output driven through the real render probe.
//! The batch is converted, handed to the pane that consumes it, and
//! `facett_core::testmatrix::probe_and_emit` proves the pane tessellates real
//! vertices from Arrow-derived data. ONE call per lane, shared probe (L5).

use std::sync::Arc;

use arrow_array::{Int64Array, RecordBatch, StringArray};
use arrow_schema::{DataType, Field, Schema};

use facett_arrow::{scene_from_edge_batch, table_from_batch};

/// A four-edge social batch with labels on both endpoints (so node colouring by
/// label is exercised) — the shared fixture for both lanes below.
fn edge_batch() -> RecordBatch {
    RecordBatch::try_new(
        Arc::new(Schema::new(vec![
            Field::new("src", DataType::Int64, false),
            Field::new("dst", DataType::Int64, false),
            Field::new("src_label", DataType::Utf8, false),
            Field::new("dst_label", DataType::Utf8, false),
        ])),
        vec![
            Arc::new(Int64Array::from(vec![1, 1, 2, 3])),
            Arc::new(Int64Array::from(vec![2, 3, 4, 4])),
            Arc::new(StringArray::from(vec!["Person", "Person", "Company", "Address"])),
            Arc::new(StringArray::from(vec!["Company", "Address", "Bank", "Bank"])),
        ],
    )
    .unwrap()
}

#[test]
fn arrow_edges_become_a_graph_that_actually_draws() {
    let scene = scene_from_edge_batch(&edge_batch()).expect("the batch converts");
    assert_eq!(scene.nodes.len(), 4, "ids 1..4 are distinct nodes");
    assert_eq!(scene.edges.len(), 4);

    let mut view = facett_graph::GraphView::new(scene);
    let probe = facett_core::testmatrix::probe_and_emit("facett-arrow.scene", &mut view, &[]);

    assert!(probe.drew(), "an Arrow-derived scene must tessellate to vertices");
    assert_eq!(probe.initial_state["nodes"], 4, "the pane sees every Arrow node");
    assert_eq!(probe.initial_state["edges"], 4, "the pane sees every Arrow edge");
}

#[test]
fn arrow_columns_become_a_table_that_actually_draws() {
    let batch = RecordBatch::try_new(
        Arc::new(Schema::new(vec![
            Field::new("id", DataType::Int64, false),
            Field::new("name", DataType::Utf8, false),
        ])),
        vec![
            Arc::new(Int64Array::from(vec![1, 2, 3])),
            Arc::new(StringArray::from(vec!["knut", "korp", "nornir"])),
        ],
    )
    .unwrap();

    let mut view = table_from_batch(&batch, "repos");
    let probe = facett_core::testmatrix::probe_and_emit("facett-arrow.table", &mut view, &[]);

    assert!(probe.drew(), "an Arrow-derived table must tessellate to vertices");
    assert_eq!(probe.initial_state["rows"], 3);
    let cols: Vec<&str> =
        probe.initial_state["columns"].as_array().unwrap().iter().map(|c| c.as_str().unwrap()).collect();
    assert_eq!(cols, ["id", "name"]);
}

/// RED-when-broken: the error path had only an `is_err()` oracle with no message
/// contract. Pin WHICH column is reported missing — a converter that blames the
/// wrong column sends a host hunting the wrong schema field.
#[test]
fn a_batch_without_the_edge_columns_names_the_missing_one() {
    let batch = RecordBatch::try_new(
        Arc::new(Schema::new(vec![Field::new("x", DataType::Int64, false)])),
        vec![Arc::new(Int64Array::from(vec![1]))],
    )
    .unwrap();
    let Err(err) = scene_from_edge_batch(&batch) else { panic!("a schema without src/dst must be rejected") };
    assert!(err.contains("src") || err.contains("dst"), "the error must name the column: {err}");

    // A batch with `src` but no `dst` is equally rejected (not half-converted).
    let half = RecordBatch::try_new(
        Arc::new(Schema::new(vec![Field::new("src", DataType::Int64, false)])),
        vec![Arc::new(Int64Array::from(vec![1]))],
    )
    .unwrap();
    assert!(scene_from_edge_batch(&half).is_err(), "a half schema must not half-convert");
}