Skip to main content
Glama

Convex MCP server

Official
by get-convex
values.rs4.47 kB
use core::f64; use cmd_util::env::env_config; use common::{ assert_obj, value::ConvexValue, }; use must_let::must_let; use proptest::prelude::*; use runtime::testing::{ TestDriver, TestRuntime, }; use value::{ assert_val, proptest::{ RestrictNaNs, ValueBranching, }, ExcludeSetsAndMaps, FieldType, }; use crate::test_helpers::{ UdfTest, UdfTestType, }; #[convex_macro::test_runtime] async fn test_bigint(rt: TestRuntime) -> anyhow::Result<()> { UdfTest::run_test_with_isolate2(rt, async move |t: UdfTestType| { let value = t.query("values:intQuery", assert_obj!()).await?; must_let!(let ConvexValue::Int64(v) = value); assert_eq!(v, 1); Ok(()) }) .await } #[convex_macro::test_runtime] async fn test_empty_key(rt: TestRuntime) -> anyhow::Result<()> { UdfTest::run_test_with_isolate2(rt, async move |t: UdfTestType| { // Check that an object with an empty key round trips through mutation and // query. let id = t .mutation("values:insertObject", assert_obj!("obj" => {"" => "hi"})) .await?; let value = t.query("values:getObject", assert_obj!("id" => id)).await?; must_let!(let ConvexValue::Object(o) = value); assert_eq!(o.len(), 3); assert_eq!(o.get("").unwrap().clone(), assert_val!("hi")); Ok(()) }) .await } async fn test_compare(rt: TestRuntime, values: Vec<ConvexValue>) -> anyhow::Result<()> { let udf = UdfTest::default(rt).await?; let values = values.clone(); let mut sorted_values = values.clone(); sorted_values.sort(); let value = udf .query("values:compare", assert_obj!("values" => values)) .await?; must_let!(let ConvexValue::Array(sorted_result) = value); let sorted_result_vec = sorted_result.to_vec(); for (i, value) in sorted_result_vec.iter().enumerate() { if value != &sorted_values[i] { println!("js sort: {sorted_result_vec:?}"); println!("rust sort: {sorted_values:?}"); println!("js value at index {i:?}: {value:?}"); println!("rust value at index {:?}: {:?}", i, sorted_values[i]); } assert_eq!(value, &sorted_values[i]); } Ok(()) } #[convex_macro::test_runtime] async fn test_compare_nan_and_zero(rt: TestRuntime) -> anyhow::Result<()> { // This is the most basic test for special values like `NaN` and negative zero. let values = vec![ ConvexValue::Float64(-f64::NAN), ConvexValue::Float64(-0.0), ConvexValue::Float64(0.0), ConvexValue::Float64(1.0), ConvexValue::Float64(f64::NAN), ]; for i in 0..values.len() { for j in i + 1..values.len() { test_compare(rt.clone(), vec![values[i].clone(), values[j].clone()]).await?; } } Ok(()) } #[convex_macro::test_runtime] async fn test_compare_utf16_strings(rt: TestRuntime) -> anyhow::Result<()> { // This test case was surfaced by proptests -- JS has UTF-16 strings that get // compared differently in JS vs. Rust. let values = vec![ ConvexValue::String("𐏍ꢕ¥🕴JಏÚﶒ੫'".to_string().try_into()?), ConvexValue::String("ﹲ𓓄\\𝕆".to_string().try_into()?), ]; test_compare(rt.clone(), values).await?; Ok(()) } proptest! { #![proptest_config(ProptestConfig { cases: 32 * env_config("CONVEX_PROPTEST_MULTIPLIER", 1), failure_persistence: None, .. ProptestConfig::default() })] #[test] fn proptest_compare_values(values in prop::collection::vec(any_with::<ConvexValue>(( FieldType::User, ValueBranching::small(), ExcludeSetsAndMaps(true), RestrictNaNs(true), )), 10)) { // This tests that the JS implementation for comparing values matches the Rust implementation. // It does so by generating an array of values, and then calling a query that compares the values, // and then checking that the result is the same as the Rust implementation. // There's overhead to calling the query, so we generate a list of values instead of comparing // two values directly. // We also restrict this to only use one type of `NaN` because apparently some of them change when // put into an array. let td = TestDriver::new(); let rt = td.rt(); td.run_until(test_compare(rt, values)).unwrap(); } }

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/get-convex/convex-backend'

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