diff --git a/shared-lib/lib-ot/tests/node/operation_test.rs b/shared-lib/lib-ot/tests/node/operation_test.rs index d60b035c1c..ba8e76b4d9 100644 --- a/shared-lib/lib-ot/tests/node/operation_test.rs +++ b/shared-lib/lib-ot/tests/node/operation_test.rs @@ -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: 1.into(), - expected: node_3, + 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(), + 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); +} diff --git a/shared-lib/lib-ot/tests/node/script.rs b/shared-lib/lib-ot/tests/node/script.rs index 01d1ad16db..2ebc7c9fba 100644 --- a/shared-lib/lib-ot/tests/node/script.rs +++ b/shared-lib/lib-ot/tests/node/script.rs @@ -22,6 +22,7 @@ pub enum NodeScript { }, DeleteNode { path: Path, + rev_id: usize, }, AssertNumberOfNodesAtPath { path: Option, @@ -33,16 +34,12 @@ pub enum NodeScript { }, AssertNode { path: Path, - expected: Node, + expected: Option, }, AssertNodeDelta { path: Path, expected: TextDelta, }, - ApplyTransaction { - transaction: Transaction, - rev_id: usize, - }, } pub struct NodeTest { @@ -92,15 +89,20 @@ impl NodeTest { .finalize(); self.apply_transaction(transaction); } - NodeScript::DeleteNode { path } => { - let transaction = TransactionBuilder::new(&self.node_tree) + NodeScript::DeleteNode { path, rev_id } => { + let mut transaction = TransactionBuilder::new(&self.node_tree) .delete_node_at_path(&path) .finalize(); + self.transform_transaction_if_need(&mut transaction, rev_id); self.apply_transaction(transaction); } NodeScript::AssertNode { path, expected } => { - let node_id = self.node_tree.node_id_at_path(path).unwrap(); - let node = self.node_tree.get_node(node_id).cloned().unwrap(); + let node_id = self.node_tree.node_id_at_path(path); + if expected.is_none() && node_id.is_none() { + return; + } + + let node = self.node_tree.get_node(node_id.unwrap()).cloned(); assert_eq!(node, expected); } NodeScript::AssertNodeData { path, expected } => { @@ -136,14 +138,6 @@ impl NodeTest { panic!("Node body type not match, expect Delta"); } } - - NodeScript::ApplyTransaction { - mut transaction, - rev_id, - } => { - self.transform_transaction_if_need(&mut transaction, rev_id); - self.apply_transaction(transaction); - } } } diff --git a/shared-lib/lib-ot/tests/node/tree_test.rs b/shared-lib/lib-ot/tests/node/tree_test.rs index 39357b158c..90427457d0 100644 --- a/shared-lib/lib-ot/tests/node/tree_test.rs +++ b/shared-lib/lib-ot/tests/node/tree_test.rs @@ -185,7 +185,10 @@ fn node_delete_test() { node_data: inserted_node, rev_id: 1, }, - DeleteNode { path: path.clone() }, + DeleteNode { + path: path.clone(), + rev_id: 2, + }, AssertNodeData { path, expected: None }, ]; test.run_scripts(scripts);