Kaynağa Gözat

chore: add group unit test

appflowy 2 yıl önce
ebeveyn
işleme
0680b20579
20 değiştirilmiş dosya ile 190 ekleme ve 53 silme
  1. 0 2
      frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart
  2. 1 1
      frontend/rust-lib/flowy-folder/src/services/view/controller.rs
  3. 7 0
      frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs
  4. 14 1
      frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs
  5. 1 3
      frontend/rust-lib/flowy-grid/src/services/grid_editor.rs
  6. 22 12
      frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs
  7. 2 2
      frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs
  8. 2 2
      frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs
  9. 3 5
      frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs
  10. 13 8
      frontend/rust-lib/flowy-grid/src/services/group/group_service.rs
  11. 1 1
      frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs
  12. 1 1
      frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs
  13. 1 1
      frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs
  14. 1 1
      frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs
  15. 15 2
      frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs
  16. 1 0
      frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs
  17. 51 8
      frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs
  18. 51 0
      frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs
  19. 1 1
      frontend/rust-lib/flowy-sdk/src/deps_resolve/folder_deps.rs
  20. 2 2
      shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs

+ 0 - 2
frontend/app_flowy/lib/plugins/board/presentation/card/board_text_cell.dart

@@ -1,10 +1,8 @@
 import 'package:app_flowy/plugins/board/application/card/board_text_cell_bloc.dart';
 import 'package:app_flowy/plugins/grid/application/cell/cell_service/cell_service.dart';
-import 'package:flowy_infra/image.dart';
 import 'package:flowy_infra_ui/style_widget/text.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:flutter_svg/svg.dart';
 
 class BoardTextCell extends StatefulWidget {
   final GridCellControllerBuilder cellControllerBuilder;

+ 1 - 1
frontend/rust-lib/flowy-folder/src/services/view/controller.rs

@@ -1,5 +1,5 @@
 pub use crate::entities::view::ViewDataTypePB;
-use crate::entities::{ViewInfoPB, ViewLayoutTypePB};
+use crate::entities::ViewInfoPB;
 use crate::manager::{ViewDataProcessor, ViewDataProcessorMap};
 use crate::{
     dart_notification::{send_dart_notification, FolderNotification},

+ 7 - 0
frontend/rust-lib/flowy-folder/tests/workspace/folder_test.rs

@@ -1,6 +1,7 @@
 use crate::script::{invalid_workspace_name_test_case, FolderScript::*, FolderTest};
 use flowy_folder::entities::view::ViewDataTypePB;
 use flowy_folder::entities::workspace::CreateWorkspacePayloadPB;
+use flowy_folder::entities::ViewLayoutTypePB;
 
 use flowy_revision::disk::RevisionState;
 use flowy_test::{event_builder::*, FlowySDKTest};
@@ -135,11 +136,13 @@ async fn app_create_with_view() {
             name: "View A".to_owned(),
             desc: "View A description".to_owned(),
             data_type: ViewDataTypePB::Text,
+            layout: ViewLayoutTypePB::Document,
         },
         CreateView {
             name: "Grid".to_owned(),
             desc: "Grid description".to_owned(),
             data_type: ViewDataTypePB::Database,
+            layout: ViewLayoutTypePB::Document,
         },
         ReadApp(app.id),
     ])
@@ -199,11 +202,13 @@ async fn view_delete_all() {
             name: "View A".to_owned(),
             desc: "View A description".to_owned(),
             data_type: ViewDataTypePB::Text,
+            layout: ViewLayoutTypePB::Document,
         },
         CreateView {
             name: "Grid".to_owned(),
             desc: "Grid description".to_owned(),
             data_type: ViewDataTypePB::Database,
+            layout: ViewLayoutTypePB::Document,
         },
         ReadApp(app.id.clone()),
     ])
@@ -232,6 +237,7 @@ async fn view_delete_all_permanent() {
             name: "View A".to_owned(),
             desc: "View A description".to_owned(),
             data_type: ViewDataTypePB::Text,
+            layout: ViewLayoutTypePB::Document,
         },
         ReadApp(app.id.clone()),
     ])
@@ -331,6 +337,7 @@ async fn folder_sync_revision_with_new_view() {
             name: view_name.clone(),
             desc: view_desc.clone(),
             data_type: ViewDataTypePB::Text,
+            layout: ViewLayoutTypePB::Document,
         },
         AssertCurrentRevId(3),
         AssertNextSyncRevId(Some(3)),

+ 14 - 1
frontend/rust-lib/flowy-grid/src/entities/group_entities/group.rs

@@ -28,7 +28,20 @@ impl std::convert::From<&GroupConfigurationRevision> for GridGroupConfigurationP
 #[derive(ProtoBuf, Debug, Default, Clone)]
 pub struct RepeatedGridGroupPB {
     #[pb(index = 1)]
-    pub(crate) items: Vec<GroupPB>,
+    pub items: Vec<GroupPB>,
+}
+
+impl std::ops::Deref for RepeatedGridGroupPB {
+    type Target = Vec<GroupPB>;
+    fn deref(&self) -> &Self::Target {
+        &self.items
+    }
+}
+
+impl std::ops::DerefMut for RepeatedGridGroupPB {
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        &mut self.items
+    }
 }
 
 #[derive(ProtoBuf, Debug, Default, Clone)]

+ 1 - 3
frontend/rust-lib/flowy-grid/src/services/grid_editor.rs

@@ -9,9 +9,7 @@ use crate::services::field::{default_type_option_builder_from_type, type_option_
 use crate::services::filter::GridFilterService;
 use crate::services::grid_view_manager::GridViewManager;
 use crate::services::persistence::block_index::BlockIndexCache;
-use crate::services::row::{
-    make_grid_blocks, make_row_from_row_rev, make_rows_from_row_revs, GridBlockSnapshot, RowRevisionBuilder,
-};
+use crate::services::row::{make_grid_blocks, make_rows_from_row_revs, GridBlockSnapshot, RowRevisionBuilder};
 use bytes::Bytes;
 use flowy_error::{ErrorCode, FlowyError, FlowyResult};
 use flowy_grid_data_model::revision::*;

+ 22 - 12
frontend/rust-lib/flowy-grid/src/services/grid_view_editor.rs

@@ -13,6 +13,7 @@ use flowy_sync::client_grid::{GridViewRevisionChangeset, GridViewRevisionPad};
 use flowy_sync::entities::grid::GridSettingChangesetParams;
 use flowy_sync::entities::revision::Revision;
 use lib_infra::future::{wrap_future, AFFuture, FutureResult};
+use std::sync::atomic::{AtomicBool, Ordering};
 use std::sync::Arc;
 use tokio::sync::RwLock;
 
@@ -26,6 +27,7 @@ pub struct GridViewRevisionEditor {
     row_delegate: Arc<dyn GridViewRowDelegate>,
     group_service: Arc<RwLock<GroupService>>,
     scheduler: Arc<dyn GridServiceTaskScheduler>,
+    did_load_group: AtomicBool,
 }
 
 impl GridViewRevisionEditor {
@@ -46,6 +48,7 @@ impl GridViewRevisionEditor {
         let rev_manager = Arc::new(rev_manager);
         let group_service = GroupService::new(Box::new(pad.clone())).await;
         let user_id = user_id.to_owned();
+        let did_load_group = AtomicBool::new(false);
         Ok(Self {
             pad,
             user_id,
@@ -55,6 +58,7 @@ impl GridViewRevisionEditor {
             field_delegate,
             row_delegate,
             group_service: Arc::new(RwLock::new(group_service)),
+            did_load_group,
         })
     }
 
@@ -140,19 +144,25 @@ impl GridViewRevisionEditor {
     }
 
     pub(crate) async fn load_groups(&self) -> FlowyResult<Vec<GroupPB>> {
-        let field_revs = self.field_delegate.get_field_revs().await;
-        let row_revs = self.row_delegate.gv_row_revs().await;
+        let groups = if !self.did_load_group.load(Ordering::SeqCst) {
+            self.did_load_group.store(true, Ordering::SeqCst);
+            let field_revs = self.field_delegate.get_field_revs().await;
+            let row_revs = self.row_delegate.gv_row_revs().await;
+            match self
+                .group_service
+                .write()
+                .await
+                .load_groups(&field_revs, row_revs)
+                .await
+            {
+                None => vec![],
+                Some(groups) => groups,
+            }
+        } else {
+            self.group_service.read().await.groups().await
+        };
 
-        match self
-            .group_service
-            .write()
-            .await
-            .load_groups(&field_revs, row_revs)
-            .await
-        {
-            None => Ok(vec![]),
-            Some(groups) => Ok(groups.into_iter().map(GroupPB::from).collect()),
-        }
+        Ok(groups.into_iter().map(GroupPB::from).collect())
     }
 
     pub(crate) async fn get_setting(&self) -> GridSettingPB {

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/group_generator/checkbox_group.rs

@@ -37,9 +37,9 @@ impl Groupable for CheckboxGroupController {
 
     fn move_row_if_match(
         &mut self,
-        field_rev: &FieldRevision,
+        _field_rev: &FieldRevision,
         _row_rev: &RowRevision,
-        row_changeset: &mut RowChangeset,
+        _row_changeset: &mut RowChangeset,
         _cell_data: &Self::CellDataType,
         _to_row_id: &str,
     ) -> Vec<GroupRowsChangesetPB> {

+ 2 - 2
frontend/rust-lib/flowy-grid/src/services/group/group_generator/group_controller.rs

@@ -47,7 +47,7 @@ pub trait GroupController: GroupControllerSharedAction + Send + Sync {
 pub trait GroupControllerSharedAction: Send + Sync {
     // The field that is used for grouping the rows
     fn field_id(&self) -> &str;
-    fn build_groups(&self) -> Vec<Group>;
+    fn groups(&self) -> Vec<Group>;
     fn group_rows(&mut self, row_revs: &[Arc<RowRevision>], field_rev: &FieldRevision) -> FlowyResult<()>;
     fn did_update_row(
         &mut self,
@@ -194,7 +194,7 @@ where
         &self.field_id
     }
 
-    fn build_groups(&self) -> Vec<Group> {
+    fn groups(&self) -> Vec<Group> {
         let default_group = self.default_group.clone();
         let mut groups: Vec<Group> = self.groups_map.values().cloned().collect();
         if !default_group.rows.is_empty() {

+ 3 - 5
frontend/rust-lib/flowy-grid/src/services/group/group_generator/select_option_group.rs

@@ -249,11 +249,9 @@ fn move_row(
 ) {
     cell_data.select_options.iter().for_each(|option| {
         // Remove the row in which group contains the row
-        if option.id == group.id {
-            if group.contains_row(&row_rev.id) {
-                group_changeset.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
-                group.remove_row(&row_rev.id);
-            }
+        if option.id == group.id && group.contains_row(&row_rev.id) {
+            group_changeset.push(GroupRowsChangesetPB::delete(group.id.clone(), vec![row_rev.id.clone()]));
+            group.remove_row(&row_rev.id);
         }
 
         // Find the inserted group

+ 13 - 8
frontend/rust-lib/flowy-grid/src/services/group/group_service.rs

@@ -7,7 +7,9 @@ use crate::services::group::{
 };
 use bytes::Bytes;
 use flowy_error::FlowyResult;
-use flowy_grid_data_model::revision::{gen_grid_group_id, FieldRevision, GroupConfigurationRevision, RowRevision, RowChangeset};
+use flowy_grid_data_model::revision::{
+    gen_grid_group_id, FieldRevision, GroupConfigurationRevision, RowChangeset, RowRevision,
+};
 use lib_infra::future::AFFuture;
 use std::future::Future;
 use std::sync::Arc;
@@ -18,7 +20,6 @@ pub trait GroupConfigurationDelegate: Send + Sync + 'static {
 }
 
 pub(crate) struct GroupService {
-    pub groups: Vec<Group>,
     delegate: Box<dyn GroupConfigurationDelegate>,
     group_controller: Option<Arc<RwLock<dyn GroupController>>>,
 }
@@ -26,12 +27,19 @@ pub(crate) struct GroupService {
 impl GroupService {
     pub(crate) async fn new(delegate: Box<dyn GroupConfigurationDelegate>) -> Self {
         Self {
-            groups: vec![],
             delegate,
             group_controller: None,
         }
     }
 
+    pub(crate) async fn groups(&self) -> Vec<Group> {
+        if let Some(group_action_handler) = self.group_controller.as_ref() {
+            group_action_handler.read().await.groups()
+        } else {
+            vec![]
+        }
+    }
+
     pub(crate) async fn load_groups(
         &mut self,
         field_revs: &[Arc<FieldRevision>],
@@ -44,10 +52,7 @@ impl GroupService {
             .build_groups(&field_type, &field_rev, row_revs, configuration)
             .await
         {
-            Ok(groups) => {
-                self.groups = groups.clone();
-                Some(groups)
-            }
+            Ok(groups) => Some(groups),
             Err(_) => None,
         }
     }
@@ -183,7 +188,7 @@ impl GroupService {
         if let Some(group_action_handler) = self.group_controller.as_ref() {
             let mut write_guard = group_action_handler.write().await;
             let _ = write_guard.group_rows(&row_revs, field_rev)?;
-            groups = write_guard.build_groups();
+            groups = write_guard.groups();
             drop(write_guard);
         }
 

+ 1 - 1
frontend/rust-lib/flowy-grid/tests/grid/block_test/script.rs

@@ -56,7 +56,7 @@ pub struct GridRowTest {
 
 impl GridRowTest {
     pub async fn new() -> Self {
-        let editor_test = GridEditorTest::new().await;
+        let editor_test = GridEditorTest::new_table().await;
         Self { inner: editor_test }
     }
 

+ 1 - 1
frontend/rust-lib/flowy-grid/tests/grid/cell_test/script.rs

@@ -11,7 +11,7 @@ pub struct GridCellTest {
 
 impl GridCellTest {
     pub async fn new() -> Self {
-        let inner = GridEditorTest::new().await;
+        let inner = GridEditorTest::new_table().await;
         Self { inner }
     }
 

+ 1 - 1
frontend/rust-lib/flowy-grid/tests/grid/field_test/script.rs

@@ -26,7 +26,7 @@ pub struct GridFieldTest {
 
 impl GridFieldTest {
     pub async fn new() -> Self {
-        let editor_test = GridEditorTest::new().await;
+        let editor_test = GridEditorTest::new_table().await;
         Self { inner: editor_test }
     }
 

+ 1 - 1
frontend/rust-lib/flowy-grid/tests/grid/filter_test/script.rs

@@ -36,7 +36,7 @@ pub struct GridFilterTest {
 
 impl GridFilterTest {
     pub async fn new() -> Self {
-        let editor_test =  GridEditorTest::new().await;
+        let editor_test =  GridEditorTest::new_table().await;
         Self {
             inner: editor_test
         }

+ 15 - 2
frontend/rust-lib/flowy-grid/tests/grid/grid_editor.rs

@@ -36,12 +36,25 @@ pub struct GridEditorTest {
 }
 
 impl GridEditorTest {
-    pub async fn new() -> Self {
+    pub async fn new_table() -> Self {
+        Self::new(GridLayout::Table).await
+    }
+
+    pub async fn new_board() -> Self {
+        Self::new(GridLayout::Board).await
+    }
+
+    pub async fn new(layout: GridLayout) -> Self {
         let sdk = FlowySDKTest::default();
         let _ = sdk.init_user().await;
         let build_context = make_test_grid();
         let view_data: Bytes = build_context.into();
-        let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await;
+
+        let test = match layout {
+            GridLayout::Table => ViewTest::new_grid_view(&sdk, view_data.to_vec()).await,
+            GridLayout::Board => ViewTest::new_board_view(&sdk, view_data.to_vec()).await,
+        };
+
         let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
         let field_revs = editor.get_field_revs(None).await.unwrap();
         let block_meta_revs = editor.get_block_meta_revs().await.unwrap();

+ 1 - 0
frontend/rust-lib/flowy-grid/tests/grid/group_test/mod.rs

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

+ 51 - 8
frontend/rust-lib/flowy-grid/tests/grid/group_test/script.rs

@@ -1,9 +1,23 @@
 use crate::grid::grid_editor::GridEditorTest;
-use flowy_grid::entities::MoveRowParams;
+use flowy_grid::entities::{GroupPB, MoveRowParams, RowPB};
 
 pub enum GroupScript {
-    MoveCard { from_row_id: String, to_row_id: String },
+    AssertGroup {
+        group_index: usize,
+        row_count: usize,
+    },
     AssertGroupCount(usize),
+    AssertGroupRow {
+        group_index: usize,
+        row_index: usize,
+        row: RowPB,
+    },
+    MoveRow {
+        from_group_index: usize,
+        from_row_index: usize,
+        to_group_index: usize,
+        to_row_index: usize,
+    },
 }
 
 pub struct GridGroupTest {
@@ -12,7 +26,7 @@ pub struct GridGroupTest {
 
 impl GridGroupTest {
     pub async fn new() -> Self {
-        let editor_test = GridEditorTest::new().await;
+        let editor_test = GridEditorTest::new_board().await;
         Self { inner: editor_test }
     }
 
@@ -24,19 +38,48 @@ impl GridGroupTest {
 
     pub async fn run_script(&mut self, script: GroupScript) {
         match script {
-            GroupScript::MoveCard { from_row_id, to_row_id } => {
+            GroupScript::AssertGroup { group_index, row_count } => {
+                assert_eq!(row_count, self.group_at_index(group_index).await.rows.len());
+            }
+            GroupScript::AssertGroupCount(count) => {
+                let groups = self.editor.load_groups().await.unwrap();
+                assert_eq!(count, groups.len());
+            }
+            GroupScript::MoveRow {
+                from_group_index,
+                from_row_index,
+                to_group_index,
+                to_row_index,
+            } => {
+                let groups: Vec<GroupPB> = self.editor.load_groups().await.unwrap().items;
+                let from_row = groups.get(from_group_index).unwrap().rows.get(from_row_index).unwrap();
+                let to_row = groups.get(to_group_index).unwrap().rows.get(to_row_index).unwrap();
                 let params = MoveRowParams {
                     view_id: self.inner.grid_id.clone(),
-                    from_row_id,
-                    to_row_id,
+                    from_row_id: from_row.id.clone(),
+                    to_row_id: to_row.id.clone(),
                 };
-                let _ = self.editor.move_row(params).await.unwrap();
+
+                self.editor.move_row(params).await.unwrap();
             }
-            GroupScript::AssertGroupCount(count) => {
+            GroupScript::AssertGroupRow {
+                group_index,
+                row_index,
+                row,
+            } => {
                 //
+                let group = self.group_at_index(group_index).await;
+                let compare_row = group.rows.get(row_index).unwrap().clone();
+
+                assert_eq!(row.id, compare_row.id);
             }
         }
     }
+
+    pub async fn group_at_index(&self, index: usize) -> GroupPB {
+        let groups = self.editor.load_groups().await.unwrap().items;
+        groups.get(index).unwrap().clone()
+    }
 }
 
 impl std::ops::Deref for GridGroupTest {

+ 51 - 0
frontend/rust-lib/flowy-grid/tests/grid/group_test/test.rs

@@ -0,0 +1,51 @@
+use crate::grid::group_test::script::GridGroupTest;
+use crate::grid::group_test::script::GroupScript::*;
+
+#[tokio::test]
+async fn board_init_test() {
+    let mut test = GridGroupTest::new().await;
+    let scripts = vec![
+        AssertGroupCount(3),
+        AssertGroup {
+            group_index: 0,
+            row_count: 2,
+        },
+        AssertGroup {
+            group_index: 1,
+            row_count: 2,
+        },
+        AssertGroup {
+            group_index: 2,
+            row_count: 1,
+        },
+    ];
+    test.run_scripts(scripts).await;
+}
+
+#[tokio::test]
+async fn board_move_row_test() {
+    let mut test = GridGroupTest::new().await;
+    let group = test.group_at_index(0).await;
+    let scripts = vec![
+        MoveRow {
+            from_group_index: 0,
+            from_row_index: 0,
+            to_group_index: 1,
+            to_row_index: 1,
+        },
+        AssertGroup {
+            group_index: 0,
+            row_count: 1,
+        },
+        AssertGroup {
+            group_index: 1,
+            row_count: 3,
+        },
+        AssertGroupRow {
+            group_index: 1,
+            row_index: 1,
+            row: group.rows.get(0).unwrap().clone(),
+        },
+    ];
+    test.run_scripts(scripts).await;
+}

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

@@ -184,7 +184,7 @@ impl ViewDataProcessor for TextBlockViewDataProcessor {
         &self,
         user_id: &str,
         view_id: &str,
-        sub_data_type: ViewLayoutTypePB,
+        _sub_data_type: ViewLayoutTypePB,
     ) -> FutureResult<Bytes, FlowyError> {
         let user_id = user_id.to_string();
         let view_id = view_id.to_string();

+ 2 - 2
shared-lib/flowy-sync/src/client_grid/block_revision_pad.rs

@@ -275,7 +275,7 @@ impl std::default::Default for GridBlockRevisionPad {
 #[cfg(test)]
 mod tests {
     use crate::client_grid::GridBlockRevisionPad;
-    use flowy_grid_data_model::revision::{RowMetaChangeset, RowRevision};
+    use flowy_grid_data_model::revision::{RowChangeset, RowRevision};
     use lib_ot::core::TextDelta;
     use std::borrow::Cow;
 
@@ -400,7 +400,7 @@ mod tests {
             visibility: false,
         };
 
-        let changeset = RowMetaChangeset {
+        let changeset = RowChangeset {
             row_id: row.id.clone(),
             height: Some(100),
             visibility: Some(true),