mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
1. rename flowy_str functions
2. mv the document_test to flowy_document crate
This commit is contained in:
@ -0,0 +1,68 @@
|
||||
use crate::document::edit_script::{EditorScript::*, *};
|
||||
use flowy_collaboration::entities::revision::RevisionState;
|
||||
use lib_ot::core::{count_utf16_code_units, Interval};
|
||||
|
||||
#[tokio::test]
|
||||
async fn document_sync_current_rev_id_check() {
|
||||
let scripts = vec![
|
||||
InsertText("1", 0),
|
||||
AssertCurrentRevId(1),
|
||||
InsertText("2", 1),
|
||||
AssertCurrentRevId(2),
|
||||
InsertText("3", 2),
|
||||
AssertCurrentRevId(3),
|
||||
AssertNextRevId(None),
|
||||
AssertJson(r#"[{"insert":"123\n"}]"#),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn document_sync_state_check() {
|
||||
let scripts = vec![
|
||||
InsertText("1", 0),
|
||||
InsertText("2", 1),
|
||||
InsertText("3", 2),
|
||||
AssertRevisionState(1, RevisionState::Ack),
|
||||
AssertRevisionState(2, RevisionState::Ack),
|
||||
AssertRevisionState(3, RevisionState::Ack),
|
||||
AssertJson(r#"[{"insert":"123\n"}]"#),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn document_sync_insert_test() {
|
||||
let scripts = vec![
|
||||
InsertText("1", 0),
|
||||
InsertText("2", 1),
|
||||
InsertText("3", 2),
|
||||
AssertJson(r#"[{"insert":"123\n"}]"#),
|
||||
AssertNextRevId(None),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn document_sync_delete_test1() {
|
||||
let scripts = vec![
|
||||
InsertText("1", 0),
|
||||
InsertText("2", 1),
|
||||
InsertText("3", 2),
|
||||
Delete(Interval::new(0, 2)),
|
||||
AssertJson(r#"[{"insert":"3\n"}]"#),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn document_sync_replace_test() {
|
||||
let scripts = vec![
|
||||
InsertText("1", 0),
|
||||
InsertText("2", 1),
|
||||
InsertText("3", 2),
|
||||
Replace(Interval::new(0, 3), "abc"),
|
||||
AssertJson(r#"[{"insert":"abc\n"}]"#),
|
||||
];
|
||||
EditorTest::new().await.run_scripts(scripts).await;
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
use flowy_collaboration::entities::revision::RevisionState;
|
||||
use flowy_document::core::{edit::ClientDocumentEditor, SYNC_INTERVAL_IN_MILLIS};
|
||||
use flowy_test::{helper::ViewTest, FlowySDKTest};
|
||||
use lib_ot::{core::Interval, rich_text::RichTextDelta};
|
||||
use std::sync::Arc;
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
pub enum EditorScript {
|
||||
InsertText(&'static str, usize),
|
||||
Delete(Interval),
|
||||
Replace(Interval, &'static str),
|
||||
|
||||
AssertRevisionState(i64, RevisionState),
|
||||
AssertNextRevId(Option<i64>),
|
||||
AssertCurrentRevId(i64),
|
||||
AssertJson(&'static str),
|
||||
}
|
||||
|
||||
pub struct EditorTest {
|
||||
pub sdk: FlowySDKTest,
|
||||
pub editor: Arc<ClientDocumentEditor>,
|
||||
}
|
||||
|
||||
impl EditorTest {
|
||||
pub async fn new() -> Self {
|
||||
let sdk = FlowySDKTest::default();
|
||||
let _ = sdk.init_user().await;
|
||||
let test = ViewTest::new(&sdk).await;
|
||||
let editor = sdk.document_ctx.controller.open_document(&test.view.id).await.unwrap();
|
||||
Self { sdk, editor }
|
||||
}
|
||||
|
||||
pub async fn run_scripts(mut self, scripts: Vec<EditorScript>) {
|
||||
for script in scripts {
|
||||
self.run_script(script).await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_script(&mut self, script: EditorScript) {
|
||||
let rev_manager = self.editor.rev_manager();
|
||||
let cache = rev_manager.revision_cache();
|
||||
let _user_id = self.sdk.user_session.user_id().unwrap();
|
||||
// let ws_manager = self.sdk.ws_conn.clone();
|
||||
// let token = self.sdk.user_session.token().unwrap();
|
||||
|
||||
match script {
|
||||
EditorScript::InsertText(s, offset) => {
|
||||
self.editor.insert(offset, s).await.unwrap();
|
||||
},
|
||||
EditorScript::Delete(interval) => {
|
||||
self.editor.delete(interval).await.unwrap();
|
||||
},
|
||||
EditorScript::Replace(interval, s) => {
|
||||
self.editor.replace(interval, s).await.unwrap();
|
||||
},
|
||||
EditorScript::AssertRevisionState(rev_id, state) => {
|
||||
let record = cache.get(rev_id).await.unwrap();
|
||||
assert_eq!(record.state, state);
|
||||
},
|
||||
EditorScript::AssertCurrentRevId(rev_id) => {
|
||||
assert_eq!(self.editor.rev_manager().rev_id(), rev_id);
|
||||
},
|
||||
EditorScript::AssertNextRevId(rev_id) => {
|
||||
let next_revision = rev_manager.next_sync_revision().await.unwrap();
|
||||
if rev_id.is_none() {
|
||||
assert_eq!(next_revision.is_none(), true, "Next revision should be None");
|
||||
return;
|
||||
}
|
||||
let next_revision = next_revision.unwrap();
|
||||
assert_eq!(next_revision.rev_id, rev_id.unwrap());
|
||||
},
|
||||
EditorScript::AssertJson(expected) => {
|
||||
let expected_delta: RichTextDelta = serde_json::from_str(expected).unwrap();
|
||||
let delta = self.editor.doc_delta().await.unwrap();
|
||||
if expected_delta != delta {
|
||||
eprintln!("✅ expect: {}", expected,);
|
||||
eprintln!("❌ receive: {}", delta.to_json());
|
||||
}
|
||||
assert_eq!(expected_delta, delta);
|
||||
},
|
||||
}
|
||||
sleep(Duration::from_millis(SYNC_INTERVAL_IN_MILLIS)).await;
|
||||
}
|
||||
}
|
2
frontend/rust-lib/flowy-document/tests/document/mod.rs
Normal file
2
frontend/rust-lib/flowy-document/tests/document/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod document_test;
|
||||
mod edit_script;
|
@ -724,7 +724,7 @@ fn attributes_preserve_header_format_on_merge() {
|
||||
fn attributes_format_emoji() {
|
||||
let emoji_s = "👋 ";
|
||||
let s: FlowyStr = emoji_s.into();
|
||||
let len = s.count_utf16_code_units();
|
||||
let len = s.utf16_size();
|
||||
assert_eq!(3, len);
|
||||
assert_eq!(2, s.graphemes(true).count());
|
||||
let ops = vec![
|
||||
|
@ -297,8 +297,9 @@ impl Rng {
|
||||
|
||||
pub fn gen_delta(&mut self, s: &str) -> RichTextDelta {
|
||||
let mut delta = RichTextDelta::default();
|
||||
let s = FlowyStr::from(s);
|
||||
loop {
|
||||
let left = s.chars().count() - delta.base_len;
|
||||
let left = s.utf16_size() - delta.utf16_base_len;
|
||||
if left == 0 {
|
||||
break;
|
||||
}
|
||||
|
@ -298,20 +298,20 @@ fn delta_next_op_with_len_cross_op_return_last() {
|
||||
#[test]
|
||||
fn lengths() {
|
||||
let mut delta = RichTextDelta::default();
|
||||
assert_eq!(delta.base_len, 0);
|
||||
assert_eq!(delta.target_len, 0);
|
||||
assert_eq!(delta.utf16_base_len, 0);
|
||||
assert_eq!(delta.utf16_target_len, 0);
|
||||
delta.retain(5, RichTextAttributes::default());
|
||||
assert_eq!(delta.base_len, 5);
|
||||
assert_eq!(delta.target_len, 5);
|
||||
assert_eq!(delta.utf16_base_len, 5);
|
||||
assert_eq!(delta.utf16_target_len, 5);
|
||||
delta.insert("abc", RichTextAttributes::default());
|
||||
assert_eq!(delta.base_len, 5);
|
||||
assert_eq!(delta.target_len, 8);
|
||||
assert_eq!(delta.utf16_base_len, 5);
|
||||
assert_eq!(delta.utf16_target_len, 8);
|
||||
delta.retain(2, RichTextAttributes::default());
|
||||
assert_eq!(delta.base_len, 7);
|
||||
assert_eq!(delta.target_len, 10);
|
||||
assert_eq!(delta.utf16_base_len, 7);
|
||||
assert_eq!(delta.utf16_target_len, 10);
|
||||
delta.delete(2);
|
||||
assert_eq!(delta.base_len, 9);
|
||||
assert_eq!(delta.target_len, 10);
|
||||
assert_eq!(delta.utf16_base_len, 9);
|
||||
assert_eq!(delta.utf16_target_len, 10);
|
||||
}
|
||||
#[test]
|
||||
fn sequence() {
|
||||
@ -331,7 +331,7 @@ fn apply_1000() {
|
||||
let mut rng = Rng::default();
|
||||
let s: FlowyStr = rng.gen_string(50).into();
|
||||
let delta = rng.gen_delta(&s);
|
||||
assert_eq!(s.count_utf16_code_units(), delta.base_len);
|
||||
assert_eq!(s.utf16_size(), delta.utf16_base_len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -372,8 +372,8 @@ fn invert() {
|
||||
let s = rng.gen_string(50);
|
||||
let delta_a = rng.gen_delta(&s);
|
||||
let delta_b = delta_a.invert_str(&s);
|
||||
assert_eq!(delta_a.base_len, delta_b.target_len);
|
||||
assert_eq!(delta_a.target_len, delta_b.base_len);
|
||||
assert_eq!(delta_a.utf16_base_len, delta_b.utf16_target_len);
|
||||
assert_eq!(delta_a.utf16_target_len, delta_b.utf16_base_len);
|
||||
assert_eq!(delta_b.apply(&delta_a.apply(&s).unwrap()).unwrap(), s);
|
||||
}
|
||||
}
|
||||
@ -444,14 +444,14 @@ fn compose() {
|
||||
let s = rng.gen_string(20);
|
||||
let a = rng.gen_delta(&s);
|
||||
let after_a: FlowyStr = a.apply(&s).unwrap().into();
|
||||
assert_eq!(a.target_len, after_a.count_utf16_code_units());
|
||||
assert_eq!(a.utf16_target_len, after_a.utf16_size());
|
||||
|
||||
let b = rng.gen_delta(&after_a);
|
||||
let after_b: FlowyStr = b.apply(&after_a).unwrap().into();
|
||||
assert_eq!(b.target_len, after_b.count_utf16_code_units());
|
||||
assert_eq!(b.utf16_target_len, after_b.utf16_size());
|
||||
|
||||
let ab = a.compose(&b).unwrap();
|
||||
assert_eq!(ab.target_len, b.target_len);
|
||||
assert_eq!(ab.utf16_target_len, b.utf16_target_len);
|
||||
let after_ab: FlowyStr = ab.apply(&s).unwrap().into();
|
||||
assert_eq!(after_b, after_ab);
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
mod document;
|
||||
mod editor;
|
||||
|
Reference in New Issue
Block a user