Browse Source

customize Document initialization with CustomDocument Trait

appflowy 3 years ago
parent
commit
30a7149764

+ 15 - 4
rust-lib/flowy-ot/src/client/document/document.rs

@@ -8,6 +8,20 @@ pub trait DocumentData {
     fn into_string(self) -> Result<String, OTError>;
 }
 
+pub trait CustomDocument {
+    fn init_delta() -> Delta;
+}
+
+pub struct PlainDoc();
+impl CustomDocument for PlainDoc {
+    fn init_delta() -> Delta { Delta::new() }
+}
+
+pub struct FlowyDoc();
+impl CustomDocument for FlowyDoc {
+    fn init_delta() -> Delta { DeltaBuilder::new().insert("\n").build() }
+}
+
 pub struct Document {
     delta: Delta,
     history: History,
@@ -17,10 +31,7 @@ pub struct Document {
 }
 
 impl Document {
-    pub fn new() -> Self {
-        let delta = Delta::new();
-        Self::from_delta(delta)
-    }
+    pub fn new<C: CustomDocument>() -> Self { Self::from_delta(C::init_delta()) }
 
     pub fn from_delta(delta: Delta) -> Self {
         Document {

+ 9 - 8
rust-lib/flowy-ot/src/core/attributes/attribute.rs

@@ -1,5 +1,5 @@
 #![allow(non_snake_case)]
-use crate::core::{Attributes, REMOVE_FLAG};
+use crate::core::Attributes;
 use derive_more::Display;
 use lazy_static::lazy_static;
 use std::{collections::HashSet, fmt, fmt::Formatter, iter::FromIterator};
@@ -96,6 +96,7 @@ pub struct Attribute {
 }
 
 impl Attribute {
+    // inline
     inline_attribute!(Bold, bool);
     inline_attribute!(Italic, bool);
     inline_attribute!(Underline, bool);
@@ -106,6 +107,7 @@ impl Attribute {
     inline_attribute!(Size, usize);
     inline_attribute!(Background, String);
 
+    // block
     block_attribute!(Header, usize);
     block_attribute!(LeftAlignment, usize);
     block_attribute!(CenterAlignment, usize);
@@ -121,6 +123,7 @@ impl Attribute {
     block_attribute!(UnChecked, bool);
     block_attribute!(QuoteBlock, bool);
 
+    // ignore
     ignore_attribute!(Width, usize);
     ignore_attribute!(Height, usize);
 }
@@ -203,13 +206,7 @@ impl AsRef<str> for AttributeValue {
 }
 
 impl std::convert::From<&usize> for AttributeValue {
-    fn from(val: &usize) -> Self {
-        if *val > (0 as usize) {
-            AttributeValue(format!("{}", val))
-        } else {
-            AttributeValue(format!(""))
-        }
-    }
+    fn from(val: &usize) -> Self { AttributeValue::from(*val) }
 }
 
 impl std::convert::From<usize> for AttributeValue {
@@ -230,6 +227,10 @@ impl std::convert::From<String> for AttributeValue {
     fn from(val: String) -> Self { AttributeValue(val) }
 }
 
+impl std::convert::From<&bool> for AttributeValue {
+    fn from(val: &bool) -> Self { AttributeValue::from(*val) }
+}
+
 impl std::convert::From<bool> for AttributeValue {
     fn from(val: bool) -> Self {
         let val = match val {

+ 44 - 41
rust-lib/flowy-ot/tests/attribute_test.rs

@@ -1,7 +1,10 @@
 pub mod helper;
 
 use crate::helper::{TestOp::*, *};
-use flowy_ot::core::{Interval, NEW_LINE, WHITESPACE};
+use flowy_ot::{
+    client::{FlowyDoc, PlainDoc},
+    core::{Interval, NEW_LINE, WHITESPACE},
+};
 
 #[test]
 fn attributes_bold_added() {
@@ -17,7 +20,7 @@ fn attributes_bold_added() {
             ]"#,
         ),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -29,7 +32,7 @@ fn attributes_bold_added_and_invert_all() {
         Bold(0, Interval::new(0, 3), false),
         AssertOpsJson(0, r#"[{"insert":"123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -41,7 +44,7 @@ fn attributes_bold_added_and_invert_partial_suffix() {
         Bold(0, Interval::new(2, 4), false),
         AssertOpsJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -55,7 +58,7 @@ fn attributes_bold_added_and_invert_partial_suffix2() {
         Bold(0, Interval::new(2, 4), true),
         AssertOpsJson(0, r#"[{"insert":"1234","attributes":{"bold":"true"}}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -80,7 +83,7 @@ fn attributes_bold_added_with_new_line() {
             r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\na\n"},{"insert":"456","attributes":{"bold":"true"}},{"insert":"\n"}]"#,
         ),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -92,7 +95,7 @@ fn attributes_bold_added_and_invert_partial_prefix() {
         Bold(0, Interval::new(0, 2), false),
         AssertOpsJson(0, r#"[{"insert":"12"},{"insert":"34","attributes":{"bold":"true"}}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -104,7 +107,7 @@ fn attributes_bold_added_consecutive() {
         Bold(0, Interval::new(1, 2), true),
         AssertOpsJson(0, r#"[{"insert":"12","attributes":{"bold":"true"}},{"insert":"34"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -123,7 +126,7 @@ fn attributes_bold_added_italic() {
             r#"[{"insert":"12345678","attributes":{"bold":"true","italic":"true"}},{"insert":"\n"}]"#,
         ),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -151,7 +154,7 @@ fn attributes_bold_added_italic2() {
         ),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -188,7 +191,7 @@ fn attributes_bold_added_italic3() {
         ),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -224,7 +227,7 @@ fn attributes_bold_added_italic_delete() {
         AssertOpsJson(0, r#"[{"insert":"67"},{"insert":"89","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -235,7 +238,7 @@ fn attributes_merge_inserted_text_with_same_attribute() {
         InsertBold(0, "456", Interval::new(3, 6)),
         AssertOpsJson(0, r#"[{"insert":"123456","attributes":{"bold":"true"}}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -250,7 +253,7 @@ fn attributes_compose_attr_attributes_with_attr_attributes_test() {
         AssertOpsJson(1, r#"[{"insert":"1234567","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -291,7 +294,7 @@ fn attributes_compose_attr_attributes_with_attr_attributes_test2() {
         ),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -307,7 +310,7 @@ fn attributes_compose_attr_attributes_with_no_attr_attributes_test() {
         AssertOpsJson(0, expected),
         AssertOpsJson(1, expected),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -319,7 +322,7 @@ fn attributes_replace_heading() {
         AssertOpsJson(0, r#"[{"insert":"3456","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -331,7 +334,7 @@ fn attributes_replace_trailing() {
         AssertOpsJson(0, r#"[{"insert":"12345","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -345,7 +348,7 @@ fn attributes_replace_middle() {
         AssertOpsJson(0, r#"[{"insert":"34","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -357,7 +360,7 @@ fn attributes_replace_all() {
         AssertOpsJson(0, r#"[]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -369,7 +372,7 @@ fn attributes_replace_with_text() {
         AssertOpsJson(0, r#"[{"insert":"ab"},{"insert":"456","attributes":{"bold":"true"}}]"#),
     ];
 
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -385,7 +388,7 @@ fn attributes_header_insert_newline_at_middle() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -410,7 +413,7 @@ fn attributes_header_insert_double_newline_at_middle() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -425,7 +428,7 @@ fn attributes_header_insert_newline_at_trailing() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -441,7 +444,7 @@ fn attributes_header_insert_double_newline_at_trailing() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -455,7 +458,7 @@ fn attributes_link_added() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -474,7 +477,7 @@ fn attributes_link_format_with_bold() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -493,7 +496,7 @@ fn attributes_link_insert_char_at_head() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -508,7 +511,7 @@ fn attributes_link_insert_char_at_middle() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -527,7 +530,7 @@ fn attributes_link_insert_char_at_trailing() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -542,7 +545,7 @@ fn attributes_link_insert_newline_at_middle() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -558,7 +561,7 @@ fn attributes_link_auto_format() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -574,7 +577,7 @@ fn attributes_link_auto_format_exist() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -590,7 +593,7 @@ fn attributes_link_auto_format_exist2() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -601,7 +604,7 @@ fn attributes_bullet_added() {
         AssertOpsJson(0, r#"[{"insert":"12"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -619,7 +622,7 @@ fn attributes_bullet_added_2() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -636,7 +639,7 @@ fn attributes_bullet_remove_partial() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -652,7 +655,7 @@ fn attributes_bullet_auto_exit() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -689,7 +692,7 @@ fn attributes_preserve_block_when_insert_newline_inside() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -706,7 +709,7 @@ fn attributes_preserve_header_format_on_merge() {
         AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":"1"}}]"#),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -723,5 +726,5 @@ fn attributes_preserve_list_format_on_merge() {
         AssertOpsJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"bullet":"true"}}]"#),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }

+ 9 - 21
rust-lib/flowy-ot/tests/helper/mod.rs

@@ -1,5 +1,8 @@
 use derive_more::Display;
-use flowy_ot::{client::Document, core::*};
+use flowy_ot::{
+    client::{CustomDocument, Document},
+    core::*,
+};
 use rand::{prelude::*, Rng as WrappedRng};
 use std::{sync::Once, time::Duration};
 
@@ -59,11 +62,11 @@ pub enum TestOp {
     AssertOpsJson(usize, &'static str),
 }
 
-pub struct OpTester {
+pub struct TestBuilder {
     documents: Vec<Document>,
 }
 
-impl OpTester {
+impl TestBuilder {
     pub fn new() -> Self {
         static INIT: Once = Once::new();
         INIT.call_once(|| {
@@ -75,7 +78,7 @@ impl OpTester {
         Self { documents: vec![] }
     }
 
-    pub fn run_op(&mut self, op: &TestOp) {
+    fn run_op(&mut self, op: &TestOp) {
         log::debug!("***************** 😈{} *******************", &op);
         match op {
             TestOp::Insert(delta_i, s, index) => {
@@ -186,23 +189,8 @@ impl OpTester {
         }
     }
 
-    pub fn run_script(&mut self, script: Vec<TestOp>) {
-        let delta = Delta::new();
-        self.run(script, delta);
-    }
-
-    pub fn run_script_with_newline(&mut self, script: Vec<TestOp>) {
-        let mut delta = Delta::new();
-        delta.insert("\n", Attributes::default());
-        self.run(script, delta);
-    }
-
-    fn run(&mut self, script: Vec<TestOp>, delta: Delta) {
-        let mut documents = Vec::with_capacity(2);
-        for _ in 0..2 {
-            documents.push(Document::from_delta(delta.clone()));
-        }
-        self.documents = documents;
+    pub fn run_script<C: CustomDocument>(mut self, script: Vec<TestOp>) {
+        self.documents = vec![Document::new::<C>(), Document::new::<C>()];
         for (_i, op) in script.iter().enumerate() {
             self.run_op(op);
         }

+ 11 - 11
rust-lib/flowy-ot/tests/op_test.rs

@@ -2,7 +2,7 @@ pub mod helper;
 
 use crate::helper::TestOp::*;
 use bytecount::num_chars;
-use flowy_ot::core::*;
+use flowy_ot::{client::PlainDoc, core::*};
 use helper::*;
 
 #[test]
@@ -12,7 +12,7 @@ fn attributes_insert_text() {
         Insert(0, "456", 3),
         AssertOpsJson(0, r#"[{"insert":"123456"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -22,7 +22,7 @@ fn attributes_insert_text_at_head() {
         Insert(0, "456", 0),
         AssertOpsJson(0, r#"[{"insert":"456123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -32,7 +32,7 @@ fn attributes_insert_text_at_middle() {
         Insert(0, "456", 1),
         AssertOpsJson(0, r#"[{"insert":"145623"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -471,7 +471,7 @@ fn transform2() {
         AssertOpsJson(0, r#"[{"insert":"123456"}]"#),
         AssertOpsJson(1, r#"[{"insert":"123456"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -523,7 +523,7 @@ fn delta_invert_no_attribute_delta2() {
         Invert(0, 1),
         AssertOpsJson(0, r#"[{"insert":"123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -536,7 +536,7 @@ fn delta_invert_attribute_delta_with_no_attribute_delta() {
         Invert(0, 1),
         AssertOpsJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -571,7 +571,7 @@ fn delta_invert_attribute_delta_with_no_attribute_delta2() {
             ]"#,
         ),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -584,7 +584,7 @@ fn delta_invert_no_attribute_delta_with_attribute_delta() {
         Invert(0, 1),
         AssertOpsJson(0, r#"[{"insert":"123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -605,7 +605,7 @@ fn delta_invert_no_attribute_delta_with_attribute_delta2() {
         Invert(0, 1),
         AssertOpsJson(0, r#"[{"insert":"123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -646,5 +646,5 @@ fn delta_invert_attribute_delta_with_attribute_delta() {
             ]"#,
         ),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }

+ 5 - 2
rust-lib/flowy-ot/tests/serde_test.rs

@@ -1,4 +1,7 @@
-use flowy_ot::{client::Document, core::*};
+use flowy_ot::{
+    client::{Document, PlainDoc},
+    core::*,
+};
 
 #[test]
 fn operation_insert_serialize_test() {
@@ -54,7 +57,7 @@ fn delta_serialize_test() {
 
 #[test]
 fn document_insert_serde_test() {
-    let mut document = Document::new();
+    let mut document = Document::new::<PlainDoc>();
     document.insert(0, "\n");
     document.insert(0, "123");
     let json = document.to_json();

+ 22 - 22
rust-lib/flowy-ot/tests/undo_redo_test.rs

@@ -2,14 +2,14 @@ pub mod helper;
 
 use crate::helper::{TestOp::*, *};
 use flowy_ot::{
-    client::RECORD_THRESHOLD,
+    client::{FlowyDoc, PlainDoc, RECORD_THRESHOLD},
     core::{Interval, NEW_LINE, WHITESPACE},
 };
 
 #[test]
 fn history_insert_undo() {
     let ops = vec![Insert(0, "123", 0), Undo(0), AssertOpsJson(0, r#"[{"insert":"\n"}]"#)];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -23,7 +23,7 @@ fn history_insert_undo_with_lagging() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -36,7 +36,7 @@ fn history_insert_redo() {
         Redo(0),
         AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -55,7 +55,7 @@ fn history_insert_redo_with_lagging() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -66,7 +66,7 @@ fn history_bold_undo() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -78,7 +78,7 @@ fn history_bold_undo_with_lagging() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"123\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -91,7 +91,7 @@ fn history_bold_redo() {
         Redo(0),
         AssertOpsJson(0, r#" [{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -105,7 +105,7 @@ fn history_bold_redo_with_lagging() {
         Redo(0),
         AssertOpsJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -118,7 +118,7 @@ fn history_delete_undo() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"123"}]"#),
     ];
-    OpTester::new().run_script(ops);
+    TestBuilder::new().run_script::<PlainDoc>(ops);
 }
 
 #[test]
@@ -137,7 +137,7 @@ fn history_delete_undo_2() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -164,7 +164,7 @@ fn history_delete_undo_with_lagging() {
             "#,
         ),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -178,7 +178,7 @@ fn history_delete_redo() {
         Redo(0),
         AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -197,7 +197,7 @@ fn history_replace_undo() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -218,7 +218,7 @@ fn history_replace_undo_with_lagging() {
         Undo(0),
         AssertOpsJson(0, r#"[{"insert":"123","attributes":{"bold":"true"}},{"insert":"\n"}]"#),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -237,7 +237,7 @@ fn history_replace_redo() {
             "#,
         ),
     ];
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -256,7 +256,7 @@ fn history_header_added_undo() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -275,7 +275,7 @@ fn history_link_added_undo() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -294,7 +294,7 @@ fn history_link_auto_format_undo_with_lagging() {
         AssertOpsJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -317,7 +317,7 @@ fn history_bullet_undo() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -345,7 +345,7 @@ fn history_bullet_undo_with_lagging() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }
 
 #[test]
@@ -369,5 +369,5 @@ fn history_undo_attribute_on_merge_between_line() {
         ),
     ];
 
-    OpTester::new().run_script_with_newline(ops);
+    TestBuilder::new().run_script::<FlowyDoc>(ops);
 }