瀏覽代碼

1. rename flowy_str functions
2. mv the document_test to flowy_document crate

appflowy 3 年之前
父節點
當前提交
c456687a18

+ 0 - 1
backend/Cargo.lock

@@ -1436,7 +1436,6 @@ dependencies = [
  "claim",
  "flowy-collaboration",
  "flowy-core",
- "flowy-document",
  "flowy-net",
  "flowy-sdk",
  "flowy-user",

+ 1 - 1
backend/tests/document_test/edit_script.rs

@@ -37,7 +37,7 @@ pub enum DocScript {
 impl DocumentTest {
     pub async fn new() -> Self {
         let server = spawn_server().await;
-        let flowy_test = FlowySDKTest::new(server.client_server_config.clone(), None);
+        let flowy_test = FlowySDKTest::new(server.client_server_config.clone());
         Self { server, flowy_test }
     }
 

+ 1 - 1
frontend/rust-lib/flowy-document/src/core/revision/cache.rs

@@ -132,7 +132,7 @@ impl DocumentRevisionCache {
 }
 
 impl RevisionMemoryCacheDelegate for Arc<SQLitePersistence> {
-    #[tracing::instrument(level = "debug", skip(self, records), fields(checkpoint_result), err)]
+    #[tracing::instrument(level = "trace", skip(self, records), fields(checkpoint_result), err)]
     fn checkpoint_tick(&self, mut records: Vec<RevisionRecord>) -> FlowyResult<()> {
         let conn = &*self.pool.get().map_err(internal_error)?;
         records.retain(|record| record.write_to_disk);

+ 1 - 1
frontend/rust-lib/flowy-document/src/core/revision/disk/sql_impl.rs

@@ -120,7 +120,7 @@ impl RevisionTableSql {
             .filter(dsl::rev_id.eq(changeset.rev_id.as_ref()))
             .filter(dsl::doc_id.eq(changeset.doc_id));
         let _ = update(filter).set(dsl::state.eq(changeset.state)).execute(conn)?;
-        tracing::debug!("Set {} to {:?}", changeset.rev_id, changeset.state);
+        tracing::debug!("Save revision:{} state to {:?}", changeset.rev_id, changeset.state);
         Ok(())
     }
 

+ 1 - 2
frontend/rust-lib/flowy-document/src/core/revision/manager.rs

@@ -169,11 +169,10 @@ impl RevisionSyncSequence {
                     "The ack rev_id:{} is not equal to the current rev_id:{}",
                     rev_id, pop_rev_id
                 );
-                // tracing::error!("{}", desc);
                 return Err(FlowyError::internal().context(desc));
             }
 
-            tracing::debug!("pop revision {}", pop_rev_id);
+            tracing::trace!("{} revision finish synchronizing", pop_rev_id);
             self.revs_map.remove(&pop_rev_id);
             let _ = self.local_revs.write().await.pop_front();
         }

+ 68 - 0
frontend/rust-lib/flowy-document/tests/document/document_test.rs

@@ -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;
+}

+ 3 - 8
frontend/rust-lib/flowy-test/src/doc_script.rs → frontend/rust-lib/flowy-document/tests/document/edit_script.rs

@@ -1,7 +1,6 @@
-use crate::{helper::ViewTest, FlowySDKTest};
-use backend_service::configuration::get_client_server_configuration;
 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};
@@ -24,8 +23,7 @@ pub struct EditorTest {
 
 impl EditorTest {
     pub async fn new() -> Self {
-        let server_config = get_client_server_configuration().unwrap();
-        let sdk = FlowySDKTest::new(server_config, None);
+        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();
@@ -36,8 +34,6 @@ impl EditorTest {
         for script in scripts {
             self.run_script(script).await;
         }
-
-        sleep(Duration::from_secs(3)).await;
     }
 
     async fn run_script(&mut self, script: EditorScript) {
@@ -46,7 +42,6 @@ impl EditorTest {
         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();
-        let wait_millis = 2 * SYNC_INTERVAL_IN_MILLIS;
 
         match script {
             EditorScript::InsertText(s, offset) => {
@@ -84,6 +79,6 @@ impl EditorTest {
                 assert_eq!(expected_delta, delta);
             },
         }
-        sleep(Duration::from_millis(wait_millis)).await;
+        sleep(Duration::from_millis(SYNC_INTERVAL_IN_MILLIS)).await;
     }
 }

+ 2 - 0
frontend/rust-lib/flowy-document/tests/document/mod.rs

@@ -0,0 +1,2 @@
+mod document_test;
+mod edit_script;

+ 1 - 1
frontend/rust-lib/flowy-document/tests/editor/attribute_test.rs

@@ -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![

+ 2 - 1
frontend/rust-lib/flowy-document/tests/editor/mod.rs

@@ -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;
             }

+ 16 - 16
frontend/rust-lib/flowy-document/tests/editor/op_test.rs

@@ -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 - 0
frontend/rust-lib/flowy-document/tests/main.rs

@@ -1 +1,2 @@
+mod document;
 mod editor;

+ 1 - 1
frontend/rust-lib/flowy-sdk/src/deps_resolve/document_deps.rs

@@ -6,7 +6,7 @@ use flowy_document::{
     core::{DocumentWSReceivers, DocumentWebSocket, WSStateReceiver},
     errors::{internal_error, FlowyError},
 };
-use flowy_net::services::ws_conn::{FlowyWSSender, FlowyWebSocketConnect};
+use flowy_net::services::ws_conn::FlowyWebSocketConnect;
 use flowy_user::services::user::UserSession;
 use lib_ws::{WSMessageReceiver, WSModule, WebSocketRawMessage};
 use std::{convert::TryInto, path::Path, sync::Arc};

+ 0 - 1
frontend/rust-lib/flowy-test/Cargo.toml

@@ -10,7 +10,6 @@ flowy-sdk = { path = "../flowy-sdk"}
 flowy-user = { path = "../flowy-user"}
 flowy-net = { path = "../flowy-net"}
 flowy-core = { path = "../flowy-core", default-features = false}
-flowy-document = { path = "../flowy-document", features = ["flowy_unit_test"]}
 lib-dispatch = { path = "../lib-dispatch" }
 
 flowy-collaboration = { path = "../../../shared-lib/flowy-collaboration" }

+ 2 - 4
frontend/rust-lib/flowy-test/src/helper.rs

@@ -1,5 +1,4 @@
-use std::{fs, path::PathBuf, sync::Arc};
-
+use crate::prelude::*;
 use flowy_collaboration::entities::doc::DocumentInfo;
 use flowy_core::{
     entities::{
@@ -18,8 +17,7 @@ use flowy_user::{
 };
 use lib_dispatch::prelude::{EventDispatcher, ModuleRequest, ToBytes};
 use lib_infra::uuid_string;
-
-use crate::prelude::*;
+use std::{fs, path::PathBuf, sync::Arc};
 
 pub struct WorkspaceTest {
     pub sdk: FlowySDKTest,

+ 3 - 7
frontend/rust-lib/flowy-test/src/lib.rs

@@ -1,14 +1,11 @@
-pub mod doc_script;
 pub mod event_builder;
 pub mod helper;
 
 use crate::helper::*;
 use backend_service::configuration::{get_client_server_configuration, ClientServerConfiguration};
-use flowy_net::services::ws_conn::FlowyRawWebSocket;
 use flowy_sdk::{FlowySDK, FlowySDKConfig};
 use flowy_user::entities::UserProfile;
 use lib_infra::uuid_string;
-use std::sync::Arc;
 
 pub mod prelude {
     pub use crate::{event_builder::*, helper::*, *};
@@ -18,7 +15,6 @@ pub mod prelude {
 #[derive(Clone)]
 pub struct FlowySDKTest {
     pub inner: FlowySDK,
-    pub ws: Option<Arc<dyn FlowyRawWebSocket>>,
 }
 
 impl std::ops::Deref for FlowySDKTest {
@@ -30,18 +26,18 @@ impl std::ops::Deref for FlowySDKTest {
 impl std::default::Default for FlowySDKTest {
     fn default() -> Self {
         let server_config = get_client_server_configuration().unwrap();
-        let sdk = Self::new(server_config, None);
+        let sdk = Self::new(server_config);
         std::mem::forget(sdk.dispatcher());
         sdk
     }
 }
 
 impl FlowySDKTest {
-    pub fn new(server_config: ClientServerConfiguration, ws: Option<Arc<dyn FlowyRawWebSocket>>) -> Self {
+    pub fn new(server_config: ClientServerConfiguration) -> Self {
         let config = FlowySDKConfig::new(&root_dir(), server_config, &uuid_string()).log_filter("debug");
         let sdk = FlowySDK::new(config);
         std::mem::forget(sdk.dispatcher());
-        Self { inner: sdk, ws }
+        Self { inner: sdk }
     }
 
     pub async fn sign_up(&self) -> SignUpContext {

+ 0 - 1
frontend/rust-lib/flowy-test/tests/main.rs

@@ -1 +0,0 @@
-mod revision_test;

+ 0 - 28
frontend/rust-lib/flowy-test/tests/revision_test.rs

@@ -1,28 +0,0 @@
-use flowy_collaboration::entities::revision::RevisionState;
-use flowy_test::doc_script::{EditorScript::*, *};
-
-#[tokio::test]
-async fn doc_sync_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 doc_sync_retry_ws_conn() {
-    let scripts = vec![
-        InsertText("1", 0),
-        InsertText("2", 1),
-        InsertText("3", 2),
-        AssertRevisionState(2, RevisionState::Ack),
-        AssertRevisionState(3, RevisionState::Ack),
-        AssertNextRevId(None),
-        AssertJson(r#"[{"insert":"123\n"}]"#),
-    ];
-    EditorTest::new().await.run_scripts(scripts).await;
-}

+ 1 - 2
frontend/rust-lib/lib-log/src/lib.rs

@@ -74,8 +74,7 @@ impl Builder {
         let _ = LogTracer::builder()
             .with_max_level(LevelFilter::Trace)
             .init()
-            .map_err(|e| format!("{:?}", e))
-            .unwrap();
+            .map_err(|e| format!("{:?}", e))?;
 
         *LOG_GUARD.write().unwrap() = Some(guard);
         Ok(())

+ 3 - 3
shared-lib/flowy-collaboration/src/document/document.rs

@@ -109,10 +109,10 @@ impl Document {
     }
 
     pub fn insert<T: ToString>(&mut self, index: usize, data: T) -> Result<RichTextDelta, CollaborateError> {
+        let text = data.to_string();
         let interval = Interval::new(index, index);
         let _ = validate_interval(&self.delta, &interval)?;
 
-        let text = data.to_string();
         let delta = self.view.insert(&self.delta, &text, interval)?;
         self.compose_delta(delta.clone())?;
         Ok(delta)
@@ -201,8 +201,8 @@ impl Document {
 }
 
 fn validate_interval(delta: &RichTextDelta, interval: &Interval) -> Result<(), CollaborateError> {
-    if delta.target_len < interval.end {
-        log::error!("{:?} out of bounds. should 0..{}", interval, delta.target_len);
+    if delta.utf16_target_len < interval.end {
+        log::error!("{:?} out of bounds. should 0..{}", interval, delta.utf16_target_len);
         return Err(CollaborateError::out_of_bound());
     }
     Ok(())

+ 14 - 14
shared-lib/lib-ot/src/core/delta/delta.rs

@@ -17,8 +17,8 @@ use std::{
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub struct Delta<T: Attributes> {
     pub ops: Vec<Operation<T>>,
-    pub base_len: usize,
-    pub target_len: usize,
+    pub utf16_base_len: usize,
+    pub utf16_target_len: usize,
 }
 
 impl<T> Default for Delta<T>
@@ -28,8 +28,8 @@ where
     fn default() -> Self {
         Self {
             ops: Vec::new(),
-            base_len: 0,
-            target_len: 0,
+            utf16_base_len: 0,
+            utf16_target_len: 0,
         }
     }
 }
@@ -72,8 +72,8 @@ where
     pub fn with_capacity(capacity: usize) -> Self {
         Self {
             ops: Vec::with_capacity(capacity),
-            base_len: 0,
-            target_len: 0,
+            utf16_base_len: 0,
+            utf16_target_len: 0,
         }
     }
 
@@ -89,7 +89,7 @@ where
         if n == 0 {
             return;
         }
-        self.base_len += n as usize;
+        self.utf16_base_len += n as usize;
         if let Some(Operation::Delete(n_last)) = self.ops.last_mut() {
             *n_last += n;
         } else {
@@ -103,7 +103,7 @@ where
             return;
         }
 
-        self.target_len += s.count_utf16_code_units();
+        self.utf16_target_len += s.utf16_size();
         let new_last = match self.ops.as_mut_slice() {
             [.., Operation::<T>::Insert(insert)] => {
                 //
@@ -131,8 +131,8 @@ where
         if n == 0 {
             return;
         }
-        self.base_len += n as usize;
-        self.target_len += n as usize;
+        self.utf16_base_len += n as usize;
+        self.utf16_target_len += n as usize;
 
         if let Some(Operation::<T>::Retain(retain)) = self.ops.last_mut() {
             if let Some(new_op) = retain.merge_or_new(n, attributes) {
@@ -146,11 +146,11 @@ where
     /// Applies an operation to a string, returning a new string.
     pub fn apply(&self, s: &str) -> Result<String, OTError> {
         let s: FlowyStr = s.into();
-        if s.count_utf16_code_units() != self.base_len {
+        if s.utf16_size() != self.utf16_base_len {
             return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength).build());
         }
         let mut new_s = String::new();
-        let code_point_iter = &mut s.code_point_iter();
+        let code_point_iter = &mut s.utf16_code_unit_iter();
         for op in &self.ops {
             match &op {
                 Operation::Retain(retain) => {
@@ -271,11 +271,11 @@ where
     where
         Self: Sized,
     {
-        if self.base_len != other.base_len {
+        if self.utf16_base_len != other.utf16_base_len {
             return Err(ErrorBuilder::new(OTErrorCode::IncompatibleLength)
                 .msg(format!(
                     "cur base length: {}, other base length: {}",
-                    self.base_len, other.base_len
+                    self.utf16_base_len, other.utf16_base_len
                 ))
                 .build());
         }

+ 18 - 18
shared-lib/lib-ot/src/core/flowy_str.rs

@@ -6,11 +6,9 @@ pub struct FlowyStr(pub String);
 
 impl FlowyStr {
     // https://stackoverflow.com/questions/2241348/what-is-unicode-utf-8-utf-16
-    pub fn count_utf16_code_units(&self) -> usize { count_utf16_code_units(&self.0) }
+    pub fn utf16_size(&self) -> usize { count_utf16_code_units(&self.0) }
 
-    pub fn utf16_iter(&self) -> FlowyUtf16CodePointIterator { FlowyUtf16CodePointIterator::new(self, 0) }
-
-    pub fn code_point_iter(&self) -> Utf16CodeUnitIterator { Utf16CodeUnitIterator::new(self) }
+    pub fn utf16_code_unit_iter(&self) -> Utf16CodeUnitIterator { Utf16CodeUnitIterator::new(self) }
 
     pub fn sub_str(&self, interval: Interval) -> String {
         match self.with_interval(interval) {
@@ -23,7 +21,7 @@ impl FlowyStr {
         let mut iter = Utf16CodeUnitIterator::new(self);
         let mut buf = vec![];
         while let Some((byte, _len)) = iter.next() {
-            if interval.start < iter.code_point_offset && interval.end >= iter.code_point_offset {
+            if interval.start < iter.code_unit_offset && interval.end >= iter.code_unit_offset {
                 buf.extend_from_slice(byte);
             }
         }
@@ -37,12 +35,15 @@ impl FlowyStr {
             Err(_e) => None,
         }
     }
+
+    #[allow(dead_code)]
+    fn utf16_code_point_iter(&self) -> FlowyUtf16CodePointIterator { FlowyUtf16CodePointIterator::new(self, 0) }
 }
 
 pub struct Utf16CodeUnitIterator<'a> {
     s: &'a FlowyStr,
     bytes_offset: usize,
-    code_point_offset: usize,
+    code_unit_offset: usize,
     iter_index: usize,
     iter: slice::Iter<'a, u8>,
 }
@@ -52,7 +53,7 @@ impl<'a> Utf16CodeUnitIterator<'a> {
         Utf16CodeUnitIterator {
             s,
             bytes_offset: 0,
-            code_point_offset: 0,
+            code_unit_offset: 0,
             iter_index: 0,
             iter: s.as_bytes().iter(),
         }
@@ -69,7 +70,7 @@ impl<'a> Iterator for Utf16CodeUnitIterator<'a> {
         while let Some(&b) = self.iter.next() {
             self.iter_index += 1;
 
-            let mut code_point_count = 0;
+            let mut code_unit_count = 0;
             if self.bytes_offset > self.iter_index {
                 continue;
             }
@@ -79,16 +80,16 @@ impl<'a> Iterator for Utf16CodeUnitIterator<'a> {
             }
 
             if (b as i8) >= -0x40 {
-                code_point_count += 1
+                code_unit_count += 1
             }
             if b >= 0xf0 {
-                code_point_count += 1
+                code_unit_count += 1
             }
 
             self.bytes_offset += len_utf8_from_first_byte(b);
-            self.code_point_offset += code_point_count;
+            self.code_unit_offset += code_unit_count;
 
-            if code_point_count == 1 {
+            if code_unit_count == 1 {
                 break;
             }
         }
@@ -201,7 +202,6 @@ impl<'a> Iterator for FlowyUtf16CodePointIterator<'a> {
 }
 
 pub fn count_utf16_code_units(s: &str) -> usize {
-    // bytecount::num_chars(s.as_bytes())
     let mut utf16_count = 0;
     for &b in s.as_bytes() {
         if (b as i8) >= -0x40 {
@@ -231,9 +231,9 @@ mod tests {
     use crate::core::{FlowyStr, Interval};
 
     #[test]
-    fn flowy_str_utf16_test() {
+    fn flowy_str_utf16_code_point_iter_test1() {
         let s: FlowyStr = "👋😁👋😁".into();
-        let mut iter = s.utf16_iter();
+        let mut iter = s.utf16_code_point_iter();
         assert_eq!(iter.next().unwrap(), "👋".to_string());
         assert_eq!(iter.next().unwrap(), "😁".to_string());
         assert_eq!(iter.next().unwrap(), "👋".to_string());
@@ -242,15 +242,15 @@ mod tests {
     }
 
     #[test]
-    fn flowy_str_utf16_iter_test() {
+    fn flowy_str_utf16_code_point_iter_test2() {
         let s: FlowyStr = "👋👋😁😁👋👋".into();
-        let iter = s.utf16_iter();
+        let iter = s.utf16_code_point_iter();
         let result = iter.skip(2).take(2).collect::<String>();
         assert_eq!(result, "😁😁".to_string());
     }
 
     #[test]
-    fn flowy_str_code_point_test() {
+    fn flowy_str_code_unit_test() {
         let s: FlowyStr = "👋 \n👋".into();
         let output = s.with_interval(Interval::new(0, 2)).unwrap().0;
         assert_eq!(output, "👋");

+ 1 - 1
shared-lib/lib-ot/src/core/operation/operation.rs

@@ -291,7 +291,7 @@ impl<T> Insert<T>
 where
     T: Attributes,
 {
-    pub fn count_of_utf16_code_units(&self) -> usize { self.s.count_utf16_code_units() }
+    pub fn count_of_utf16_code_units(&self) -> usize { self.s.utf16_size() }
 
     pub fn merge_or_new_op(&mut self, s: &str, attributes: T) -> Option<Operation<T>> {
         if self.attributes == attributes {