|
@@ -73,7 +73,7 @@ fn operation_update_node_body_deserialize_test() {
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
-fn operation_insert_transform_test() {
|
|
|
+fn operation_insert_op_transform_test() {
|
|
|
let node_1 = NodeDataBuilder::new("text_1").build();
|
|
|
let node_2 = NodeDataBuilder::new("text_2").build();
|
|
|
let op_1 = NodeOperation::Insert {
|
|
@@ -81,7 +81,7 @@ fn operation_insert_transform_test() {
|
|
|
nodes: vec![node_1],
|
|
|
};
|
|
|
|
|
|
- let mut insert_2 = NodeOperation::Insert {
|
|
|
+ let insert_2 = NodeOperation::Insert {
|
|
|
path: Path(vec![0, 1]),
|
|
|
nodes: vec![node_2],
|
|
|
};
|
|
@@ -95,14 +95,23 @@ fn operation_insert_transform_test() {
|
|
|
}
|
|
|
|
|
|
#[test]
|
|
|
-fn operation_insert_transform_test2() {
|
|
|
+fn operation_insert_transform_test() {
|
|
|
let mut test = NodeTest::new();
|
|
|
let node_data_1 = NodeDataBuilder::new("text_1").build();
|
|
|
let node_data_2 = NodeDataBuilder::new("text_2").build();
|
|
|
- let node_2: Node = node_data_2.clone().into();
|
|
|
let node_data_3 = NodeDataBuilder::new("text_3").build();
|
|
|
let node_3: Node = node_data_3.clone().into();
|
|
|
-
|
|
|
+ //
|
|
|
+ // rev_id:1 0: text_1
|
|
|
+ // rev_id:2 1: text_2
|
|
|
+ //
|
|
|
+ // Insert a new operation with rev_id 1.But the rev_id:1 is already exist, so
|
|
|
+ // it needs to do the transform.
|
|
|
+ //
|
|
|
+ // --> 1:text_3
|
|
|
+ // transform into:
|
|
|
+ // --> 2:text_3
|
|
|
+ //
|
|
|
let scripts = vec![
|
|
|
InsertNode {
|
|
|
path: 0.into(),
|
|
@@ -119,14 +128,65 @@ fn operation_insert_transform_test2() {
|
|
|
node_data: node_data_3.clone(),
|
|
|
rev_id: 1,
|
|
|
},
|
|
|
- // AssertNode {
|
|
|
- // path: 2.into(),
|
|
|
- // expected: node_2,
|
|
|
- // },
|
|
|
AssertNode {
|
|
|
+ path: 2.into(),
|
|
|
+ expected: Some(node_3),
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ test.run_scripts(scripts);
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn operation_delete_transform_test() {
|
|
|
+ let mut test = NodeTest::new();
|
|
|
+ let node_data_1 = NodeDataBuilder::new("text_1").build();
|
|
|
+ let node_data_2 = NodeDataBuilder::new("text_2").build();
|
|
|
+ let node_data_3 = NodeDataBuilder::new("text_3").build();
|
|
|
+ let node_3: Node = node_data_3.clone().into();
|
|
|
+
|
|
|
+ let scripts = vec![
|
|
|
+ InsertNode {
|
|
|
+ path: 0.into(),
|
|
|
+ node_data: node_data_1.clone(),
|
|
|
+ rev_id: 1,
|
|
|
+ },
|
|
|
+ InsertNode {
|
|
|
path: 1.into(),
|
|
|
- expected: node_3,
|
|
|
+ node_data: node_data_2.clone(),
|
|
|
+ rev_id: 2,
|
|
|
+ },
|
|
|
+ // The node's in the tree will be:
|
|
|
+ // 0: text_1
|
|
|
+ // 2: text_2
|
|
|
+ //
|
|
|
+ // The insert action is happened concurrently with the delete action, because they
|
|
|
+ // share the same rev_id. aka, 3. The delete action is want to delete the node at index 1,
|
|
|
+ // but it was moved to index 2.
|
|
|
+ InsertNode {
|
|
|
+ path: 1.into(),
|
|
|
+ node_data: node_data_3.clone(),
|
|
|
+ rev_id: 3,
|
|
|
+ },
|
|
|
+ //
|
|
|
+ // 0: text_1
|
|
|
+ // 1: text_3
|
|
|
+ // 2: text_2
|
|
|
+ //
|
|
|
+ // The path of the delete action will be transformed to a new path that point to the text_2.
|
|
|
+ // 1 -> 2
|
|
|
+ DeleteNode {
|
|
|
+ path: 1.into(),
|
|
|
+ rev_id: 3,
|
|
|
+ },
|
|
|
+ AssertNode {
|
|
|
+ path: 1.into(),
|
|
|
+ expected: Some(node_3),
|
|
|
+ },
|
|
|
+ AssertNode {
|
|
|
+ path: 2.into(),
|
|
|
+ expected: None,
|
|
|
},
|
|
|
+ AssertNumberOfNodesAtPath { path: None, len: 2 },
|
|
|
];
|
|
|
test.run_scripts(scripts);
|
|
|
}
|