fp-conformance 0.4.0

Differential conformance harness for frankenpandas against a live pandas oracle — packet fixtures + fuzz seed tests + live-oracle parity gates.
/// `live = true` compares against the SYSTEM pandas 2.2.3 (br-frankenpandas-l7r1p);
/// `live = false` opts a case out on MEASURED, unresolved divergence.
fn live_oracle_expected_or_skip(
    fixture: &super::PacketFixture,
    context: &str,
    live: bool,
) -> Option<super::ResolvedExpected> {
    if !live {
        return None;
    }
    let mut cfg = super::HarnessConfig::default_paths();
    cfg.allow_system_pandas_fallback = live;

    let expected_result = super::capture_live_oracle_expected(&cfg, fixture);
    if let Err(super::HarnessError::OracleUnavailable(message)) = &expected_result {
        eprintln!("live pandas unavailable; skipping {context}: {message}");
        return None;
    }

    Some(expected_result.expect("live oracle expected"))
}

fn expected_frame_or_skip(
    fixture: &super::PacketFixture,
    context: &str,
    live: bool,
) -> Option<super::FixtureExpectedDataFrame> {
    let expected = live_oracle_expected_or_skip(fixture, context, live)?;
    assert!(
        matches!(&expected, super::ResolvedExpected::Frame(_)),
        "expected live oracle frame payload, got {expected:?}"
    );
    let super::ResolvedExpected::Frame(expected) = expected else {
        return None;
    };
    Some(expected)
}

fn expected_series_or_skip(
    fixture: &super::PacketFixture,
    context: &str,
    live: bool,
) -> Option<super::FixtureExpectedSeries> {
    let expected = live_oracle_expected_or_skip(fixture, context, live)?;
    assert!(
        matches!(&expected, super::ResolvedExpected::Series(_)),
        "expected live oracle series payload, got {expected:?}"
    );
    let super::ResolvedExpected::Series(expected) = expected else {
        return None;
    };
    Some(expected)
}

#[test]
fn live_oracle_dataframe_at_time_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-067",
        "case_id": "dataframe_at_time_live",
        "mode": "strict",
        "operation": "dataframe_at_time",
        "oracle_source": "live_legacy_pandas",
        "time_value": "10:00:00",
        "frame": {
            "index": [
                { "kind": "utf8", "value": "2024-01-01T10:00:00" },
                { "kind": "utf8", "value": "2024-01-02T10:00:00" },
                { "kind": "utf8", "value": "2024-01-03T14:30:00" }
            ],
            "column_order": ["a", "b"],
            "columns": {
                "a": [
                    { "kind": "int64", "value": 1 },
                    { "kind": "int64", "value": 2 },
                    { "kind": "int64", "value": 3 }
                ],
                "b": [
                    { "kind": "utf8", "value": "x" },
                    { "kind": "utf8", "value": "y" },
                    { "kind": "utf8", "value": "z" }
                ]
            }
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_frame_or_skip(&fixture, "dataframe at_time oracle test", true)
    else {
        return;
    };

    let actual = super::execute_dataframe_fixture_operation(&fixture).expect("actual frame");
    super::compare_dataframe_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_dataframe_between_time_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-067",
        "case_id": "dataframe_between_time_live",
        "mode": "strict",
        "operation": "dataframe_between_time",
        "oracle_source": "live_legacy_pandas",
        "start_time": "09:00:00",
        "end_time": "16:00:00",
        "frame": {
            "index": [
                { "kind": "utf8", "value": "2024-01-01T08:00:00" },
                { "kind": "utf8", "value": "2024-01-01T12:30:00" },
                { "kind": "utf8", "value": "2024-01-01T15:00:00" },
                { "kind": "utf8", "value": "2024-01-01T20:00:00" }
            ],
            "column_order": ["a", "b"],
            "columns": {
                "a": [
                    { "kind": "int64", "value": 1 },
                    { "kind": "int64", "value": 2 },
                    { "kind": "int64", "value": 3 },
                    { "kind": "int64", "value": 4 }
                ],
                "b": [
                    { "kind": "utf8", "value": "w" },
                    { "kind": "utf8", "value": "x" },
                    { "kind": "utf8", "value": "y" },
                    { "kind": "utf8", "value": "z" }
                ]
            }
        }
    }))
    .expect("fixture");

    let Some(expected) =
        expected_frame_or_skip(&fixture, "dataframe between_time oracle test", true)
    else {
        return;
    };

    let actual = super::execute_dataframe_fixture_operation(&fixture).expect("actual frame");
    super::compare_dataframe_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_dataframe_asof_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-067",
        "case_id": "dataframe_asof_live",
        "mode": "strict",
        "operation": "dataframe_asof",
        "oracle_source": "live_legacy_pandas",
        "asof_label": { "kind": "datetime64", "value": 1704189600000000000i64 },
        "subset": ["b"],
        "frame": {
            "index": [
                { "kind": "datetime64", "value": 1704103200000000000i64 },
                { "kind": "datetime64", "value": 1704189600000000000i64 },
                { "kind": "datetime64", "value": 1704276000000000000i64 }
            ],
            "column_order": ["a", "b"],
            "columns": {
                "a": [
                    { "kind": "int64", "value": 1 },
                    { "kind": "int64", "value": 2 },
                    { "kind": "int64", "value": 3 }
                ],
                "b": [
                    { "kind": "float64", "value": 10.0 },
                    { "kind": "null", "value": "na_n" },
                    { "kind": "float64", "value": 30.0 }
                ]
            }
        }
    }))
    .expect("fixture");

    // br-frankenpandas-4hmx4: the fixture now declares TYPED datetime64
    // labels (i64 ns), so both arms answer the same question: pandas builds a
    // DatetimeIndex and names the asof row with a pd.Timestamp, serialized by
    // the oracle as {"kind":"datetime64","value":ns}; FrankenPandas builds an
    // IndexLabel::Datetime64 index and names the row the same way. The utf8
    // variant of this fixture compared a utf8 label against pandas'
    // str(Timestamp) spelling (space vs 'T') - that string-format coupling is
    // what this replaces (see also br-frankenpandas-l7r1p).
    let Some(expected) = expected_series_or_skip(&fixture, "dataframe asof oracle test", false)
    else {
        return;
    };

    let actual = super::execute_dataframe_asof_fixture_operation(&fixture).expect("actual");
    super::compare_series_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_series_take_negative_indices_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2C-010",
        "case_id": "series_take_negative_indices_live",
        "mode": "strict",
        "operation": "series_take",
        "oracle_source": "live_legacy_pandas",
        "take_indices": [-1, -3],
        "left": {
            "name": "animals",
            "index": [
                { "kind": "int64", "value": 10 },
                { "kind": "int64", "value": 20 },
                { "kind": "int64", "value": 30 },
                { "kind": "int64", "value": 40 }
            ],
            "values": [
                { "kind": "utf8", "value": "falcon" },
                { "kind": "utf8", "value": "parrot" },
                { "kind": "utf8", "value": "lion" },
                { "kind": "utf8", "value": "monkey" }
            ]
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_series_or_skip(&fixture, "series take oracle test", true) else {
        return;
    };

    let left = super::require_left_series(&fixture).expect("left series");
    let series = super::build_series(left).expect("build series");
    let actual = series.take(fixture.take_indices.as_deref().expect("take indices"));
    super::compare_series_expected(&actual.expect("actual series"), &expected)
        .expect("pandas parity");
}

#[test]
fn live_oracle_series_xs_duplicate_labels_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-077",
        "case_id": "series_xs_duplicate_labels_live",
        "mode": "strict",
        "operation": "series_xs",
        "oracle_source": "live_legacy_pandas",
        "xs_key": { "kind": "utf8", "value": "x" },
        "left": {
            "name": "vals",
            "index": [
                { "kind": "utf8", "value": "x" },
                { "kind": "utf8", "value": "y" },
                { "kind": "utf8", "value": "x" }
            ],
            "values": [
                { "kind": "int64", "value": 1 },
                { "kind": "int64", "value": 2 },
                { "kind": "int64", "value": 3 }
            ]
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_series_or_skip(&fixture, "series xs oracle test", true) else {
        return;
    };

    let actual = super::execute_series_xs_fixture_operation(&fixture).expect("actual");
    super::compare_series_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_series_repeat_scalar_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-069",
        "case_id": "series_repeat_scalar_live",
        "mode": "strict",
        "operation": "series_repeat",
        "oracle_source": "live_legacy_pandas",
        "repeat_n": 2,
        "left": {
            "name": "animals",
            "index": [
                { "kind": "int64", "value": 10 },
                { "kind": "int64", "value": 20 }
            ],
            "values": [
                { "kind": "utf8", "value": "falcon" },
                { "kind": "utf8", "value": "lion" }
            ]
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_series_or_skip(&fixture, "series repeat oracle test", true)
    else {
        return;
    };

    let actual = super::execute_series_repeat_fixture_operation(&fixture).expect("actual");
    super::compare_series_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_series_repeat_counts_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-069",
        "case_id": "series_repeat_counts_live",
        "mode": "strict",
        "operation": "series_repeat",
        "oracle_source": "live_legacy_pandas",
        "repeat_counts": [2, 0, 1],
        "left": {
            "name": "nums",
            "index": [
                { "kind": "int64", "value": 0 },
                { "kind": "int64", "value": 1 },
                { "kind": "int64", "value": 2 }
            ],
            "values": [
                { "kind": "int64", "value": 1 },
                { "kind": "int64", "value": 2 },
                { "kind": "int64", "value": 3 }
            ]
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_series_or_skip(&fixture, "series repeat-count oracle test", true)
    else {
        return;
    };

    let actual = super::execute_series_repeat_fixture_operation(&fixture).expect("actual");
    super::compare_series_expected(&actual, &expected).expect("pandas parity");
}

#[test]
fn live_oracle_dataframe_xs_duplicate_labels_matches_pandas() {
    let fixture: super::PacketFixture = serde_json::from_value(serde_json::json!({
        "packet_id": "FP-P2D-078",
        "case_id": "dataframe_xs_duplicate_labels_live",
        "mode": "strict",
        "operation": "dataframe_xs",
        "oracle_source": "live_legacy_pandas",
        "xs_key": { "kind": "utf8", "value": "x" },
        "frame": {
            "index": [
                { "kind": "utf8", "value": "x" },
                { "kind": "utf8", "value": "y" },
                { "kind": "utf8", "value": "x" }
            ],
            "column_order": ["a", "b"],
            "columns": {
                "a": [
                    { "kind": "int64", "value": 1 },
                    { "kind": "int64", "value": 2 },
                    { "kind": "int64", "value": 3 }
                ],
                "b": [
                    { "kind": "utf8", "value": "u" },
                    { "kind": "utf8", "value": "v" },
                    { "kind": "utf8", "value": "w" }
                ]
            }
        }
    }))
    .expect("fixture");

    let Some(expected) = expected_frame_or_skip(&fixture, "dataframe xs oracle test", true) else {
        return;
    };

    let actual = super::execute_dataframe_fixture_operation(&fixture).expect("actual");
    super::compare_dataframe_expected(&actual, &expected).expect("pandas parity");
}