use crate::node::script::NodeScript::*; use crate::node::script::NodeTest; use lib_ot::core::{AttributeEntry, Changeset, NodeData, OperationTransform}; use lib_ot::text_delta::DeltaTextOperationBuilder; #[test] fn changeset_delta_compose_delta_test() { // delta 1 let delta_1 = DeltaTextOperationBuilder::new().insert("Hello world").build(); let inverted_1 = delta_1.inverted(); let mut changeset_1 = Changeset::Delta { delta: delta_1.clone(), inverted: inverted_1, }; // delta 2 let delta_2 = DeltaTextOperationBuilder::new() .retain(delta_1.utf16_target_len) .insert("!") .build(); let inverted_2 = delta_2.inverted(); let changeset_2 = Changeset::Delta { delta: delta_2, inverted: inverted_2, }; // compose changeset_1.compose(&changeset_2).unwrap(); if let Changeset::Delta { delta, inverted } = changeset_1 { assert_eq!(delta.content().unwrap(), "Hello world!"); let new_delta = delta.compose(&inverted).unwrap(); assert_eq!(new_delta.content().unwrap(), ""); } } #[test] fn operation_compose_delta_changeset_then_invert_test() { let delta = DeltaTextOperationBuilder::new().insert("Hello world").build(); let inverted = delta.inverted(); let changeset = Changeset::Delta { delta: delta.clone(), inverted: inverted.clone(), }; let mut test = NodeTest::new(); let text_node = NodeData::new("text"); let scripts = vec![ InsertNode { path: 0.into(), node_data: text_node, rev_id: 1, }, UpdateBody { path: 0.into(), changeset: changeset.clone(), }, AssertNodeDelta { path: 0.into(), expected: delta.clone(), }, UpdateBody { path: 0.into(), changeset: changeset.inverted(), }, AssertNodeDelta { path: 0.into(), expected: delta.compose(&inverted).unwrap(), }, ]; test.run_scripts(scripts); } #[test] fn operation_compose_multiple_delta_changeset_then_invert_test() { // delta 1 let delta_1 = DeltaTextOperationBuilder::new().insert("Hello world").build(); let inverted_1 = delta_1.inverted(); let changeset_1 = Changeset::Delta { delta: delta_1.clone(), inverted: inverted_1, }; // delta 2 let delta_2 = DeltaTextOperationBuilder::new() .retain(delta_1.utf16_target_len) .insert("!") .build(); let inverted_2 = delta_2.inverted(); let changeset_2 = Changeset::Delta { delta: delta_2.clone(), inverted: inverted_2, }; // delta 3 let delta_3 = DeltaTextOperationBuilder::new() .retain(delta_2.utf16_target_len) .insert("AppFlowy") .build(); let inverted_3 = delta_3.inverted(); let changeset_3 = Changeset::Delta { delta: delta_3.clone(), inverted: inverted_3, }; let mut test = NodeTest::new(); let text_node = NodeData::new("text"); let scripts = vec![ InsertNode { path: 0.into(), node_data: text_node, rev_id: 1, }, UpdateBody { path: 0.into(), changeset: changeset_1.clone(), }, UpdateBody { path: 0.into(), changeset: changeset_2.clone(), }, UpdateBody { path: 0.into(), changeset: changeset_3.clone(), }, AssertNodeDelta { path: 0.into(), expected: delta_1.compose(&delta_2).unwrap().compose(&delta_3).unwrap(), }, UpdateBody { path: 0.into(), changeset: changeset_3.inverted(), }, AssertNodeDeltaContent { path: 0.into(), expected: r#"Hello world!"#, }, UpdateBody { path: 0.into(), changeset: changeset_2.inverted(), }, AssertNodeDeltaContent { path: 0.into(), expected: r#"Hello world"#, }, UpdateBody { path: 0.into(), changeset: changeset_1.inverted(), }, AssertNodeDeltaContent { path: 0.into(), expected: r#""#, }, ]; test.run_scripts(scripts); } #[test] #[should_panic] fn changeset_delta_compose_attributes_test() { // delta 1 let delta = DeltaTextOperationBuilder::new().insert("Hello world").build(); let inverted = delta.inverted(); let mut delta_changeset = Changeset::Delta { delta, inverted }; // attributes let attribute_changeset = Changeset::Attributes { new: Default::default(), old: Default::default(), }; // compose delta_changeset.compose(&attribute_changeset).unwrap(); } #[test] fn changeset_attributes_compose_attributes_test() { // attributes let mut changeset_1 = Changeset::Attributes { new: AttributeEntry::new("bold", true).into(), old: Default::default(), }; let changeset_2 = Changeset::Attributes { new: AttributeEntry::new("Italic", true).into(), old: Default::default(), }; // compose changeset_1.compose(&changeset_2).unwrap(); if let Changeset::Attributes { new, old: _ } = changeset_1 { assert_eq!(new, AttributeEntry::new("Italic", true).into()); } }