Browse Source

fix: inverted delta not equal to the old delta

appflowy 3 years ago
parent
commit
b322f40ff7

+ 2 - 1
rust-lib/flowy-ot/src/core/attributes.rs

@@ -161,6 +161,7 @@ pub fn compose_attributes(left: &Option<Operation>, right: &Option<Operation>) -
             Some(_) => attr_l.unwrap().extend(attr_r.clone()),
         },
         (Some(Attributes::Custom(_)), _) => attr_l.unwrap().extend(attr_r),
+        (Some(Attributes::Follow), Some(Attributes::Follow)) => Attributes::Follow,
         _ => Attributes::Empty,
     };
 
@@ -186,7 +187,7 @@ pub fn transform_attributes(
         }
 
         return match attr_r.as_ref().unwrap() {
-            Attributes::Follow => Attributes::Empty,
+            Attributes::Follow => Attributes::Follow,
             Attributes::Custom(_) => attr_r.unwrap(),
             Attributes::Empty => Attributes::Empty,
         };

+ 2 - 5
rust-lib/flowy-ot/src/core/delta.rs

@@ -161,10 +161,7 @@ impl Delta {
                     next_op1 = ops1.next();
                 },
                 (_, Some(Operation::Insert(o_insert))) => {
-                    new_delta.insert(
-                        &o_insert.s,
-                        attributes_from(&next_op2).unwrap_or(Attributes::Empty),
-                    );
+                    new_delta.insert(&o_insert.s, o_insert.attributes.clone());
                     next_op2 = ops2.next();
                 },
                 (None, _) | (_, None) => {
@@ -502,7 +499,7 @@ impl Delta {
                 },
                 Operation::Retain(_) => {
                     if op.is_plain() {
-                        inverted.retain(op_len as u64, Attributes::Empty);
+                        inverted.retain(op_len as u64, op.get_attributes());
                     } else {
                         a(&mut inverted, op, index, op_len as usize);
                     }

+ 2 - 1
rust-lib/flowy-ot/tests/attribute_test.rs

@@ -283,7 +283,8 @@ fn delta_compose_attr_delta_with_attr_delta_test2() {
 
 #[test]
 fn delta_compose_attr_delta_with_no_attr_delta_test() {
-    let expected = r#"[{"insert":"123456","attributes":{"bold":"true"}},{"insert":"7"}]"#;
+    let expected = r#"[{"insert":"1234567","attributes":{"bold":"true"}}]"#;
+
     let ops = vec![
         InsertBold(0, "123456", Interval::new(0, 6)),
         AssertOpsJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),

+ 15 - 0
rust-lib/flowy-ot/tests/helper/mod.rs

@@ -12,6 +12,8 @@ pub enum TestOp {
     Delete(usize, Interval),
     Italic(usize, Interval, bool),
     Transform(usize, usize),
+    // invert the delta_a base on the delta_b
+    Invert(usize, usize),
     AssertStr(usize, &'static str),
     AssertOpsJson(usize, &'static str),
 }
@@ -70,6 +72,19 @@ impl OpTester {
                 self.deltas[*delta_a_i] = new_delta_a;
                 self.deltas[*delta_b_i] = new_delta_b;
             },
+            TestOp::Invert(delta_a_i, delta_b_i) => {
+                let delta_a = &self.deltas[*delta_a_i];
+                let delta_b = &self.deltas[*delta_b_i];
+
+                let (_, b_prime) = delta_a.transform(delta_b).unwrap();
+                let undo = b_prime.invert_delta(&delta_a);
+                let new_delta = delta_a.compose(&b_prime).unwrap();
+                let new_delta_after_undo = new_delta.compose(&undo).unwrap();
+
+                assert_eq!(delta_a, &new_delta_after_undo);
+
+                self.deltas[*delta_a_i] = new_delta_after_undo;
+            },
             TestOp::AssertStr(delta_i, expected) => {
                 let s = self.deltas[*delta_i].apply("").unwrap();
                 assert_eq!(&s, expected);

+ 11 - 0
rust-lib/flowy-ot/tests/invert_test.rs

@@ -18,6 +18,17 @@ fn delta_invert_delta_test() {
     assert_eq!(delta_after_undo, delta);
 }
 
+#[test]
+fn delta_invert_delta_test2() {
+    let ops = vec![
+        Insert(0, "1234", 0),
+        Insert(1, "4567", 0),
+        Invert(0, 1),
+        AssertOpsJson(0, r#"[{"insert":"1234"}]"#),
+    ];
+    OpTester::new().run_script(ops);
+}
+
 #[test]
 fn delta_get_ops_in_interval_1() {
     let mut delta = Delta::default();