Skip to main content
Glama
prop.rs11.7 kB
use std::collections::HashMap; use dal::{ ComponentType, DalContext, Prop, SchemaVariant, prop::PropPath, property_editor::schema::PropertyEditorSchema, schema::variant::authoring::VariantAuthoringClient, }; use dal_test::{ Result, helpers::{ ChangeSetTestHelpers, schema::variant, }, test, }; use itertools::Itertools as _; use pretty_assertions_sorted::assert_eq; use serde_json::json; #[test] async fn prop_path(ctx: &DalContext) -> Result<()> { let variant = SchemaVariant::default_for_schema_name(ctx, "starfield").await?; let name_path = PropPath::new(["root", "si", "name"]); let name_id = Prop::find_prop_id_by_path(ctx, variant.id(), &name_path).await?; let fetched_name_path = Prop::path_by_id(ctx, name_id).await?; assert_eq!(name_path, fetched_name_path); Ok(()) } #[test] async fn verify_prop_used_as_input_flag(ctx: &DalContext) -> Result<()> { let variant_id = SchemaVariant::default_id_for_schema_name(ctx, "pirate").await?; let container_props = [ vec!["root"], vec!["root", "domain"], vec!["root", "domain", "parrot_names"], vec!["root", "domain", "treasure"], ]; let item_props = [ vec!["root", "domain", "parrot_names", "parrot_name"], vec!["root", "domain", "treasure", "location"], ]; for container_prop_path in &container_props { let container_prop = Prop::get_by_id( ctx, Prop::find_prop_id_by_path(ctx, variant_id, &PropPath::new(container_prop_path)) .await?, ) .await?; assert!( container_prop.can_be_used_as_prototype_arg, "{container_prop_path:?} should be marked as able to be used as a prototype argument" ); } for item_prop_path in &item_props { let item_prop = Prop::get_by_id( ctx, Prop::find_prop_id_by_path(ctx, variant_id, &PropPath::new(item_prop_path)).await?, ) .await?; assert!( !item_prop.can_be_used_as_prototype_arg, "{item_prop_path:?} should be marked as NOT able to be used as a prototype argument" ); } Ok(()) } #[test] async fn ordered_child_props(ctx: &DalContext) -> Result<()> { let variant_id = SchemaVariant::default_id_for_schema_name(ctx, "starfield").await?; let root_prop_id = SchemaVariant::get_root_prop_id(ctx, variant_id).await?; let ordered_child_props = Prop::direct_child_props_ordered(ctx, root_prop_id).await?; let domain_prop = ordered_child_props .iter() .find(|p| p.name == "domain") .expect("could not find prop"); let ordered_child_props = Prop::direct_child_props_ordered(ctx, domain_prop.id).await?; let ordered_child_prop_names = ordered_child_props .iter() .map(|p| p.name.to_owned()) .collect_vec(); let expected_child_prop_names = [ "name", "hidden_prop", "freestar", "attributes", "possible_world_a", "possible_world_b", "universe", ]; let expected_child_prop_names = expected_child_prop_names .iter() .map(|n| n.to_string()) .collect_vec(); assert_eq!( expected_child_prop_names, // expected ordered_child_prop_names // actual ); Ok(()) } #[test] async fn prop_documentation(ctx: &mut DalContext) -> Result<()> { let name = "Toto Wolff"; let description = None; let link = None; let category = "Mercedes AMG Petronas"; let color = "#00A19B"; // Create an asset with a corresponding asset func. After that, commit. let schema_variant_id = VariantAuthoringClient::create_schema_and_variant( ctx, name, description.clone(), link.clone(), category, color, ) .await? .id(); let asset_func = r##"function main() { const asset = new AssetBuilder(); const alpha_source_prop = new PropBuilder() .setName("alpha_source_prop") .setKind("string") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(alpha_source_prop); const alpha_destination_prop = new PropBuilder() .setName("alpha_destination_prop") .setKind("string") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(alpha_destination_prop); const beta_source_prop = new PropBuilder() .setName("beta_source_prop") .setKind("string") .setDocumentation("sweet docs yo") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(beta_source_prop); const beta_destination_output_socket = new SocketDefinitionBuilder() .setName("beta_destination_output_socket") .setArity("one") .build(); asset.addOutputSocket(beta_destination_output_socket); return asset.build(); }"##; VariantAuthoringClient::save_variant_content( ctx, schema_variant_id, name, name, category, description.clone(), link.clone(), color, ComponentType::Component, Some(asset_func), ) .await?; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; // Once it's all ready, regenerate and commit. let schema_variant_id = VariantAuthoringClient::regenerate_variant(ctx, schema_variant_id).await?; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; // Assemble property editor schema and ensure Prop Documentation is there. let property_editor_schema = PropertyEditorSchema::assemble(ctx, schema_variant_id, false).await?; let prop = property_editor_schema .props .values() .find(|schema| schema.name == "beta_source_prop") .expect("could not find prop"); assert_eq!( prop.documentation.as_ref().expect("has documentation"), "sweet docs yo" ); // now let's add documentation for the other prop, regenerate, and make sure everything works let asset_func = r##"function main() { const asset = new AssetBuilder(); const alpha_source_prop = new PropBuilder() .setName("alpha_source_prop") .setKind("string") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(alpha_source_prop); const alpha_destination_prop = new PropBuilder() .setName("alpha_destination_prop") .setKind("string") .setDocumentation("more cool docs!") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(alpha_destination_prop); const beta_source_prop = new PropBuilder() .setName("beta_source_prop") .setKind("string") .setDocumentation("sweet docs yo") .setWidget(new PropWidgetDefinitionBuilder().setKind("text").build()) .build(); asset.addProp(beta_source_prop); const beta_destination_output_socket = new SocketDefinitionBuilder() .setName("beta_destination_output_socket") .setArity("one") .build(); asset.addOutputSocket(beta_destination_output_socket); return asset.build(); }"##; VariantAuthoringClient::save_variant_content( ctx, schema_variant_id, name, name, category, description, link, color, ComponentType::Component, Some(asset_func), ) .await?; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; // Once it's all ready, regenerate and commit. let schema_variant_id = VariantAuthoringClient::regenerate_variant(ctx, schema_variant_id).await?; ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx).await?; // Assemble property editor schema and ensure both Prop Documentation is there. let property_editor_schema = PropertyEditorSchema::assemble(ctx, schema_variant_id, false).await?; let first_prop = property_editor_schema .props .values() .find(|schema| schema.name == "beta_source_prop") .expect("could not find prop"); assert_eq!( first_prop .documentation .as_ref() .expect("has documentation"), "sweet docs yo" ); let second_prop = property_editor_schema .props .values() .find(|schema| schema.name == "alpha_destination_prop") .expect("could not find prop"); assert_eq!( second_prop .documentation .as_ref() .expect("has documentation"), "more cool docs!" ); Ok(()) } #[test] async fn prop_suggestions(ctx: &DalContext) -> Result<()> { let foo = variant::create( ctx, "foo", r##"function main() { return new AssetBuilder() .addProp(new PropBuilder().setName("Id").setKind("string").build()) .build(); }"##, ) .await?; assert_eq!( HashMap::new(), Prop::find_prop_by_path(ctx, foo, &PropPath::new(["root", "domain", "Id"])) .await? .ui_optionals ); let bar = variant::create( ctx, "bar", r##"function main() { return new AssetBuilder() .addProp(new PropBuilder() .setName("Id") .setKind("string") .suggestAsSourceFor({ schema: "baz", prop: "BarId" }) // Make sure you can have multiple suggestAsSourceFor .suggestAsSourceFor({ schema: "baz2", prop: "BarId2" }) .build()) .addProp(new PropBuilder() .setName("FooId") .setKind("string") .suggestSource({ schema: "foo", prop: "Id" }) // Make sure you can have multiple suggestSource .suggestSource({ schema: "foo2", prop: "Id2" }) // Make sure you can have suggestSource as well as suggestAsSourceFor on the same prop .suggestAsSourceFor({ schema: "baz", prop: "FooBarId" }) .build()) .build(); }"##, ) .await?; assert_eq!( HashMap::from([( "suggestAsSourceFor".to_string(), json!([ { "schema": "baz", "prop": "BarId" }, { "schema": "baz2", "prop": "BarId2" }, ]) .into() )]), Prop::find_prop_by_path(ctx, bar, &PropPath::new(["root", "domain", "Id"])) .await? .ui_optionals ); assert_eq!( HashMap::from([ ( "suggestSources".to_string(), json!([ { "schema": "foo", "prop": "Id" }, { "schema": "foo2", "prop": "Id2" }, ]) .into() ), ( "suggestAsSourceFor".to_string(), json!([ { "schema": "baz", "prop": "FooBarId" }, ]) .into() ), ]), Prop::find_prop_by_path(ctx, bar, &PropPath::new(["root", "domain", "FooId"])) .await? .ui_optionals ); Ok(()) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server