2022-10-29 12:54:11 +00:00
|
|
|
use crate::node::script::{edit_node_delta, make_node_delta_changeset};
|
2023-02-13 01:29:49 +00:00
|
|
|
use lib_ot::core::{
|
|
|
|
AttributeEntry, Changeset, NodeDataBuilder, NodeOperation, Transaction, TransactionBuilder,
|
|
|
|
};
|
2022-10-29 12:54:11 +00:00
|
|
|
use lib_ot::text_delta::DeltaTextOperationBuilder;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn transaction_compose_update_after_insert_test() {
|
2023-02-13 01:29:49 +00:00
|
|
|
let (initial_delta, changeset, _) = make_node_delta_changeset("Hello", " world");
|
|
|
|
let node_data = NodeDataBuilder::new("text")
|
|
|
|
.insert_delta(initial_delta)
|
|
|
|
.build();
|
|
|
|
|
|
|
|
// Modify the same path, the operations will be merged after composing if possible.
|
|
|
|
let mut transaction_a = TransactionBuilder::new()
|
|
|
|
.insert_node_at_path(0, node_data)
|
|
|
|
.build();
|
|
|
|
let transaction_b = TransactionBuilder::new()
|
|
|
|
.update_node_at_path(0, changeset)
|
|
|
|
.build();
|
|
|
|
transaction_a.compose(transaction_b).unwrap();
|
|
|
|
|
|
|
|
// The operations are merged into one operation
|
|
|
|
assert_eq!(transaction_a.operations.len(), 1);
|
|
|
|
assert_eq!(
|
|
|
|
transaction_a.to_json().unwrap(),
|
|
|
|
r#"{"operations":[{"op":"insert","path":[0],"nodes":[{"type":"text","body":{"delta":[{"insert":"Hello world"}]}}]}]}"#
|
|
|
|
);
|
2022-10-29 12:54:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn transaction_compose_multiple_update_test() {
|
2023-02-13 01:29:49 +00:00
|
|
|
let (initial_delta, changeset_1, final_delta) = make_node_delta_changeset("Hello", " world");
|
|
|
|
let mut transaction = TransactionBuilder::new()
|
|
|
|
.insert_node_at_path(
|
|
|
|
0,
|
|
|
|
NodeDataBuilder::new("text")
|
|
|
|
.insert_delta(initial_delta)
|
|
|
|
.build(),
|
|
|
|
)
|
|
|
|
.build();
|
|
|
|
let (changeset_2, _) = edit_node_delta(
|
|
|
|
&final_delta,
|
|
|
|
DeltaTextOperationBuilder::new()
|
|
|
|
.retain(final_delta.utf16_target_len)
|
|
|
|
.insert("😁")
|
|
|
|
.build(),
|
|
|
|
);
|
|
|
|
|
|
|
|
let mut other_transaction = Transaction::new();
|
|
|
|
|
|
|
|
// the following two update operations will be merged into one
|
|
|
|
let update_1 = TransactionBuilder::new()
|
|
|
|
.update_node_at_path(0, changeset_1)
|
|
|
|
.build();
|
|
|
|
other_transaction.compose(update_1).unwrap();
|
|
|
|
|
|
|
|
let update_2 = TransactionBuilder::new()
|
|
|
|
.update_node_at_path(0, changeset_2)
|
|
|
|
.build();
|
|
|
|
other_transaction.compose(update_2).unwrap();
|
|
|
|
|
|
|
|
let inverted = Transaction::from_operations(other_transaction.operations.inverted());
|
|
|
|
|
|
|
|
// the update operation will be merged into insert operation
|
|
|
|
transaction.compose(other_transaction).unwrap();
|
|
|
|
assert_eq!(transaction.operations.len(), 1);
|
|
|
|
assert_eq!(
|
|
|
|
transaction.to_json().unwrap(),
|
|
|
|
r#"{"operations":[{"op":"insert","path":[0],"nodes":[{"type":"text","body":{"delta":[{"insert":"Hello world😁"}]}}]}]}"#
|
|
|
|
);
|
|
|
|
|
|
|
|
transaction.compose(inverted).unwrap();
|
|
|
|
assert_eq!(
|
|
|
|
transaction.to_json().unwrap(),
|
|
|
|
r#"{"operations":[{"op":"insert","path":[0],"nodes":[{"type":"text","body":{"delta":[{"insert":"Hello"}]}}]}]}"#
|
|
|
|
);
|
2022-10-29 12:54:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn transaction_compose_multiple_attribute_test() {
|
2023-02-13 01:29:49 +00:00
|
|
|
let delta = DeltaTextOperationBuilder::new().insert("Hello").build();
|
|
|
|
let node = NodeDataBuilder::new("text").insert_delta(delta).build();
|
|
|
|
|
|
|
|
let insert_operation = NodeOperation::Insert {
|
|
|
|
path: 0.into(),
|
|
|
|
nodes: vec![node],
|
|
|
|
};
|
|
|
|
|
|
|
|
let mut transaction = Transaction::new();
|
|
|
|
transaction.push_operation(insert_operation);
|
|
|
|
|
|
|
|
let new_attribute = AttributeEntry::new("subtype", "bulleted-list");
|
|
|
|
let update_operation = NodeOperation::Update {
|
|
|
|
path: 0.into(),
|
|
|
|
changeset: Changeset::Attributes {
|
|
|
|
new: new_attribute.clone().into(),
|
|
|
|
old: Default::default(),
|
|
|
|
},
|
|
|
|
};
|
|
|
|
transaction.push_operation(update_operation);
|
|
|
|
assert_eq!(
|
|
|
|
transaction.to_json().unwrap(),
|
|
|
|
r#"{"operations":[{"op":"insert","path":[0],"nodes":[{"type":"text","body":{"delta":[{"insert":"Hello"}]}}]},{"op":"update","path":[0],"changeset":{"attributes":{"new":{"subtype":"bulleted-list"},"old":{}}}}]}"#
|
|
|
|
);
|
|
|
|
|
|
|
|
let old_attribute = new_attribute;
|
|
|
|
let new_attribute = AttributeEntry::new("subtype", "number-list");
|
|
|
|
transaction.push_operation(NodeOperation::Update {
|
|
|
|
path: 0.into(),
|
|
|
|
changeset: Changeset::Attributes {
|
|
|
|
new: new_attribute.into(),
|
|
|
|
old: old_attribute.into(),
|
|
|
|
},
|
|
|
|
});
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
transaction.to_json().unwrap(),
|
|
|
|
r#"{"operations":[{"op":"insert","path":[0],"nodes":[{"type":"text","body":{"delta":[{"insert":"Hello"}]}}]},{"op":"update","path":[0],"changeset":{"attributes":{"new":{"subtype":"number-list"},"old":{"subtype":"bulleted-list"}}}}]}"#
|
|
|
|
);
|
2022-10-29 12:54:11 +00:00
|
|
|
}
|