kotoba_core/
lib.rs

1//! kotoba-core - Kotoba Core Components
2
3pub mod types;
4pub mod schema;
5pub mod schema_validator;
6// pub mod pgview; // Temporarily disabled due to Value type conflicts
7pub mod ir;
8pub mod topology;
9pub mod graph;
10pub mod prelude {
11    // Re-export commonly used items
12    pub use crate::types::*;
13    pub use crate::schema::*;
14    pub use crate::schema_validator::*;
15    // pub use crate::pgview::*; // Temporarily disabled
16    pub use crate::ir::*;
17    // Re-export KotobaError to avoid version conflicts
18    pub use kotoba_errors::KotobaError;
19}
20
21#[cfg(test)]
22mod tests {
23    use super::*;
24    use crate::types::*;
25    use std::collections::HashMap;
26
27    #[test]
28    fn test_value_serialization() {
29        // Test Value enum serialization
30        let null_val = Value::Null;
31        let json = serde_json::to_string(&null_val).unwrap();
32        assert_eq!(json, "null");
33
34        let bool_val = Value::Bool(true);
35        let json = serde_json::to_string(&bool_val).unwrap();
36        assert_eq!(json, "true");
37
38        let int_val = Value::Int(42);
39        let json = serde_json::to_string(&int_val).unwrap();
40        assert_eq!(json, "42");
41
42        let str_val = Value::String("hello".to_string());
43        let json = serde_json::to_string(&str_val).unwrap();
44        assert_eq!(json, "\"hello\"");
45
46        let array_val = Value::Array(vec!["a".to_string(), "b".to_string()]);
47        let json = serde_json::to_string(&array_val).unwrap();
48        assert_eq!(json, "[\"a\",\"b\"]");
49
50        // Test Integer variant (compatibility)
51        let integer_val = Value::Integer(123);
52        let json = serde_json::to_string(&integer_val).unwrap();
53        assert_eq!(json, "123");
54    }
55
56    #[test]
57    fn test_value_deserialization() {
58        // Test Value enum deserialization
59        let null_val: Value = serde_json::from_str("null").unwrap();
60        assert_eq!(null_val, Value::Null);
61
62        let bool_val: Value = serde_json::from_str("true").unwrap();
63        assert_eq!(bool_val, Value::Bool(true));
64
65        let int_val: Value = serde_json::from_str("42").unwrap();
66        assert_eq!(int_val, Value::Int(42));
67
68        let str_val: Value = serde_json::from_str("\"hello\"").unwrap();
69        assert_eq!(str_val, Value::String("hello".to_string()));
70
71        let array_val: Value = serde_json::from_str("[\"a\",\"b\"]").unwrap();
72        assert_eq!(array_val, Value::Array(vec!["a".to_string(), "b".to_string()]));
73    }
74
75    #[test]
76    fn test_value_equality_and_hash() {
77        // Test equality
78        assert_eq!(Value::Null, Value::Null);
79        assert_eq!(Value::Bool(true), Value::Bool(true));
80        assert_eq!(Value::Int(42), Value::Int(42));
81        assert_eq!(Value::String("test".to_string()), Value::String("test".to_string()));
82        assert_eq!(Value::Integer(42), Value::Integer(42));
83
84        // Test inequality
85        assert_ne!(Value::Bool(true), Value::Bool(false));
86        assert_ne!(Value::Int(42), Value::Int(43));
87        assert_ne!(Value::String("test".to_string()), Value::String("other".to_string()));
88
89        // Test that Int and Integer are considered different (for now)
90        assert_ne!(Value::Int(42), Value::Integer(42));
91
92        // Test Hash implementation works
93        use std::collections::HashSet;
94        let mut set = HashSet::new();
95        set.insert(Value::Null);
96        set.insert(Value::Bool(true));
97        set.insert(Value::String("test".to_string()));
98        assert_eq!(set.len(), 3);
99    }
100
101    #[test]
102    fn test_content_hash() {
103        // Test ContentHash generation
104        let data = [42u8; 32];
105        let hash = ContentHash::sha256(data);
106        assert!(!hash.0.is_empty());
107        assert!(hash.0.len() == 64); // SHA256 produces 32 bytes = 64 hex chars
108
109        // Test that same data produces same hash
110        let hash2 = ContentHash::sha256(data);
111        assert_eq!(hash, hash2);
112
113        // Test that different data produces different hash
114        let data2 = [43u8; 32];
115        let hash3 = ContentHash::sha256(data2);
116        assert_ne!(hash, hash3);
117    }
118
119    #[test]
120    fn test_uuid_types() {
121        // Test that VertexId and EdgeId are UUIDs
122        let vertex_id = VertexId::new_v4();
123        let edge_id = EdgeId::new_v4();
124
125        assert_ne!(vertex_id, edge_id); // Should be different UUIDs
126        assert_eq!(vertex_id.get_version_num(), 4); // Should be v4 UUIDs
127        assert_eq!(edge_id.get_version_num(), 4);
128
129        // Test UUID string representation
130        let id_str = vertex_id.to_string();
131        assert_eq!(id_str.len(), 36); // UUID string length
132        assert!(id_str.contains('-')); // Should contain hyphens
133    }
134
135    #[test]
136    fn test_graph_ref() {
137        // Test GraphRef_ creation and operations
138        let ref1 = GraphRef_("test_hash".to_string());
139        let ref2 = GraphRef_("test_hash".to_string());
140        let ref3 = GraphRef_("different_hash".to_string());
141
142        assert_eq!(ref1, ref2);
143        assert_ne!(ref1, ref3);
144
145        // Test serialization
146        let json = serde_json::to_string(&ref1).unwrap();
147        assert_eq!(json, "\"test_hash\"");
148
149        // Test deserialization
150        let deserialized: GraphRef_ = serde_json::from_str("\"test_hash\"").unwrap();
151        assert_eq!(deserialized, ref1);
152    }
153
154    #[test]
155    fn test_tx_id() {
156        // Test TxId creation and operations
157        let tx1 = TxId("tx_123".to_string());
158        let tx2 = TxId("tx_123".to_string());
159        let tx3 = TxId("tx_456".to_string());
160
161        assert_eq!(tx1, tx2);
162        assert_ne!(tx1, tx3);
163
164        // Test ordering
165        assert!(tx1 < tx3);
166        assert!(tx3 > tx1);
167
168        // Test serialization
169        let json = serde_json::to_string(&tx1).unwrap();
170        assert_eq!(json, "\"tx_123\"");
171
172        // Test deserialization
173        let deserialized: TxId = serde_json::from_str("\"tx_123\"").unwrap();
174        assert_eq!(deserialized, tx1);
175    }
176
177    #[test]
178    fn test_properties_operations() {
179        // Test Properties (HashMap) operations
180        let mut props = Properties::new();
181
182        // Insert various value types
183        props.insert("null_prop".to_string(), Value::Null);
184        props.insert("bool_prop".to_string(), Value::Bool(true));
185        props.insert("int_prop".to_string(), Value::Int(42));
186        props.insert("string_prop".to_string(), Value::String("hello".to_string()));
187        props.insert("array_prop".to_string(), Value::Array(vec!["a".to_string(), "b".to_string()]));
188
189        assert_eq!(props.len(), 5);
190
191        // Test retrieval
192        assert_eq!(props.get("bool_prop"), Some(&Value::Bool(true)));
193        assert_eq!(props.get("missing_prop"), None);
194
195        // Test removal
196        let removed = props.remove("int_prop");
197        assert_eq!(removed, Some(Value::Int(42)));
198        assert_eq!(props.len(), 4);
199
200        // Test iteration
201        let keys: Vec<_> = props.keys().collect();
202        assert!(keys.contains(&&"null_prop".to_string()));
203        assert!(keys.contains(&&"string_prop".to_string()));
204    }
205
206    #[test]
207    fn test_properties_serialization() {
208        let mut props = Properties::new();
209        props.insert("name".to_string(), Value::String("test".to_string()));
210        props.insert("count".to_string(), Value::Int(10));
211        props.insert("active".to_string(), Value::Bool(true));
212
213        // Test serialization
214        let json = serde_json::to_string(&props).unwrap();
215        let _expected = r#"{"active":true,"count":10,"name":"test"}"#;
216        // Note: JSON object keys may be reordered, so we just check it parses back correctly
217
218        // Test deserialization
219        let deserialized: Properties = serde_json::from_str(&json).unwrap();
220        assert_eq!(deserialized.len(), 3);
221        assert_eq!(deserialized.get("name"), Some(&Value::String("test".to_string())));
222        assert_eq!(deserialized.get("count"), Some(&Value::Int(10)));
223        assert_eq!(deserialized.get("active"), Some(&Value::Bool(true)));
224    }
225
226    #[test]
227    fn test_label_and_property_key_types() {
228        // Test Label type (just a String alias)
229        let label: Label = "vertex_label".to_string();
230        assert_eq!(label, "vertex_label");
231
232        // Test PropertyKey type (just a String alias)
233        let key: PropertyKey = "property_key".to_string();
234        assert_eq!(key, "property_key");
235    }
236
237    #[test]
238    fn test_value_display_and_debug() {
239        // Test Debug trait
240        assert_eq!(format!("{:?}", Value::Null), "Null");
241        assert_eq!(format!("{:?}", Value::Bool(true)), "Bool(true)");
242        assert_eq!(format!("{:?}", Value::Int(42)), "Int(42)");
243        assert_eq!(format!("{:?}", Value::Integer(123)), "Integer(123)");
244        assert_eq!(format!("{:?}", Value::String("hello".to_string())), "String(\"hello\")");
245        assert_eq!(format!("{:?}", Value::Array(vec!["a".to_string()])), "Array([\"a\"])");
246    }
247
248    #[test]
249    fn test_large_values() {
250        // Test with large integer values
251        let large_int = Value::Int(i64::MAX);
252        let json = serde_json::to_string(&large_int).unwrap();
253        let deserialized: Value = serde_json::from_str(&json).unwrap();
254        assert_eq!(deserialized, large_int);
255
256        // Test with large strings
257        let large_string = "a".repeat(10000);
258        let str_val = Value::String(large_string.clone());
259        let json = serde_json::to_string(&str_val).unwrap();
260        let deserialized: Value = serde_json::from_str(&json).unwrap();
261        assert_eq!(deserialized, str_val);
262    }
263
264    #[test]
265    fn test_edge_cases() {
266        // Test empty string
267        let empty_str = Value::String("".to_string());
268        let json = serde_json::to_string(&empty_str).unwrap();
269        assert_eq!(json, "\"\"");
270
271        // Test empty array
272        let empty_array = Value::Array(vec![]);
273        let json = serde_json::to_string(&empty_array).unwrap();
274        assert_eq!(json, "[]");
275
276        // Test zero values
277        assert_eq!(Value::Int(0), Value::Int(0));
278        assert_eq!(Value::Integer(0), Value::Integer(0));
279        assert_eq!(Value::Bool(false), Value::Bool(false));
280    }
281}