operation_test.rs 4.9 KB

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