use super::common;
use common::test_scenario::TestScenario;
use linkrs_core::Value;
#[test]
fn test_type_alias_basic_builtin() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE my_int AS INT")
.assert_success()
.exec_ddl("CREATE TYPE my_float AS FLOAT")
.assert_success()
.exec_ddl("CREATE TAG Person(id INT, name STRING, age my_int, score my_float)")
.assert_success()
.query("DESC TAG Person")
.assert_result_contains(vec![Value::string("age"), Value::string("INT")])
.assert_result_contains(vec![Value::string("score"), Value::string("FLOAT")]);
}
#[test]
fn test_type_alias_chain_resolution() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS INT")
.assert_success()
.exec_ddl("CREATE TYPE b AS a")
.assert_success()
.exec_ddl("CREATE TYPE c AS b")
.assert_success()
.exec_ddl("CREATE TAG Data(id INT, val c)")
.assert_success()
.query("DESC TAG Data")
.assert_result_contains(vec![Value::string("val"), Value::string("INT")]);
}
#[test]
fn test_type_alias_cast_works() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE my_float AS FLOAT")
.assert_success()
.query("RETURN 42::my_float")
.assert_result_contains(vec![Value::Float(42.0)]);
}
#[test]
fn test_type_alias_direct_cycle_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS a");
let error = scenario.error().expect("Direct cycle should be rejected");
assert!(error.contains("Cyclic"), "error: {error}");
}
#[test]
fn test_type_alias_indirect_cycle_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS b")
.assert_success()
.exec_ddl("CREATE TYPE b AS a");
let error = scenario.error().expect("Indirect cycle should be rejected");
assert!(error.contains("Cyclic"), "error: {error}");
}
#[test]
fn test_type_alias_three_link_cycle_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS c")
.assert_success()
.exec_ddl("CREATE TYPE b AS a")
.assert_success()
.exec_ddl("CREATE TYPE c AS b");
let error = scenario.error().expect("Long cycle should be rejected");
assert!(
error.contains("Cyclic") || error.contains("already exists"),
"error: {error}"
);
}
#[test]
fn test_type_alias_no_cycle_succeeds() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS INT")
.assert_success()
.exec_ddl("CREATE TYPE b AS FLOAT")
.assert_success()
.exec_ddl("CREATE TYPE c AS STRING")
.assert_success();
}
#[test]
fn test_drop_alias_referenced_by_other_rejected() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE base AS INT")
.assert_success()
.exec_ddl("CREATE TYPE derived AS base")
.assert_success()
.exec_ddl("DROP TYPE base");
let error = scenario
.error()
.expect("DROP on referenced alias should fail");
assert!(
error.contains("still referenced") || error.contains("dependency"),
"error: {error}"
);
}
#[test]
fn test_drop_leaf_alias_succeeds() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE a AS INT")
.assert_success()
.exec_ddl("CREATE TYPE b AS INT")
.assert_success()
.exec_ddl("DROP TYPE b")
.assert_success();
}
#[test]
fn test_drop_after_dependency_removed() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE base AS INT")
.assert_success()
.exec_ddl("CREATE TYPE derived AS base")
.assert_success()
.exec_ddl("DROP TYPE derived")
.assert_success()
.exec_ddl("DROP TYPE base")
.assert_success();
}
#[test]
fn test_drop_nonexistent_if_exists_ok() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("DROP TYPE IF EXISTS does_not_exist")
.assert_success();
}
#[test]
fn test_duplicate_create_fails() {
let scenario = TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE foo AS INT")
.assert_success()
.exec_ddl("CREATE TYPE foo AS FLOAT");
let error = scenario.error().expect("Duplicate creation should fail");
assert!(error.contains("already exists"), "error: {error}");
}
#[test]
fn test_duplicate_if_not_exists_ok() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE foo AS INT")
.assert_success()
.exec_ddl("CREATE TYPE IF NOT EXISTS foo AS FLOAT")
.assert_success();
}
#[test]
fn test_type_alias_insert_select_works() {
TestScenario::new()
.expect("Failed to create test scenario")
.setup_space("test_space")
.exec_ddl("CREATE TYPE user_age AS INT")
.assert_success()
.exec_ddl("CREATE TYPE score AS FLOAT")
.assert_success()
.exec_ddl("CREATE TAG User(id INT, name STRING, age user_age, score score)")
.assert_success()
.exec_dml("INSERT VERTEX User(name, age, score) VALUES 1:('Alice', 30, 95.5)")
.assert_success()
.query("MATCH (u:User) RETURN u.age, u.score")
.assert_result_contains(vec![Value::Int(30)])
.assert_result_contains(vec![Value::Float(95.5)]);
}