Browse Source

fix: potential test fail because of async channel message (#1613)

Co-authored-by: nathan <[email protected]>
Nathan.fooo 2 năm trước cách đây
mục cha
commit
05f99ee4a4

+ 4 - 0
frontend/rust-lib/flowy-grid/src/services/filter/entities.rs

@@ -105,7 +105,11 @@ impl std::convert::From<&DeleteFilterParams> for FilterType {
 pub struct FilterResultNotification {
     pub view_id: String,
     pub block_id: String,
+
+    // Indicates there will be some new rows being visible from invisible state.
     pub visible_rows: Vec<InsertedRowPB>,
+
+    // Indicates there will be some new rows being invisible from visible state.
     pub invisible_rows: Vec<String>,
 }
 

+ 16 - 11
frontend/rust-lib/flowy-grid/tests/grid/filter_test/checkbox_filter_test.rs

@@ -1,32 +1,37 @@
 use crate::grid::filter_test::script::FilterScript::*;
-use crate::grid::filter_test::script::GridFilterTest;
+use crate::grid::filter_test::script::{FilterRowChanged, GridFilterTest};
 use flowy_grid::entities::CheckboxFilterConditionPB;
 
 #[tokio::test]
 async fn grid_filter_checkbox_is_check_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
     // The initial number of unchecked is 3
     // The initial number of checked is 2
-    let scripts = vec![
-        CreateCheckboxFilter {
-            condition: CheckboxFilterConditionPB::IsChecked,
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 3,
-        },
-    ];
+    let scripts = vec![CreateCheckboxFilter {
+        condition: CheckboxFilterConditionPB::IsChecked,
+        changed: Some(FilterRowChanged {
+            showing_num_of_rows: 0,
+            hiding_num_of_rows: row_count - 3,
+        }),
+    }];
     test.run_scripts(scripts).await;
 }
 
 #[tokio::test]
 async fn grid_filter_checkbox_is_uncheck_test() {
     let mut test = GridFilterTest::new().await;
+    let expected = 3;
+    let row_count = test.row_revs.len();
     let scripts = vec![
         CreateCheckboxFilter {
             condition: CheckboxFilterConditionPB::IsUnChecked,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 3 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }

+ 15 - 3
frontend/rust-lib/flowy-grid/tests/grid/filter_test/checklist_filter_test.rs

@@ -1,15 +1,21 @@
 use crate::grid::filter_test::script::FilterScript::*;
-use crate::grid::filter_test::script::GridFilterTest;
+use crate::grid::filter_test::script::{FilterRowChanged, GridFilterTest};
 use flowy_grid::entities::ChecklistFilterConditionPB;
 
 #[tokio::test]
 async fn grid_filter_checklist_is_incomplete_test() {
     let mut test = GridFilterTest::new().await;
+    let expected = 5;
+    let row_count = test.row_revs.len();
     let scripts = vec![
         CreateChecklistFilter {
             condition: ChecklistFilterConditionPB::IsIncomplete,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 5 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -17,11 +23,17 @@ async fn grid_filter_checklist_is_incomplete_test() {
 #[tokio::test]
 async fn grid_filter_checklist_is_complete_test() {
     let mut test = GridFilterTest::new().await;
+    let expected = 1;
+    let row_count = test.row_revs.len();
     let scripts = vec![
         CreateChecklistFilter {
             condition: ChecklistFilterConditionPB::IsComplete,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 1 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }

+ 36 - 6
frontend/rust-lib/flowy-grid/tests/grid/filter_test/date_filter_test.rs

@@ -1,18 +1,24 @@
 use crate::grid::filter_test::script::FilterScript::*;
-use crate::grid::filter_test::script::GridFilterTest;
+use crate::grid::filter_test::script::{FilterRowChanged, GridFilterTest};
 use flowy_grid::entities::DateFilterConditionPB;
 
 #[tokio::test]
 async fn grid_filter_date_is_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 3;
     let scripts = vec![
         CreateDateFilter {
             condition: DateFilterConditionPB::DateIs,
             start: None,
             end: None,
             timestamp: Some(1647251762),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 3 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -20,14 +26,20 @@ async fn grid_filter_date_is_test() {
 #[tokio::test]
 async fn grid_filter_date_after_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 3;
     let scripts = vec![
         CreateDateFilter {
             condition: DateFilterConditionPB::DateAfter,
             start: None,
             end: None,
             timestamp: Some(1647251762),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 3 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -35,14 +47,20 @@ async fn grid_filter_date_after_test() {
 #[tokio::test]
 async fn grid_filter_date_on_or_after_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 3;
     let scripts = vec![
         CreateDateFilter {
             condition: DateFilterConditionPB::DateOnOrAfter,
             start: None,
             end: None,
             timestamp: Some(1668359085),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 3 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -50,14 +68,20 @@ async fn grid_filter_date_on_or_after_test() {
 #[tokio::test]
 async fn grid_filter_date_on_or_before_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 4;
     let scripts = vec![
         CreateDateFilter {
             condition: DateFilterConditionPB::DateOnOrBefore,
             start: None,
             end: None,
             timestamp: Some(1668359085),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 4 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -65,14 +89,20 @@ async fn grid_filter_date_on_or_before_test() {
 #[tokio::test]
 async fn grid_filter_date_within_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 5;
     let scripts = vec![
         CreateDateFilter {
             condition: DateFilterConditionPB::DateWithIn,
             start: Some(1647251762),
             end: Some(1668704685),
             timestamp: None,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 5 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }

+ 43 - 7
frontend/rust-lib/flowy-grid/tests/grid/filter_test/number_filter_test.rs

@@ -1,16 +1,22 @@
 use crate::grid::filter_test::script::FilterScript::*;
-use crate::grid::filter_test::script::GridFilterTest;
+use crate::grid::filter_test::script::{FilterRowChanged, GridFilterTest};
 use flowy_grid::entities::NumberFilterConditionPB;
 
 #[tokio::test]
 async fn grid_filter_number_is_equal_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 1;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::Equal,
             content: "1".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 1 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -18,12 +24,18 @@ async fn grid_filter_number_is_equal_test() {
 #[tokio::test]
 async fn grid_filter_number_is_less_than_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 2;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::LessThan,
             content: "3".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 2 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -32,12 +44,18 @@ async fn grid_filter_number_is_less_than_test() {
 #[should_panic]
 async fn grid_filter_number_is_less_than_test2() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 2;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::LessThan,
             content: "$3".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 2 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -45,12 +63,18 @@ async fn grid_filter_number_is_less_than_test2() {
 #[tokio::test]
 async fn grid_filter_number_is_less_than_or_equal_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 3;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::LessThanOrEqualTo,
             content: "3".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 3 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -58,12 +82,18 @@ async fn grid_filter_number_is_less_than_or_equal_test() {
 #[tokio::test]
 async fn grid_filter_number_is_empty_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 1;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::NumberIsEmpty,
             content: "".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 1 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -71,12 +101,18 @@ async fn grid_filter_number_is_empty_test() {
 #[tokio::test]
 async fn grid_filter_number_is_not_empty_test() {
     let mut test = GridFilterTest::new().await;
+    let row_count = test.row_revs.len();
+    let expected = 5;
     let scripts = vec![
         CreateNumberFilter {
             condition: NumberFilterConditionPB::NumberIsNotEmpty,
             content: "".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 5 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }

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

@@ -17,14 +17,21 @@ use flowy_grid::services::filter::FilterType;
 use flowy_grid::services::view_editor::GridViewChanged;
 use crate::grid::grid_editor::GridEditorTest;
 
+pub struct FilterRowChanged {
+    pub(crate) showing_num_of_rows: usize,
+    pub(crate) hiding_num_of_rows: usize,
+}
+
 pub enum FilterScript {
     UpdateTextCell {
         row_id: String,
         text: String,
+       changed: Option<FilterRowChanged>,
     },
     UpdateSingleSelectCell {
         row_id: String,
         option_id: String,
+        changed: Option<FilterRowChanged>,
     },
     InsertFilter {
         payload: AlterFilterPayloadPB,
@@ -32,24 +39,29 @@ pub enum FilterScript {
     CreateTextFilter {
         condition: TextFilterConditionPB,
         content: String,
+        changed: Option<FilterRowChanged>,
     },
     UpdateTextFilter {
         filter: FilterPB,
         condition: TextFilterConditionPB,
         content: String,
+        changed: Option<FilterRowChanged>,
     },
     CreateNumberFilter {
         condition: NumberFilterConditionPB,
         content: String,
+        changed: Option<FilterRowChanged>,
     },
     CreateCheckboxFilter {
         condition: CheckboxFilterConditionPB,
+        changed: Option<FilterRowChanged>,
     },
     CreateDateFilter{
         condition: DateFilterConditionPB,
         start: Option<i64>,
         end: Option<i64>,
         timestamp: Option<i64>,
+        changed: Option<FilterRowChanged>,
     },
     CreateMultiSelectFilter {
         condition: SelectOptionConditionPB,
@@ -58,9 +70,11 @@ pub enum FilterScript {
     CreateSingleSelectFilter {
         condition: SelectOptionConditionPB,
         option_ids: Vec<String>,
+        changed: Option<FilterRowChanged>,
     },
     CreateChecklistFilter {
         condition: ChecklistFilterConditionPB,
+        changed: Option<FilterRowChanged>,
     },
     AssertFilterCount {
         count: i32,
@@ -68,6 +82,7 @@ pub enum FilterScript {
     DeleteFilter {
         filter_id: String,
         filter_type: FilterType,
+        changed: Option<FilterRowChanged>,
     },
     AssertFilterContent {
         filter_type: FilterType,
@@ -77,10 +92,6 @@ pub enum FilterScript {
     AssertNumberOfVisibleRows {
         expected: usize,
     },
-    AssertFilterChanged{
-        visible_row_len:usize,
-        hide_row_len: usize,
-    },
     #[allow(dead_code)]
     AssertGridSetting {
         expected_setting: GridSettingPB,
@@ -118,20 +129,23 @@ impl GridFilterTest {
 
     pub async fn run_script(&mut self, script: FilterScript) {
         match script {
-            FilterScript::UpdateTextCell { row_id, text} => {
+            FilterScript::UpdateTextCell { row_id, text, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 self.update_text_cell(row_id, &text).await;
             }
-            FilterScript::UpdateSingleSelectCell { row_id, option_id} => {
+            FilterScript::UpdateSingleSelectCell { row_id, option_id, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 self.update_single_select_cell(row_id, &option_id).await;
             }
             FilterScript::InsertFilter { payload } => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
                 self.insert_filter(payload).await;
             }
-            FilterScript::CreateTextFilter { condition, content} => {
+            FilterScript::CreateTextFilter { condition, content, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::RichText);
                 let text_filter= TextFilterPB {
                     condition,
@@ -143,8 +157,9 @@ impl GridFilterTest {
                         field_rev, text_filter);
                 self.insert_filter(payload).await;
             }
-            FilterScript::UpdateTextFilter { filter, condition, content} => {
+            FilterScript::UpdateTextFilter { filter, condition, content, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let params = AlterFilterParams {
                     view_id: self.view_id(),
                     field_id: filter.field_id,
@@ -155,8 +170,9 @@ impl GridFilterTest {
                 };
                 self.editor.create_or_update_filter(params).await.unwrap();
             }
-            FilterScript::CreateNumberFilter {condition, content} => {
+            FilterScript::CreateNumberFilter {condition, content, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::Number);
                 let number_filter = NumberFilterPB {
                     condition,
@@ -168,8 +184,9 @@ impl GridFilterTest {
                         field_rev, number_filter);
                 self.insert_filter(payload).await;
             }
-            FilterScript::CreateCheckboxFilter {condition} => {
+            FilterScript::CreateCheckboxFilter {condition, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::Checkbox);
                 let checkbox_filter = CheckboxFilterPB {
                     condition
@@ -178,8 +195,9 @@ impl GridFilterTest {
                     AlterFilterPayloadPB::new(& self.view_id(), field_rev, checkbox_filter);
                 self.insert_filter(payload).await;
             }
-            FilterScript::CreateDateFilter { condition, start, end, timestamp} => {
+            FilterScript::CreateDateFilter { condition, start, end, timestamp, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::DateTime);
                 let date_filter = DateFilterPB {
                     condition,
@@ -200,16 +218,18 @@ impl GridFilterTest {
                     AlterFilterPayloadPB::new( &self.view_id(),field_rev, filter);
                 self.insert_filter(payload).await;
             }
-            FilterScript::CreateSingleSelectFilter { condition, option_ids} => {
+            FilterScript::CreateSingleSelectFilter { condition, option_ids, changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::SingleSelect);
                 let filter = SelectOptionFilterPB { condition, option_ids };
                 let payload =
                     AlterFilterPayloadPB::new(& self.view_id(),field_rev, filter);
                 self.insert_filter(payload).await;
             }
-            FilterScript::CreateChecklistFilter { condition} => {
+            FilterScript::CreateChecklistFilter { condition,changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let field_rev = self.get_first_field_rev(FieldType::Checklist);
                 // let type_option = self.get_checklist_type_option(&field_rev.id);
                 let filter = ChecklistFilterPB { condition };
@@ -227,8 +247,9 @@ impl GridFilterTest {
                 assert_eq!(filter.condition as u32, condition);
 
             }
-            FilterScript::DeleteFilter {  filter_id, filter_type } => {
+            FilterScript::DeleteFilter {  filter_id, filter_type ,changed} => {
                 self.recv = Some(self.editor.subscribe_view_changed(&self.view_id()).await.unwrap());
+                self.assert_future_changed(changed).await;
                 let params = DeleteFilterParams { view_id: self.view_id(),filter_type, filter_id };
                 let _ = self.editor.delete_filter(params).await.unwrap();
             }
@@ -236,25 +257,6 @@ impl GridFilterTest {
                 let setting = self.editor.get_setting().await.unwrap();
                 assert_eq!(expected_setting, setting);
             }
-            FilterScript::AssertFilterChanged { visible_row_len, hide_row_len} => {
-                if let Some(mut receiver) = self.recv.take() {
-                    match tokio::time::timeout(Duration::from_secs(2), receiver.recv()).await {
-                        Ok(changed) =>  {
-                            //
-                            match changed.unwrap() { GridViewChanged::FilterNotification(changed) => {
-                                assert_eq!(changed.visible_rows.len(), visible_row_len, "visible rows not match");
-                                assert_eq!(changed.invisible_rows.len(), hide_row_len, "invisible rows not match");
-                            }
-                                _ => {}
-                            }
-                        },
-                        Err(e) => {
-                            panic!("Process filter task timeout: {:?}", e);
-                        }
-                    }
-                }
-
-            }
             FilterScript::AssertNumberOfVisibleRows { expected } => {
                 let grid = self.editor.get_grid(&self.view_id()).await.unwrap();
                 assert_eq!(grid.rows.len(), expected);
@@ -265,6 +267,29 @@ impl GridFilterTest {
         }
     }
 
+    async fn assert_future_changed(&mut self, change: Option<FilterRowChanged>) {
+        if change.is_none() {return;}
+        let change = change.unwrap();
+        let mut receiver = self.recv.take().unwrap();
+        tokio::spawn(async move {
+            match tokio::time::timeout(Duration::from_secs(2), receiver.recv()).await {
+                Ok(changed) =>  {
+                    match changed.unwrap() { GridViewChanged::FilterNotification(notification) => {
+                        assert_eq!(notification.visible_rows.len(), change.showing_num_of_rows, "visible rows not match");
+                        assert_eq!(notification.invisible_rows.len(), change.hiding_num_of_rows, "invisible rows not match");
+                    }
+                        _ => {}
+                    }
+                },
+                Err(e) => {
+                    panic!("Process filter task timeout: {:?}", e);
+                }
+            }
+        });
+
+
+    }
+
     async fn insert_filter(&self, payload: AlterFilterPayloadPB) {
         let params: AlterFilterParams = payload.try_into().unwrap();
         let _ = self.editor.create_or_update_filter(params).await.unwrap();

+ 25 - 6
frontend/rust-lib/flowy-grid/tests/grid/filter_test/select_option_filter_test.rs

@@ -1,5 +1,5 @@
 use crate::grid::filter_test::script::FilterScript::*;
-use crate::grid::filter_test::script::GridFilterTest;
+use crate::grid::filter_test::script::{FilterRowChanged, GridFilterTest};
 use flowy_grid::entities::{FieldType, SelectOptionConditionPB};
 
 #[tokio::test]
@@ -61,12 +61,18 @@ async fn grid_filter_multi_select_is_test2() {
 #[tokio::test]
 async fn grid_filter_single_select_is_empty_test() {
     let mut test = GridFilterTest::new().await;
+    let expected = 2;
+    let row_count = test.row_revs.len();
     let scripts = vec![
         CreateSingleSelectFilter {
             condition: SelectOptionConditionPB::OptionIsEmpty,
             option_ids: vec![],
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
-        AssertNumberOfVisibleRows { expected: 2 },
+        AssertNumberOfVisibleRows { expected },
     ];
     test.run_scripts(scripts).await;
 }
@@ -76,10 +82,16 @@ async fn grid_filter_single_select_is_test() {
     let mut test = GridFilterTest::new().await;
     let field_rev = test.get_first_field_rev(FieldType::SingleSelect);
     let mut options = test.get_single_select_type_option(&field_rev.id).options;
+    let expected = 2;
+    let row_count = test.row_revs.len();
     let scripts = vec![
         CreateSingleSelectFilter {
             condition: SelectOptionConditionPB::OptionIs,
             option_ids: vec![options.remove(0).id],
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - expected,
+            }),
         },
         AssertNumberOfVisibleRows { expected: 2 },
     ];
@@ -93,24 +105,31 @@ async fn grid_filter_single_select_is_test2() {
     let row_revs = test.get_row_revs().await;
     let mut options = test.get_single_select_type_option(&field_rev.id).options;
     let option = options.remove(0);
+    let row_count = test.row_revs.len();
+
     let scripts = vec![
         CreateSingleSelectFilter {
             condition: SelectOptionConditionPB::OptionIs,
             option_ids: vec![option.id.clone()],
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: row_count - 2,
+            }),
         },
         AssertNumberOfVisibleRows { expected: 2 },
         UpdateSingleSelectCell {
             row_id: row_revs[1].id.clone(),
             option_id: option.id.clone(),
+            changed: None,
         },
         AssertNumberOfVisibleRows { expected: 3 },
         UpdateSingleSelectCell {
             row_id: row_revs[1].id.clone(),
             option_id: "".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 1,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 1,
+            }),
         },
         AssertNumberOfVisibleRows { expected: 2 },
     ];

+ 71 - 70
frontend/rust-lib/flowy-grid/tests/grid/filter_test/text_filter_test.rs

@@ -10,12 +10,12 @@ async fn grid_filter_text_is_empty_test() {
         CreateTextFilter {
             condition: TextFilterConditionPB::TextIsEmpty,
             content: "".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 5,
+            }),
         },
         AssertFilterCount { count: 1 },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 5,
-        },
     ];
     test.run_scripts(scripts).await;
 }
@@ -28,13 +28,12 @@ async fn grid_filter_text_is_not_empty_test() {
         CreateTextFilter {
             condition: TextFilterConditionPB::TextIsNotEmpty,
             content: "".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 1,
+            }),
         },
         AssertFilterCount { count: 1 },
-        // There is only one row in the test data that its text is empty
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 1,
-        },
     ];
     test.run_scripts(scripts).await;
 
@@ -44,12 +43,12 @@ async fn grid_filter_text_is_not_empty_test() {
         DeleteFilter {
             filter_id: filter.id,
             filter_type: FilterType::from(&field_rev),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 1,
+                hiding_num_of_rows: 0,
+            }),
         },
         AssertFilterCount { count: 0 },
-        AssertFilterChanged {
-            visible_row_len: 1,
-            hide_row_len: 0,
-        },
     ])
     .await;
 }
@@ -58,32 +57,28 @@ async fn grid_filter_text_is_not_empty_test() {
 async fn grid_filter_is_text_test() {
     let mut test = GridFilterTest::new().await;
     // Only one row's text of the initial rows is "A"
-    let scripts = vec![
-        CreateTextFilter {
-            condition: TextFilterConditionPB::Is,
-            content: "A".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 5,
-        },
-    ];
+    let scripts = vec![CreateTextFilter {
+        condition: TextFilterConditionPB::Is,
+        content: "A".to_string(),
+        changed: Some(FilterRowChanged {
+            showing_num_of_rows: 0,
+            hiding_num_of_rows: 5,
+        }),
+    }];
     test.run_scripts(scripts).await;
 }
 
 #[tokio::test]
 async fn grid_filter_contain_text_test() {
     let mut test = GridFilterTest::new().await;
-    let scripts = vec![
-        CreateTextFilter {
-            condition: TextFilterConditionPB::Contains,
-            content: "A".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 2,
-        },
-    ];
+    let scripts = vec![CreateTextFilter {
+        condition: TextFilterConditionPB::Contains,
+        content: "A".to_string(),
+        changed: Some(FilterRowChanged {
+            showing_num_of_rows: 0,
+            hiding_num_of_rows: 2,
+        }),
+    }];
     test.run_scripts(scripts).await;
 }
 
@@ -96,18 +91,18 @@ async fn grid_filter_contain_text_test2() {
         CreateTextFilter {
             condition: TextFilterConditionPB::Contains,
             content: "A".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 2,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 2,
+            }),
         },
         UpdateTextCell {
             row_id: row_revs[1].id.clone(),
             text: "ABC".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 1,
-            hide_row_len: 0,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 1,
+                hiding_num_of_rows: 0,
+            }),
         },
     ];
     test.run_scripts(scripts).await;
@@ -117,32 +112,28 @@ async fn grid_filter_contain_text_test2() {
 async fn grid_filter_does_not_contain_text_test() {
     let mut test = GridFilterTest::new().await;
     // None of the initial rows contains the text "AB"
-    let scripts = vec![
-        CreateTextFilter {
-            condition: TextFilterConditionPB::DoesNotContain,
-            content: "AB".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 0,
-        },
-    ];
+    let scripts = vec![CreateTextFilter {
+        condition: TextFilterConditionPB::DoesNotContain,
+        content: "AB".to_string(),
+        changed: Some(FilterRowChanged {
+            showing_num_of_rows: 0,
+            hiding_num_of_rows: 0,
+        }),
+    }];
     test.run_scripts(scripts).await;
 }
 
 #[tokio::test]
 async fn grid_filter_start_with_text_test() {
     let mut test = GridFilterTest::new().await;
-    let scripts = vec![
-        CreateTextFilter {
-            condition: TextFilterConditionPB::StartsWith,
-            content: "A".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 3,
-        },
-    ];
+    let scripts = vec![CreateTextFilter {
+        condition: TextFilterConditionPB::StartsWith,
+        content: "A".to_string(),
+        changed: Some(FilterRowChanged {
+            showing_num_of_rows: 0,
+            hiding_num_of_rows: 3,
+        }),
+    }];
     test.run_scripts(scripts).await;
 }
 
@@ -153,6 +144,7 @@ async fn grid_filter_ends_with_text_test() {
         CreateTextFilter {
             condition: TextFilterConditionPB::EndsWith,
             content: "A".to_string(),
+            changed: None,
         },
         AssertNumberOfVisibleRows { expected: 2 },
     ];
@@ -166,8 +158,13 @@ async fn grid_update_text_filter_test() {
         CreateTextFilter {
             condition: TextFilterConditionPB::EndsWith,
             content: "A".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 4,
+            }),
         },
         AssertNumberOfVisibleRows { expected: 2 },
+        AssertFilterCount { count: 1 },
     ];
     test.run_scripts(scripts).await;
 
@@ -178,9 +175,12 @@ async fn grid_update_text_filter_test() {
             filter,
             condition: TextFilterConditionPB::Is,
             content: "A".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 1,
+            }),
         },
         AssertNumberOfVisibleRows { expected: 1 },
-        AssertFilterCount { count: 1 },
     ];
     test.run_scripts(scripts).await;
 }
@@ -206,6 +206,7 @@ async fn grid_filter_delete_test() {
         DeleteFilter {
             filter_id: filter.id,
             filter_type: FilterType::from(&field_rev),
+            changed: None,
         },
         AssertFilterCount { count: 0 },
         AssertNumberOfVisibleRows { expected: 6 },
@@ -221,19 +222,19 @@ async fn grid_filter_update_empty_text_cell_test() {
         CreateTextFilter {
             condition: TextFilterConditionPB::TextIsEmpty,
             content: "".to_string(),
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 0,
+                hiding_num_of_rows: 5,
+            }),
         },
         AssertFilterCount { count: 1 },
-        AssertFilterChanged {
-            visible_row_len: 0,
-            hide_row_len: 5,
-        },
         UpdateTextCell {
             row_id: row_revs[0].id.clone(),
             text: "".to_string(),
-        },
-        AssertFilterChanged {
-            visible_row_len: 1,
-            hide_row_len: 0,
+            changed: Some(FilterRowChanged {
+                showing_num_of_rows: 1,
+                hiding_num_of_rows: 0,
+            }),
         },
     ];
     test.run_scripts(scripts).await;