golem-schema 1.6.2

Golem schema and value model
Documentation
use super::*;
use crate::schema::graph::{SchemaGraph, SchemaTypeDef};
use crate::schema::metadata::TypeId;
use crate::schema::schema_type::{NamedFieldType, VariantCaseType};
use crate::schema::tool::{CommandTree, Doc, MonomorphicToolMiddlewareScope, ToolMiddlewareScope};
use test_r::test;

fn tool(name: &str) -> Tool {
    Tool {
        version: "1.0.0".to_string(),
        requires_filesystem: false,
        commands: CommandTree {
            nodes: vec![CommandNode {
                name: name.to_string(),
                aliases: vec![],
                doc: Doc::default(),
                globals: Globals::default(),
                subcommands: vec![],
                body: None,
            }],
        },
        schema: SchemaGraph::empty(),
    }
}

#[test]
fn rejects_malformed_middleware_identity_and_both_embedded_tools() {
    let middleware = ToolMiddleware {
        name: "Bad_Name".to_string(),
        version: "middleware-v3".to_string(),
        aliases: vec!["Bad_Name".to_string()],
        doc: Doc::default(),
        scope: ToolMiddlewareScope::Monomorphic(Box::new(MonomorphicToolMiddlewareScope {
            presented: tool("BadPresented"),
            expected: Some(tool("BadExpected")),
        })),
        parameter_schema: SchemaGraph::empty(),
    };

    let errors = validate_tool_middleware(&middleware).unwrap_err();
    assert!(errors.iter().any(|e| matches!(
        e,
        ToolMiddlewareValidationError::InvalidIdentifier {
            kind: "tool middleware name",
            ..
        }
    )));
    assert!(
        errors
            .iter()
            .any(|e| matches!(e, ToolMiddlewareValidationError::DuplicateIdentity { .. }))
    );
    assert!(
        errors
            .iter()
            .any(|e| matches!(e, ToolMiddlewareValidationError::InvalidPresentedTool(_)))
    );
    assert!(
        errors
            .iter()
            .any(|e| matches!(e, ToolMiddlewareValidationError::InvalidExpectedTool(_)))
    );
}

#[test]
fn rejects_empty_tool_and_middleware_versions() {
    let mut invalid_tool = tool("valid");
    invalid_tool.version.clear();
    assert!(
        validate_tool(&invalid_tool)
            .unwrap_err()
            .contains(&ToolValidationError::EmptyVersion)
    );
    let middleware = ToolMiddleware {
        name: "valid".into(),
        version: " ".into(),
        aliases: vec![],
        doc: Doc::default(),
        scope: ToolMiddlewareScope::Universal,
        parameter_schema: SchemaGraph::empty(),
    };
    assert_eq!(
        validate_tool_middleware(&middleware).unwrap_err(),
        vec![ToolMiddlewareValidationError::EmptyVersion]
    );
}

fn universal_middleware(parameter_schema: SchemaGraph) -> ToolMiddleware {
    ToolMiddleware {
        name: "valid".into(),
        version: "1".into(),
        aliases: vec![],
        doc: Doc::default(),
        scope: ToolMiddlewareScope::Universal,
        parameter_schema,
    }
}

#[test]
fn accepts_static_record_and_variant_parameter_schema() {
    let schema = SchemaGraph::anonymous(SchemaType::Record {
        fields: vec![NamedFieldType {
            name: "mode".into(),
            body: SchemaType::Variant {
                cases: vec![VariantCaseType {
                    name: "named".into(),
                    payload: Some(SchemaType::string()),
                    metadata: Default::default(),
                }],
                metadata: Default::default(),
            },
            metadata: Default::default(),
        }],
        metadata: Default::default(),
    });
    assert!(validate_tool_middleware(&universal_middleware(schema)).is_ok());
}

#[test]
fn rejects_nested_and_definition_host_or_async_parameter_types() {
    let schema = SchemaGraph {
        defs: vec![SchemaTypeDef {
            id: TypeId::new("capability"),
            name: None,
            body: SchemaType::permission_card(Default::default()),
        }],
        root: SchemaType::tuple(vec![
            SchemaType::list(SchemaType::stream(Some(SchemaType::string()))),
            SchemaType::ref_to(TypeId::new("capability")),
        ]),
    };
    let errors = validate_tool_middleware(&universal_middleware(schema)).unwrap_err();
    assert!(
        errors.contains(&ToolMiddlewareValidationError::ForbiddenParameterType(
            "stream"
        ))
    );
    assert!(
        errors.contains(&ToolMiddlewareValidationError::ForbiddenParameterType(
            "permission-card"
        ))
    );
}

#[test]
fn rejects_malformed_parameter_graph() {
    let schema = SchemaGraph::anonymous(SchemaType::ref_to(TypeId::new("missing")));
    assert!(
        validate_tool_middleware(&universal_middleware(schema))
            .unwrap_err()
            .iter()
            .any(|error| matches!(
                error,
                ToolMiddlewareValidationError::InvalidParameterSchema(_)
            ))
    );
}