script.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #![allow(clippy::all)]
  2. use lib_ot::core::{NodeTreeContext, Transaction};
  3. use lib_ot::{
  4. core::attributes::AttributeHashMap,
  5. core::{Body, Changeset, NodeData, NodeTree, Path, TransactionBuilder},
  6. text_delta::TextOperations,
  7. };
  8. use std::collections::HashMap;
  9. pub enum NodeScript {
  10. InsertNode {
  11. path: Path,
  12. node_data: NodeData,
  13. rev_id: usize,
  14. },
  15. InsertNodes {
  16. path: Path,
  17. node_data_list: Vec<NodeData>,
  18. rev_id: usize,
  19. },
  20. UpdateAttributes {
  21. path: Path,
  22. attributes: AttributeHashMap,
  23. },
  24. UpdateBody {
  25. path: Path,
  26. changeset: Changeset,
  27. },
  28. DeleteNode {
  29. path: Path,
  30. rev_id: usize,
  31. },
  32. AssertNumberOfChildrenAtPath {
  33. path: Option<Path>,
  34. expected: usize,
  35. },
  36. AssertNodesAtRoot {
  37. expected: Vec<NodeData>,
  38. },
  39. #[allow(dead_code)]
  40. AssertNodesAtPath {
  41. path: Path,
  42. expected: Vec<NodeData>,
  43. },
  44. AssertNode {
  45. path: Path,
  46. expected: Option<NodeData>,
  47. },
  48. AssertNodeDelta {
  49. path: Path,
  50. expected: TextOperations,
  51. },
  52. #[allow(dead_code)]
  53. AssertTreeJSON {
  54. expected: String,
  55. },
  56. }
  57. pub struct NodeTest {
  58. rev_id: usize,
  59. rev_operations: HashMap<usize, Transaction>,
  60. node_tree: NodeTree,
  61. }
  62. impl NodeTest {
  63. pub fn new() -> Self {
  64. Self {
  65. rev_id: 0,
  66. rev_operations: HashMap::new(),
  67. node_tree: NodeTree::new(NodeTreeContext::default()),
  68. }
  69. }
  70. pub fn run_scripts(&mut self, scripts: Vec<NodeScript>) {
  71. for script in scripts {
  72. self.run_script(script);
  73. }
  74. }
  75. pub fn run_script(&mut self, script: NodeScript) {
  76. match script {
  77. NodeScript::InsertNode {
  78. path,
  79. node_data: node,
  80. rev_id,
  81. } => {
  82. let mut transaction = TransactionBuilder::new(&self.node_tree)
  83. .insert_node_at_path(path, node)
  84. .finalize();
  85. self.transform_transaction_if_need(&mut transaction, rev_id);
  86. self.apply_transaction(transaction);
  87. }
  88. NodeScript::InsertNodes {
  89. path,
  90. node_data_list,
  91. rev_id,
  92. } => {
  93. let mut transaction = TransactionBuilder::new(&self.node_tree)
  94. .insert_nodes_at_path(path, node_data_list)
  95. .finalize();
  96. self.transform_transaction_if_need(&mut transaction, rev_id);
  97. self.apply_transaction(transaction);
  98. }
  99. NodeScript::UpdateAttributes { path, attributes } => {
  100. let transaction = TransactionBuilder::new(&self.node_tree)
  101. .update_attributes_at_path(&path, attributes)
  102. .finalize();
  103. self.apply_transaction(transaction);
  104. }
  105. NodeScript::UpdateBody { path, changeset } => {
  106. //
  107. let transaction = TransactionBuilder::new(&self.node_tree)
  108. .update_body_at_path(&path, changeset)
  109. .finalize();
  110. self.apply_transaction(transaction);
  111. }
  112. NodeScript::DeleteNode { path, rev_id } => {
  113. let mut transaction = TransactionBuilder::new(&self.node_tree)
  114. .delete_node_at_path(&path)
  115. .finalize();
  116. self.transform_transaction_if_need(&mut transaction, rev_id);
  117. self.apply_transaction(transaction);
  118. }
  119. NodeScript::AssertNode { path, expected } => {
  120. let node = self.node_tree.get_node_data_at_path(&path);
  121. assert_eq!(node, expected.map(|e| e.into()));
  122. }
  123. NodeScript::AssertNumberOfChildrenAtPath { path, expected } => match path {
  124. None => {
  125. let len = self.node_tree.number_of_children(None);
  126. assert_eq!(len, expected)
  127. }
  128. Some(path) => {
  129. let node_id = self.node_tree.node_id_at_path(path).unwrap();
  130. let len = self.node_tree.number_of_children(Some(node_id));
  131. assert_eq!(len, expected)
  132. }
  133. },
  134. NodeScript::AssertNodesAtRoot { expected } => {
  135. let nodes = self.node_tree.get_node_data_at_root().unwrap().children;
  136. assert_eq!(nodes, expected)
  137. }
  138. NodeScript::AssertNodesAtPath { path, expected } => {
  139. let nodes = self.node_tree.get_node_data_at_path(&path).unwrap().children;
  140. assert_eq!(nodes, expected)
  141. }
  142. NodeScript::AssertNodeDelta { path, expected } => {
  143. let node = self.node_tree.get_node_at_path(&path).unwrap();
  144. if let Body::Delta(delta) = node.body.clone() {
  145. debug_assert_eq!(delta, expected);
  146. } else {
  147. panic!("Node body type not match, expect Delta");
  148. }
  149. }
  150. NodeScript::AssertTreeJSON { expected } => {
  151. let json = serde_json::to_string(&self.node_tree).unwrap();
  152. assert_eq!(json, expected)
  153. }
  154. }
  155. }
  156. fn apply_transaction(&mut self, transaction: Transaction) {
  157. self.rev_id += 1;
  158. self.rev_operations.insert(self.rev_id, transaction.clone());
  159. self.node_tree.apply_transaction(transaction).unwrap();
  160. }
  161. fn transform_transaction_if_need(&mut self, transaction: &mut Transaction, rev_id: usize) {
  162. if self.rev_id >= rev_id {
  163. for rev_id in rev_id..=self.rev_id {
  164. let old_transaction = self.rev_operations.get(&rev_id).unwrap();
  165. *transaction = old_transaction.transform(transaction).unwrap();
  166. }
  167. }
  168. }
  169. }