Feat: add appflowy editor in backend (#1320)

* chore: remove update attributes

* chore: format code

* chore: extension for transaction

* refactor: add document editor trait

* chore: add appflowy_document editor

* chore: add document serde

* chore: add new document editor

* chore: add tests

* chore: add more test

* chore: add test

Co-authored-by: nathan <nathan@appflowy.io>
This commit is contained in:
Nathan.fooo
2022-10-20 11:35:11 +08:00
committed by GitHub
parent 833a6cd95f
commit f1a5726fcb
81 changed files with 2367 additions and 902 deletions

View File

@ -1,2 +0,0 @@
mod script;
mod text_block_test;

View File

@ -1,6 +1,6 @@
#![cfg_attr(rustfmt, rustfmt::skip)]
use crate::editor::{TestBuilder, TestOp::*};
use flowy_sync::client_document::{NewlineDoc, EmptyDoc};
use flowy_sync::client_document::{NewlineDocument, EmptyDocument};
use lib_ot::core::{Interval, OperationTransform, NEW_LINE, WHITESPACE, OTString};
use unicode_segmentation::UnicodeSegmentation;
use lib_ot::text_delta::TextOperations;
@ -19,7 +19,7 @@ fn attributes_bold_added() {
]"#,
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -31,7 +31,7 @@ fn attributes_bold_added_and_invert_all() {
Bold(0, Interval::new(0, 3), false),
AssertDocJson(0, r#"[{"insert":"123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -43,7 +43,7 @@ fn attributes_bold_added_and_invert_partial_suffix() {
Bold(0, Interval::new(2, 4), false),
AssertDocJson(0, r#"[{"insert":"12","attributes":{"bold":true}},{"insert":"34"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -57,7 +57,7 @@ fn attributes_bold_added_and_invert_partial_suffix2() {
Bold(0, Interval::new(2, 4), true),
AssertDocJson(0, r#"[{"insert":"1234","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -85,7 +85,7 @@ fn attributes_bold_added_with_new_line() {
r#"[{"insert":"123","attributes":{"bold":true}},{"insert":"\na\n"},{"insert":"456","attributes":{"bold":true}},{"insert":"\n"}]"#,
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -97,7 +97,7 @@ fn attributes_bold_added_and_invert_partial_prefix() {
Bold(0, Interval::new(0, 2), false),
AssertDocJson(0, r#"[{"insert":"12"},{"insert":"34","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -109,7 +109,7 @@ fn attributes_bold_added_consecutive() {
Bold(0, Interval::new(1, 2), true),
AssertDocJson(0, r#"[{"insert":"12","attributes":{"bold":true}},{"insert":"34"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -128,7 +128,7 @@ fn attributes_bold_added_italic() {
r#"[{"insert":"12345678","attributes":{"bold":true,"italic":true}},{"insert":"\n"}]"#,
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -156,7 +156,7 @@ fn attributes_bold_added_italic2() {
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -193,7 +193,7 @@ fn attributes_bold_added_italic3() {
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -229,7 +229,7 @@ fn attributes_bold_added_italic_delete() {
AssertDocJson(0, r#"[{"insert":"67"},{"insert":"89","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -240,7 +240,7 @@ fn attributes_merge_inserted_text_with_same_attribute() {
InsertBold(0, "456", Interval::new(3, 6)),
AssertDocJson(0, r#"[{"insert":"123456","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -255,7 +255,7 @@ fn attributes_compose_attr_attributes_with_attr_attributes_test() {
AssertDocJson(1, r#"[{"insert":"1234567","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -296,7 +296,7 @@ fn attributes_compose_attr_attributes_with_attr_attributes_test2() {
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -312,7 +312,7 @@ fn attributes_compose_attr_attributes_with_no_attr_attributes_test() {
AssertDocJson(0, expected),
AssertDocJson(1, expected),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -324,7 +324,7 @@ fn attributes_replace_heading() {
AssertDocJson(0, r#"[{"insert":"3456","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -336,7 +336,7 @@ fn attributes_replace_trailing() {
AssertDocJson(0, r#"[{"insert":"12345","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -350,7 +350,7 @@ fn attributes_replace_middle() {
AssertDocJson(0, r#"[{"insert":"34","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -362,7 +362,7 @@ fn attributes_replace_all() {
AssertDocJson(0, r#"[]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -374,7 +374,7 @@ fn attributes_replace_with_text() {
AssertDocJson(0, r#"[{"insert":"ab"},{"insert":"456","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -390,7 +390,7 @@ fn attributes_header_insert_newline_at_middle() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -415,7 +415,7 @@ fn attributes_header_insert_double_newline_at_middle() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -430,7 +430,7 @@ fn attributes_header_insert_newline_at_trailing() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -446,7 +446,7 @@ fn attributes_header_insert_double_newline_at_trailing() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -460,7 +460,7 @@ fn attributes_link_added() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -479,7 +479,7 @@ fn attributes_link_format_with_bold() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -498,7 +498,7 @@ fn attributes_link_insert_char_at_head() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -513,7 +513,7 @@ fn attributes_link_insert_char_at_middle() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -532,7 +532,7 @@ fn attributes_link_insert_char_at_trailing() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -547,7 +547,7 @@ fn attributes_link_insert_newline_at_middle() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -563,7 +563,7 @@ fn attributes_link_auto_format() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -579,7 +579,7 @@ fn attributes_link_auto_format_exist() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -595,7 +595,7 @@ fn attributes_link_auto_format_exist2() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -606,7 +606,7 @@ fn attributes_bullet_added() {
AssertDocJson(0, r#"[{"insert":"12"},{"insert":"\n","attributes":{"list":"bullet"}}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -627,7 +627,7 @@ fn attributes_bullet_added_2() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -644,7 +644,7 @@ fn attributes_bullet_remove_partial() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -660,7 +660,7 @@ fn attributes_bullet_auto_exit() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -700,7 +700,7 @@ fn attributes_preserve_block_when_insert_newline_inside() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -717,7 +717,7 @@ fn attributes_preserve_header_format_on_merge() {
AssertDocJson(0, r#"[{"insert":"123456"},{"insert":"\n","attributes":{"header":1}}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -737,7 +737,7 @@ fn attributes_format_emoji() {
r#"[{"insert":"👋 "},{"insert":"\n","attributes":{"header":1}}]"#,
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -757,7 +757,7 @@ fn attributes_preserve_list_format_on_merge() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -796,5 +796,5 @@ fn delta_compose() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}

View File

@ -1,6 +1,6 @@
#![allow(clippy::all)]
use crate::editor::{Rng, TestBuilder, TestOp::*};
use flowy_sync::client_document::{EmptyDoc, NewlineDoc};
use flowy_sync::client_document::{EmptyDocument, NewlineDocument};
use lib_ot::text_delta::TextOperationBuilder;
use lib_ot::{core::Interval, core::*, text_delta::TextOperations};
@ -11,7 +11,7 @@ fn attributes_insert_text() {
Insert(0, "456", 3),
AssertDocJson(0, r#"[{"insert":"123456"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -21,7 +21,7 @@ fn attributes_insert_text_at_head() {
Insert(0, "456", 0),
AssertDocJson(0, r#"[{"insert":"456123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -31,7 +31,7 @@ fn attributes_insert_text_at_middle() {
Insert(0, "456", 1),
AssertDocJson(0, r#"[{"insert":"145623"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -528,7 +528,7 @@ fn transform_two_plain_delta() {
AssertDocJson(0, r#"[{"insert":"123456"}]"#),
AssertDocJson(1, r#"[{"insert":"123456"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -542,7 +542,7 @@ fn transform_two_plain_delta2() {
AssertDocJson(0, r#"[{"insert":"123456"}]"#),
AssertDocJson(1, r#"[{"insert":"123456"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -560,7 +560,7 @@ fn transform_two_non_seq_delta() {
AssertDocJson(0, r#"[{"insert":"123456"}]"#),
AssertDocJson(1, r#"[{"insert":"123456789"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -575,7 +575,7 @@ fn transform_two_conflict_non_seq_delta() {
AssertDocJson(0, r#"[{"insert":"123456"}]"#),
AssertDocJson(1, r#"[{"insert":"12378456"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -602,7 +602,7 @@ fn delta_invert_no_attribute_delta2() {
Invert(0, 1),
AssertDocJson(0, r#"[{"insert":"123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -615,7 +615,7 @@ fn delta_invert_attribute_delta_with_no_attribute_delta() {
Invert(0, 1),
AssertDocJson(0, r#"[{"insert":"123","attributes":{"bold":true}}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -650,7 +650,7 @@ fn delta_invert_attribute_delta_with_no_attribute_delta2() {
]"#,
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -663,7 +663,7 @@ fn delta_invert_no_attribute_delta_with_attribute_delta() {
Invert(0, 1),
AssertDocJson(0, r#"[{"insert":"123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -682,7 +682,7 @@ fn delta_invert_no_attribute_delta_with_attribute_delta2() {
Invert(0, 1),
AssertDocJson(0, r#"[{"insert":"123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -723,7 +723,7 @@ fn delta_invert_attribute_delta_with_attribute_delta() {
]"#,
),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -733,7 +733,7 @@ fn delta_compose_str() {
Insert(0, "2", 1),
AssertDocJson(0, r#"[{"insert":"12\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -746,5 +746,5 @@ fn delta_compose_with_missing_delta() {
AssertDocJson(0, r#"[{"insert":"1234\n"}]"#),
AssertStr(1, r#"4\n"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}

View File

@ -1,4 +1,4 @@
use flowy_sync::client_document::{ClientDocument, EmptyDoc};
use flowy_sync::client_document::{ClientDocument, EmptyDocument};
use lib_ot::text_delta::TextOperation;
use lib_ot::{
core::*,
@ -101,7 +101,7 @@ fn delta_deserialize_null_test() {
#[test]
fn document_insert_serde_test() {
let mut document = ClientDocument::new::<EmptyDoc>();
let mut document = ClientDocument::new::<EmptyDocument>();
document.insert(0, "\n").unwrap();
document.insert(0, "123").unwrap();
let json = document.get_operations_json();

View File

@ -1,11 +1,11 @@
use crate::editor::{TestBuilder, TestOp::*};
use flowy_sync::client_document::{EmptyDoc, NewlineDoc, RECORD_THRESHOLD};
use flowy_sync::client_document::{EmptyDocument, NewlineDocument, RECORD_THRESHOLD};
use lib_ot::core::{Interval, NEW_LINE, WHITESPACE};
#[test]
fn history_insert_undo() {
let ops = vec![Insert(0, "123", 0), Undo(0), AssertDocJson(0, r#"[{"insert":"\n"}]"#)];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -19,7 +19,7 @@ fn history_insert_undo_with_lagging() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -32,7 +32,7 @@ fn history_insert_redo() {
Redo(0),
AssertDocJson(0, r#"[{"insert":"123\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -51,7 +51,7 @@ fn history_insert_redo_with_lagging() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"123\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -62,7 +62,7 @@ fn history_bold_undo() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -74,7 +74,7 @@ fn history_bold_undo_with_lagging() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"123\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -87,7 +87,7 @@ fn history_bold_redo() {
Redo(0),
AssertDocJson(0, r#" [{"insert":"123","attributes":{"bold":true}},{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -101,7 +101,7 @@ fn history_bold_redo_with_lagging() {
Redo(0),
AssertDocJson(0, r#"[{"insert":"123","attributes":{"bold":true}},{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -115,7 +115,7 @@ fn history_delete_undo() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"123"}]"#),
];
TestBuilder::new().run_scripts::<EmptyDoc>(ops);
TestBuilder::new().run_scripts::<EmptyDocument>(ops);
}
#[test]
@ -134,7 +134,7 @@ fn history_delete_undo_2() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -161,7 +161,7 @@ fn history_delete_undo_with_lagging() {
"#,
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -175,7 +175,7 @@ fn history_delete_redo() {
Redo(0),
AssertDocJson(0, r#"[{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -194,7 +194,7 @@ fn history_replace_undo() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -215,7 +215,7 @@ fn history_replace_undo_with_lagging() {
Undo(0),
AssertDocJson(0, r#"[{"insert":"123","attributes":{"bold":true}},{"insert":"\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -234,7 +234,7 @@ fn history_replace_redo() {
"#,
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -253,7 +253,7 @@ fn history_header_added_undo() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -272,7 +272,7 @@ fn history_link_added_undo() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -291,7 +291,7 @@ fn history_link_auto_format_undo_with_lagging() {
AssertDocJson(0, r#"[{"insert":"https://appflowy.io\n"}]"#),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -314,7 +314,7 @@ fn history_bullet_undo() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -342,7 +342,7 @@ fn history_bullet_undo_with_lagging() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}
#[test]
@ -369,5 +369,5 @@ fn history_undo_attribute_on_merge_between_line() {
),
];
TestBuilder::new().run_scripts::<NewlineDoc>(ops);
TestBuilder::new().run_scripts::<NewlineDocument>(ops);
}

View File

@ -1,2 +1,3 @@
mod document;
mod editor;
mod new_document;
mod old_document;

View File

@ -0,0 +1,2 @@
mod script;
mod test;

View File

@ -0,0 +1,84 @@
use flowy_document::editor::AppFlowyDocumentEditor;
use flowy_test::helper::ViewTest;
use flowy_test::FlowySDKTest;
use lib_ot::core::{Body, Changeset, NodeDataBuilder, NodeOperation, Path, Transaction};
use lib_ot::text_delta::TextOperations;
use std::sync::Arc;
pub enum EditScript {
InsertText { path: Path, delta: TextOperations },
UpdateText { path: Path, delta: TextOperations },
Delete { path: Path },
AssertContent { expected: &'static str },
AssertPrettyContent { expected: &'static str },
}
pub struct DocumentEditorTest {
pub sdk: FlowySDKTest,
pub editor: Arc<AppFlowyDocumentEditor>,
}
impl DocumentEditorTest {
pub async fn new() -> Self {
let sdk = FlowySDKTest::new(true);
let _ = sdk.init_user().await;
let test = ViewTest::new_document_view(&sdk).await;
let document_editor = sdk.document_manager.open_document_editor(&test.view.id).await.unwrap();
let editor = match document_editor.as_any().downcast_ref::<Arc<AppFlowyDocumentEditor>>() {
None => panic!(),
Some(editor) => editor.clone(),
};
Self { sdk, editor }
}
pub async fn run_scripts(&self, scripts: Vec<EditScript>) {
for script in scripts {
self.run_script(script).await;
}
}
async fn run_script(&self, script: EditScript) {
match script {
EditScript::InsertText { path, delta } => {
let node_data = NodeDataBuilder::new("text").insert_body(Body::Delta(delta)).build();
let operation = NodeOperation::Insert {
path,
nodes: vec![node_data],
};
self.editor
.apply_transaction(Transaction::from_operations(vec![operation]))
.await
.unwrap();
}
EditScript::UpdateText { path, delta } => {
let inverted = delta.invert_str("");
let changeset = Changeset::Delta { delta, inverted };
let operation = NodeOperation::Update { path, changeset };
self.editor
.apply_transaction(Transaction::from_operations(vec![operation]))
.await
.unwrap();
}
EditScript::Delete { path } => {
let operation = NodeOperation::Delete { path, nodes: vec![] };
self.editor
.apply_transaction(Transaction::from_operations(vec![operation]))
.await
.unwrap();
}
EditScript::AssertContent { expected } => {
//
let content = self.editor.get_content(false).await.unwrap();
assert_eq!(content, expected);
}
EditScript::AssertPrettyContent { expected } => {
//
let content = self.editor.get_content(true).await.unwrap();
assert_eq!(content, expected);
}
}
}
}

View File

@ -0,0 +1,156 @@
use crate::new_document::script::DocumentEditorTest;
use crate::new_document::script::EditScript::*;
use lib_ot::text_delta::TextOperationBuilder;
#[tokio::test]
async fn document_initialize_test() {
let scripts = vec![AssertContent {
expected: r#"{"document":{"type":"editor","children":[{"type":"text"}]}}"#,
}];
DocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn document_insert_text_test() {
let delta = TextOperationBuilder::new().insert("Hello world").build();
let expected = r#"{
"document": {
"type": "editor",
"children": [
{
"type": "text",
"delta": [
{
"insert": "Hello world"
}
]
},
{
"type": "text"
}
]
}
}"#;
let scripts = vec![
InsertText {
path: vec![0, 0].into(),
delta,
},
AssertPrettyContent { expected },
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn document_update_text_test() {
let test = DocumentEditorTest::new().await;
let hello_world = "Hello world".to_string();
let scripts = vec![
UpdateText {
path: vec![0, 0].into(),
delta: TextOperationBuilder::new().insert(&hello_world).build(),
},
AssertPrettyContent {
expected: r#"{
"document": {
"type": "editor",
"children": [
{
"type": "text",
"delta": [
{
"insert": "Hello world"
}
]
}
]
}
}"#,
},
];
test.run_scripts(scripts).await;
let scripts = vec![
UpdateText {
path: vec![0, 0].into(),
delta: TextOperationBuilder::new()
.retain(hello_world.len())
.insert(", AppFlowy")
.build(),
},
AssertPrettyContent {
expected: r#"{
"document": {
"type": "editor",
"children": [
{
"type": "text",
"delta": [
{
"insert": "Hello world, AppFlowy"
}
]
}
]
}
}"#,
},
];
test.run_scripts(scripts).await;
}
#[tokio::test]
async fn document_delete_text_test() {
let expected = r#"{
"document": {
"type": "editor",
"children": [
{
"type": "text",
"delta": [
{
"insert": "Hello"
}
]
}
]
}
}"#;
let hello_world = "Hello world".to_string();
let scripts = vec![
UpdateText {
path: vec![0, 0].into(),
delta: TextOperationBuilder::new().insert(&hello_world).build(),
},
UpdateText {
path: vec![0, 0].into(),
delta: TextOperationBuilder::new().retain(5).delete(6).build(),
},
AssertPrettyContent { expected },
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn document_delete_node_test() {
let scripts = vec![
UpdateText {
path: vec![0, 0].into(),
delta: TextOperationBuilder::new().insert("Hello world").build(),
},
AssertContent {
expected: r#"{"document":{"type":"editor","children":[{"type":"text","delta":[{"insert":"Hello world"}]}]}}"#,
},
Delete {
path: vec![0, 0].into(),
},
AssertContent {
expected: r#"{"document":{"type":"editor"}}"#,
},
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
}

View File

@ -0,0 +1,2 @@
mod old_document_test;
mod script;

View File

@ -1,4 +1,4 @@
use crate::document::script::{EditorScript::*, *};
use crate::old_document::script::{EditorScript::*, *};
use flowy_revision::disk::RevisionState;
use lib_ot::core::{count_utf16_code_units, Interval};
@ -14,7 +14,7 @@ async fn text_block_sync_current_rev_id_check() {
AssertNextSyncRevId(None),
AssertJson(r#"[{"insert":"123\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -28,7 +28,7 @@ async fn text_block_sync_state_check() {
AssertRevisionState(3, RevisionState::Ack),
AssertJson(r#"[{"insert":"123\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -40,7 +40,7 @@ async fn text_block_sync_insert_test() {
AssertJson(r#"[{"insert":"123\n"}]"#),
AssertNextSyncRevId(None),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -52,7 +52,7 @@ async fn text_block_sync_insert_in_chinese() {
InsertText("", offset),
AssertJson(r#"[{"insert":"你好\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -64,7 +64,7 @@ async fn text_block_sync_insert_with_emoji() {
InsertText("☺️", offset),
AssertJson(r#"[{"insert":"😁☺️\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -76,7 +76,7 @@ async fn text_block_sync_delete_in_english() {
Delete(Interval::new(0, 2)),
AssertJson(r#"[{"insert":"3\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -89,7 +89,7 @@ async fn text_block_sync_delete_in_chinese() {
Delete(Interval::new(0, offset)),
AssertJson(r#"[{"insert":"好\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
@ -101,5 +101,5 @@ async fn text_block_sync_replace_test() {
Replace(Interval::new(0, 3), "abc"),
AssertJson(r#"[{"insert":"abc\n"}]"#),
];
DocumentEditorTest::new().await.run_scripts(scripts).await;
OldDocumentEditorTest::new().await.run_scripts(scripts).await;
}

View File

@ -1,4 +1,4 @@
use flowy_document::editor::DocumentEditor;
use flowy_document::old_editor::editor::OldDocumentEditor;
use flowy_document::TEXT_BLOCK_SYNC_INTERVAL_IN_MILLIS;
use flowy_revision::disk::RevisionState;
use flowy_test::{helper::ViewTest, FlowySDKTest};
@ -17,21 +17,21 @@ pub enum EditorScript {
AssertJson(&'static str),
}
pub struct DocumentEditorTest {
pub struct OldDocumentEditorTest {
pub sdk: FlowySDKTest,
pub editor: Arc<DocumentEditor>,
pub editor: Arc<OldDocumentEditor>,
}
impl DocumentEditorTest {
impl OldDocumentEditorTest {
pub async fn new() -> Self {
let sdk = FlowySDKTest::default();
let _ = sdk.init_user().await;
let test = ViewTest::new_text_block_view(&sdk).await;
let editor = sdk
.text_block_manager
.open_document_editor(&test.view.id)
.await
.unwrap();
let test = ViewTest::new_document_view(&sdk).await;
let document_editor = sdk.document_manager.open_document_editor(&test.view.id).await.unwrap();
let editor = match document_editor.as_any().downcast_ref::<Arc<OldDocumentEditor>>() {
None => panic!(),
Some(editor) => editor.clone(),
};
Self { sdk, editor }
}