operation_test.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. use crate::node::script::NodeScript::*;
  2. use crate::node::script::NodeTest;
  3. use lib_ot::core::Node;
  4. use lib_ot::core::{NodeDataBuilder, NodeOperation, Path};
  5. #[test]
  6. fn operation_insert_op_transform_test() {
  7. let node_1 = NodeDataBuilder::new("text_1").build();
  8. let node_2 = NodeDataBuilder::new("text_2").build();
  9. let op_1 = NodeOperation::Insert {
  10. path: Path(vec![0, 1]),
  11. nodes: vec![node_1],
  12. };
  13. let mut insert_2 = NodeOperation::Insert {
  14. path: Path(vec![0, 1]),
  15. nodes: vec![node_2],
  16. };
  17. // let mut node_tree = NodeTree::new("root");
  18. // node_tree.apply_op(insert_1.clone()).unwrap();
  19. op_1.transform(&mut insert_2);
  20. let json = serde_json::to_string(&insert_2).unwrap();
  21. assert_eq!(json, r#"{"op":"insert","path":[0,2],"nodes":[{"type":"text_2"}]}"#);
  22. }
  23. #[test]
  24. fn operation_insert_transform_one_level_path_test() {
  25. let mut test = NodeTest::new();
  26. let node_data_1 = NodeDataBuilder::new("text_1").build();
  27. let node_data_2 = NodeDataBuilder::new("text_2").build();
  28. let node_data_3 = NodeDataBuilder::new("text_3").build();
  29. let node_3: Node = node_data_3.clone().into();
  30. // 0: text_1
  31. // 1: text_2
  32. //
  33. // Insert a new operation with rev_id 1,but the rev_id:1 is already exist, so
  34. // it needs to be transformed.
  35. // 1:text_3 => 2:text_3
  36. //
  37. // 0: text_1
  38. // 1: text_2
  39. // 2: text_3
  40. //
  41. // If the rev_id of the insert operation is 3. then the tree will be:
  42. // 0: text_1
  43. // 1: text_3
  44. // 2: text_2
  45. let scripts = vec![
  46. InsertNode {
  47. path: 0.into(),
  48. node_data: node_data_1,
  49. rev_id: 1,
  50. },
  51. InsertNode {
  52. path: 1.into(),
  53. node_data: node_data_2,
  54. rev_id: 2,
  55. },
  56. InsertNode {
  57. path: 1.into(),
  58. node_data: node_data_3,
  59. rev_id: 1,
  60. },
  61. AssertNode {
  62. path: 2.into(),
  63. expected: Some(node_3),
  64. },
  65. ];
  66. test.run_scripts(scripts);
  67. }
  68. #[test]
  69. fn operation_insert_transform_multiple_level_path_test() {
  70. let mut test = NodeTest::new();
  71. let node_data_1 = NodeDataBuilder::new("text_1")
  72. .add_node(NodeDataBuilder::new("text_1_1").build())
  73. .add_node(NodeDataBuilder::new("text_1_2").build())
  74. .build();
  75. let node_data_2 = NodeDataBuilder::new("text_2")
  76. .add_node(NodeDataBuilder::new("text_2_1").build())
  77. .add_node(NodeDataBuilder::new("text_2_2").build())
  78. .build();
  79. let node_data_3 = NodeDataBuilder::new("text_3").build();
  80. let scripts = vec![
  81. InsertNode {
  82. path: 0.into(),
  83. node_data: node_data_1,
  84. rev_id: 1,
  85. },
  86. InsertNode {
  87. path: 1.into(),
  88. node_data: node_data_2,
  89. rev_id: 2,
  90. },
  91. InsertNode {
  92. path: 1.into(),
  93. node_data: node_data_3.clone(),
  94. rev_id: 1,
  95. },
  96. AssertNode {
  97. path: 2.into(),
  98. expected: Some(node_data_3.into()),
  99. },
  100. ];
  101. test.run_scripts(scripts);
  102. }
  103. #[test]
  104. fn operation_delete_transform_path_test() {
  105. let mut test = NodeTest::new();
  106. let node_data_1 = NodeDataBuilder::new("text_1").build();
  107. let node_data_2 = NodeDataBuilder::new("text_2").build();
  108. let node_data_3 = NodeDataBuilder::new("text_3").build();
  109. let node_3: Node = node_data_3.clone().into();
  110. let scripts = vec![
  111. InsertNode {
  112. path: 0.into(),
  113. node_data: node_data_1,
  114. rev_id: 1,
  115. },
  116. InsertNode {
  117. path: 1.into(),
  118. node_data: node_data_2,
  119. rev_id: 2,
  120. },
  121. // The node's in the tree will be:
  122. // 0: text_1
  123. // 2: text_2
  124. //
  125. // The insert action is happened concurrently with the delete action, because they
  126. // share the same rev_id. aka, 3. The delete action is want to delete the node at index 1,
  127. // but it was moved to index 2.
  128. InsertNode {
  129. path: 1.into(),
  130. node_data: node_data_3,
  131. rev_id: 3,
  132. },
  133. // 0: text_1
  134. // 1: text_3
  135. // 2: text_2
  136. //
  137. // The path of the delete action will be transformed to a new path that point to the text_2.
  138. // 1 -> 2
  139. DeleteNode {
  140. path: 1.into(),
  141. rev_id: 3,
  142. },
  143. // After perform the delete action, the tree will be:
  144. // 0: text_1
  145. // 1: text_3
  146. AssertNumberOfNodesAtPath { path: None, len: 2 },
  147. AssertNode {
  148. path: 1.into(),
  149. expected: Some(node_3),
  150. },
  151. AssertNode {
  152. path: 2.into(),
  153. expected: None,
  154. },
  155. ];
  156. test.run_scripts(scripts);
  157. }