icydb-model 0.299.0

IcyDB application-model authoring, validation, and code generation
Documentation
use quote::quote;

use super::SqlSurfaceTokens;

fn compact_tokens(tokens: proc_macro2::TokenStream) -> String {
    tokens
        .to_string()
        .chars()
        .filter(|character| !character.is_whitespace())
        .collect()
}

#[test]
fn generated_sql_capability_contains_every_private_handler_and_no_export() {
    let mut surface = SqlSurfaceTokens::empty(quote!(::icydb));
    surface.push_entity("Character");
    let surface = compact_tokens(quote!(#surface));

    for handler in [
        "sql_query",
        "sql_ddl",
        "fixtures_reset",
        "fixtures_load",
        "sql_update_primary_key",
        "sql_update_bounded",
        "sql_integrity",
    ] {
        assert!(surface.contains(format!("__icydb_endpoint_handler_{handler}").as_str()));
    }
    for forbidden in [
        "ic_cdk::query",
        "ic_cdk::update",
        "export_name",
        "no_mangle",
    ] {
        assert!(!surface.contains(forbidden));
    }
}

#[test]
fn generated_sql_capability_keeps_both_sealed_update_admissions() {
    let mut surface = SqlSurfaceTokens::empty(quote!(::icydb));
    surface.push_entity("Character");
    let surface = compact_tokens(quote!(#surface));

    assert!(surface.contains("execute_sql_public_primary_key_update(&dispatch)"));
    assert!(surface.contains("execute_sql_public_bounded_update(&dispatch)"));
    assert!(surface.contains("__icydb_sql_surface_update_primary_key_dispatch"));
    assert!(surface.contains("__icydb_sql_surface_update_bounded_dispatch"));
}

#[test]
fn generated_sql_capability_uses_trusted_query_and_admin_ddl() {
    let mut surface = SqlSurfaceTokens::empty(quote!(::icydb));
    surface.push_entity("Character");
    let surface = compact_tokens(quote!(#surface));

    assert!(surface.contains("execute_trusted_sql_query_dispatch(&dispatch,&[])"));
    assert!(surface.contains("into_deliverable_query_reply()"));
    assert!(surface.contains("execute_admin_sql_ddl_dispatch(&dispatch)"));
}

#[test]
fn generated_sql_query_capability_keeps_introspection_gate() {
    let mut surface = SqlSurfaceTokens::empty(quote!(::icydb));
    surface.push_entity("Character");
    let surface = compact_tokens(quote!(#surface));

    assert!(surface.contains("if!INTROSPECTION&&dispatch.requires_introspection()"));
    assert!(surface.contains("SqlIntrospectionDisabled"));
}

#[test]
fn generated_fixture_load_reuses_reset_then_calls_handler_once() {
    let surface = SqlSurfaceTokens::empty(quote!(::icydb));
    let handler = compact_tokens(surface.handler_tokens());
    let reset = handler
        .find("__icydb_endpoint_handler_fixtures_reset()?")
        .expect("fixture load should propagate reset failure");
    let load = handler
        .find("handler()")
        .expect("fixture load should invoke the checked handler");

    assert!(reset < load);
    assert_eq!(handler.matches("handler()").count(), 1);
}

#[test]
fn empty_and_entity_sql_capabilities_keep_exact_dispatch_boundaries() {
    let empty_surface = SqlSurfaceTokens::empty(quote!(::icydb));
    let empty = compact_tokens(quote!(#empty_surface));
    let mut entity = SqlSurfaceTokens::empty(quote!(::icydb));
    entity.push_entity("Character");
    let entity = compact_tokens(quote!(#entity));

    assert!(empty.contains("SqlQueryNoConfiguredEntities"));
    assert!(!empty.contains("execute_trusted_sql_query_dispatch"));
    assert!(entity.contains("execute_trusted_sql_query_dispatch"));
    assert!(entity.contains("DELETEFROMCharacter"));
}