operation_delete_test.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. use crate::node::script::NodeScript::*;
  2. use crate::node::script::NodeTest;
  3. use lib_ot::core::{Changeset, NodeData, NodeDataBuilder};
  4. #[test]
  5. fn operation_delete_nested_node_test() {
  6. let mut test = NodeTest::new();
  7. let image_a = NodeData::new("image_a");
  8. let image_b = NodeData::new("image_b");
  9. let video_a = NodeData::new("video_a");
  10. let video_b = NodeData::new("video_b");
  11. let image_1 = NodeDataBuilder::new("image_1")
  12. .add_node_data(image_a.clone())
  13. .add_node_data(image_b.clone())
  14. .build();
  15. let video_1 = NodeDataBuilder::new("video_1")
  16. .add_node_data(video_a.clone())
  17. .add_node_data(video_b)
  18. .build();
  19. let text_node_1 = NodeDataBuilder::new("text_1")
  20. .add_node_data(image_1)
  21. .add_node_data(video_1.clone())
  22. .build();
  23. let image_2 = NodeDataBuilder::new("image_2")
  24. .add_node_data(image_a)
  25. .add_node_data(image_b.clone())
  26. .build();
  27. let text_node_2 = NodeDataBuilder::new("text_2")
  28. .add_node_data(image_2)
  29. .build();
  30. let scripts = vec![
  31. InsertNode {
  32. path: 0.into(),
  33. node_data: text_node_1,
  34. rev_id: 1,
  35. },
  36. InsertNode {
  37. path: 1.into(),
  38. node_data: text_node_2,
  39. rev_id: 2,
  40. },
  41. // 0:text_1
  42. // 0:image_1
  43. // 0:image_a
  44. // 1:image_b
  45. // 1:video_1
  46. // 0:video_a
  47. // 1:video_b
  48. // 1:text_2
  49. // 0:image_2
  50. // 0:image_a
  51. // 1:image_b
  52. DeleteNode {
  53. path: vec![0, 0, 0].into(),
  54. rev_id: 3,
  55. },
  56. AssertNode {
  57. path: vec![0, 0, 0].into(),
  58. expected: Some(image_b),
  59. },
  60. AssertNode {
  61. path: vec![0, 1].into(),
  62. expected: Some(video_1),
  63. },
  64. DeleteNode {
  65. path: vec![0, 1, 1].into(),
  66. rev_id: 4,
  67. },
  68. AssertNode {
  69. path: vec![0, 1, 0].into(),
  70. expected: Some(video_a),
  71. },
  72. ];
  73. test.run_scripts(scripts);
  74. }
  75. #[test]
  76. fn operation_delete_node_with_revision_conflict_test() {
  77. let mut test = NodeTest::new();
  78. let text_1 = NodeDataBuilder::new("text_1").build();
  79. let text_2 = NodeDataBuilder::new("text_2").build();
  80. let text_3 = NodeDataBuilder::new("text_3").build();
  81. let scripts = vec![
  82. InsertNode {
  83. path: 0.into(),
  84. node_data: text_1.clone(),
  85. rev_id: 1,
  86. },
  87. InsertNode {
  88. path: 1.into(),
  89. node_data: text_2,
  90. rev_id: 2,
  91. },
  92. // The node's in the tree will be:
  93. // 0: text_1
  94. // 2: text_2
  95. //
  96. // The insert action is happened concurrently with the delete action, because they
  97. // share the same rev_id. aka, 3. The delete action is want to delete the node at index 1,
  98. // but it was moved to index 2.
  99. InsertNode {
  100. path: 1.into(),
  101. node_data: text_3.clone(),
  102. rev_id: 3,
  103. },
  104. // 0: text_1
  105. // 1: text_3
  106. // 2: text_2
  107. //
  108. // The path of the delete action will be transformed to a new path that point to the text_2.
  109. // 1 -> 2
  110. DeleteNode {
  111. path: 1.into(),
  112. rev_id: 3,
  113. },
  114. // After perform the delete action, the tree will be:
  115. // 0: text_1
  116. // 1: text_3
  117. AssertNumberOfChildrenAtPath {
  118. path: None,
  119. expected: 2,
  120. },
  121. AssertNode {
  122. path: 0.into(),
  123. expected: Some(text_1),
  124. },
  125. AssertNode {
  126. path: 1.into(),
  127. expected: Some(text_3),
  128. },
  129. AssertNode {
  130. path: 2.into(),
  131. expected: None,
  132. },
  133. ];
  134. test.run_scripts(scripts);
  135. }
  136. #[test]
  137. fn operation_update_node_after_delete_test() {
  138. let mut test = NodeTest::new();
  139. let text_1 = NodeDataBuilder::new("text_1").build();
  140. let text_2 = NodeDataBuilder::new("text_2").build();
  141. let scripts = vec![
  142. InsertNode {
  143. path: 0.into(),
  144. node_data: text_1,
  145. rev_id: 1,
  146. },
  147. InsertNode {
  148. path: 1.into(),
  149. node_data: text_2,
  150. rev_id: 2,
  151. },
  152. DeleteNode {
  153. path: 0.into(),
  154. rev_id: 3,
  155. },
  156. // The node at path 1 is not exist. The following UpdateBody script will do nothing
  157. AssertNode {
  158. path: 1.into(),
  159. expected: None,
  160. },
  161. UpdateBody {
  162. path: 1.into(),
  163. changeset: Changeset::Delta {
  164. delta: Default::default(),
  165. inverted: Default::default(),
  166. },
  167. },
  168. ];
  169. test.run_scripts(scripts);
  170. }