//! Matrix coverage for `drop relationship (endpoints | name)` //! (ADR-0013). //! //! Two selector forms: //! - by endpoints: `drop relationship from P.c to C.c` //! - by name: `drop relationship ` //! //! Handoff-12 §2.2 noted the qualified-column slots //! (`from T.col`) don't narrow to T's columns. The fix lands //! alongside the matrix where the test asserts narrowing. use crate::typing_surface::*; use rdbms_playground::completion::SchemaCache; use rdbms_playground::input_render::InputState; /// schema_multi_table + a named relationship in the cache so /// the by-name selector has a candidate. fn schema_with_relationship() -> SchemaCache { let mut cache = schema_multi_table(); cache .relationships .push("Orders_CustId_to_Customers".to_string()); cache } #[test] fn after_relationship_keyword_offers_from_and_names() { let schema = schema_with_relationship(); let a = assess_at_end("drop relationship ", &schema); assert!(matches!(a.state, InputState::IncompleteAtEof)); // Both selector forms discoverable: `from` for endpoints, // the relationship name for the by-name form. assert_candidate_present( &a, &["from", "Orders_CustId_to_Customers"], ); crate::snap!("after_relationship_keyword", a); } #[test] fn after_from_offers_table_names() { let schema = schema_with_relationship(); let a = assess_at_end("drop relationship from ", &schema); assert!(matches!(a.state, InputState::IncompleteAtEof)); assert_candidate_present(&a, &["Customers", "Orders"]); crate::snap!("after_from", a); } #[test] fn after_parent_table_dot_narrows_to_parent_columns() { // §2.2 follow-up: `from Orders.` should narrow the // column slot to Orders's columns. let schema = schema_with_relationship(); let a = assess_at_end("drop relationship from Orders.", &schema); assert!(matches!(a.state, InputState::IncompleteAtEof)); assert_candidate_present(&a, &["OrderId", "CustId", "Total"]); assert_no_candidate_named(&a, &["Name"]); crate::snap!("after_parent_dot", a); } #[test] fn after_to_offers_table_names() { let schema = schema_with_relationship(); let a = assess_at_end( "drop relationship from Orders.CustId to ", &schema, ); assert!(matches!(a.state, InputState::IncompleteAtEof)); assert_candidate_present(&a, &["Customers", "Orders"]); crate::snap!("after_to", a); } #[test] fn after_child_table_dot_narrows_to_child_columns() { let schema = schema_with_relationship(); let a = assess_at_end( "drop relationship from Orders.CustId to Customers.", &schema, ); assert!(matches!(a.state, InputState::IncompleteAtEof)); assert_candidate_present(&a, &["id", "Name"]); assert_no_candidate_named(&a, &["OrderId", "CustId", "Total"]); crate::snap!("after_child_dot", a); } #[test] fn complete_drop_relationship_by_endpoints_parses() { let schema = schema_with_relationship(); let a = assess_at_end( "drop relationship from Orders.CustId to Customers.id", &schema, ); assert!(matches!(a.state, InputState::Valid)); assert_eq!(a.parse_result.as_deref(), Ok("DropRelationship")); crate::snap!("complete_by_endpoints", a); } #[test] fn complete_drop_relationship_by_name_parses() { let schema = schema_with_relationship(); let a = assess_at_end( "drop relationship Orders_CustId_to_Customers", &schema, ); assert!(matches!(a.state, InputState::Valid)); assert_eq!(a.parse_result.as_deref(), Ok("DropRelationship")); crate::snap!("complete_by_name", a); }