1pub mod error;
2pub mod storage;
3pub mod tree;
4pub mod types;
5
6pub use error::MemoryError;
7pub use storage::{
8 clear_memory_storage_root, memory_storage_path, read_memory_tree, set_memory_storage_root,
9 write_memory_tree, MemoryStorageFile,
10};
11pub use tree::{
12 MemoryNeighborhoodPoint, MemoryRecallBranch, MemoryRecallOptions, MemoryTree,
13 MemoryTypeNeighborhood, MemoryTypeSearchOptions,
14};
15pub use types::{MemoryPoint, MemoryPointKind, MemoryPointStatus, HEADLESS_POINT_ID};
16
17#[cfg(test)]
18mod tests {
19 use super::*;
20
21 #[test]
22 fn creates_valid_headless_point() {
23 let point = MemoryPoint::headless();
24
25 assert_eq!(point.point_id, HEADLESS_POINT_ID);
26 assert!(point.is_headless());
27 assert!(point.storage.is_none());
28 assert!(point.types.is_none());
29 assert!(point.validate().is_ok());
30 }
31
32 #[test]
33 fn creates_root_point_under_headless() {
34 let point = MemoryPoint::new_root("用户比较喜欢吃炸酱面", "用户喜欢吃的面食").unwrap();
35
36 assert_eq!(point.kind, MemoryPointKind::Root);
37 assert_eq!(point.parent_id.as_deref(), Some(HEADLESS_POINT_ID));
38 assert_eq!(point.storage.as_deref(), Some("用户比较喜欢吃炸酱面"));
39 assert_eq!(point.types.as_deref(), Some("用户喜欢吃的面食"));
40 assert!(point.validate().is_ok());
41 }
42
43 #[test]
44 fn creates_child_point() {
45 let point =
46 MemoryPoint::new_child("parent-1", "用户比较喜欢吃糖醋排骨", "用户喜欢吃的菜").unwrap();
47
48 assert_eq!(point.kind, MemoryPointKind::Point);
49 assert_eq!(point.parent_id.as_deref(), Some("parent-1"));
50 assert!(point.validate().is_ok());
51 }
52
53 #[test]
54 fn updates_types_and_storage() {
55 let mut point = MemoryPoint::new_root("用户比较喜欢吃炸酱面", "用户喜欢吃的面食").unwrap();
56
57 point.update_types("用户喜欢吃的食物").unwrap();
58 point
59 .update_storage("用户喜欢吃炸酱面、糖醋排骨等食物")
60 .unwrap();
61
62 assert_eq!(point.types.as_deref(), Some("用户喜欢吃的食物"));
63 assert_eq!(
64 point.storage.as_deref(),
65 Some("用户喜欢吃炸酱面、糖醋排骨等食物")
66 );
67 }
68
69 #[test]
70 fn prevents_headless_modification() {
71 let mut point = MemoryPoint::headless();
72
73 let result = point.update_types("anything");
74
75 assert!(matches!(
76 result,
77 Err(MemoryError::HeadlessModification {
78 operation: "update_types"
79 })
80 ));
81 }
82
83 #[test]
84 fn reparenting_updates_kind() {
85 let mut point =
86 MemoryPoint::new_child("parent-1", "用户比较喜欢吃糖醋排骨", "用户喜欢吃的菜").unwrap();
87
88 point.set_parent(HEADLESS_POINT_ID).unwrap();
89 assert_eq!(point.kind, MemoryPointKind::Root);
90
91 point.set_parent("another-parent").unwrap();
92 assert_eq!(point.kind, MemoryPointKind::Point);
93 }
94
95 #[test]
96 fn rejects_empty_storage_and_types() {
97 let storage_result = MemoryPoint::new_root("", "用户喜欢吃的面食");
98 let types_result = MemoryPoint::new_root("用户比较喜欢吃炸酱面", " ");
99
100 assert!(matches!(
101 storage_result,
102 Err(MemoryError::EmptyField { field: "storage" })
103 ));
104 assert!(matches!(
105 types_result,
106 Err(MemoryError::EmptyField { field: "types" })
107 ));
108 }
109
110 #[test]
111 fn supports_custom_attributes() {
112 let mut point = MemoryPoint::new_root("用户比较喜欢吃炸酱面", "用户喜欢吃的面食").unwrap();
113
114 point
115 .set_attribute("confidence", serde_json::json!(0.92))
116 .unwrap();
117
118 assert_eq!(point.attributes["confidence"], serde_json::json!(0.92));
119 assert_eq!(
120 point.remove_attribute("confidence"),
121 Some(serde_json::json!(0.92))
122 );
123 }
124}