chore: add more tests

This commit is contained in:
appflowy 2022-07-04 15:24:40 +08:00
parent a6c001941e
commit 1f7f0b5880
4 changed files with 105 additions and 62 deletions

View File

@ -43,7 +43,7 @@ class GridRowCacheService {
_delegate = delegate { _delegate = delegate {
// //
delegate.onFieldsChanged(() => _notifier.receive(const GridRowChangeReason.fieldDidChange())); delegate.onFieldsChanged(() => _notifier.receive(const GridRowChangeReason.fieldDidChange()));
_rows = block.rowInfos.map((rowInfo) => buildGridRow(rowInfo)).toList(); _rows = block.rowInfos.map((rowInfo) => buildGridRow(rowInfo.rowId, rowInfo.height.toDouble())).toList();
} }
Future<void> dispose() async { Future<void> dispose() async {
@ -52,7 +52,7 @@ class GridRowCacheService {
await _cellCache.dispose(); await _cellCache.dispose();
} }
void applyChangesets(List<GridRowsChangeset> changesets) { void applyChangesets(List<GridBlockChangeset> changesets) {
for (final changeset in changesets) { for (final changeset in changesets) {
_deleteRows(changeset.deletedRows); _deleteRows(changeset.deletedRows);
_insertRows(changeset.insertedRows); _insertRows(changeset.insertedRows);
@ -80,7 +80,7 @@ class GridRowCacheService {
_notifier.receive(GridRowChangeReason.delete(deletedIndex)); _notifier.receive(GridRowChangeReason.delete(deletedIndex));
} }
void _insertRows(List<IndexRowOrder> insertRows) { void _insertRows(List<IndexRow> insertRows) {
if (insertRows.isEmpty) { if (insertRows.isEmpty) {
return; return;
} }
@ -90,16 +90,16 @@ class GridRowCacheService {
for (final insertRow in insertRows) { for (final insertRow in insertRows) {
final insertIndex = InsertedIndex( final insertIndex = InsertedIndex(
index: insertRow.index, index: insertRow.index,
rowId: insertRow.rowInfo.rowId, rowId: insertRow.rowId,
); );
insertIndexs.add(insertIndex); insertIndexs.add(insertIndex);
newRows.insert(insertRow.index, (buildGridRow(insertRow.rowInfo))); newRows.insert(insertRow.index, (buildGridRow(insertRow.rowId, insertIndex.row.height)));
} }
_notifier.receive(GridRowChangeReason.insert(insertIndexs)); _notifier.receive(GridRowChangeReason.insert(insertIndexs));
} }
void _updateRows(List<UpdatedRowOrder> updatedRows) { void _updateRows(List<UpdatedRow> updatedRows) {
if (updatedRows.isEmpty) { if (updatedRows.isEmpty) {
return; return;
} }
@ -107,14 +107,13 @@ class GridRowCacheService {
final UpdatedIndexs updatedIndexs = UpdatedIndexs(); final UpdatedIndexs updatedIndexs = UpdatedIndexs();
final List<GridRow> newRows = _rows; final List<GridRow> newRows = _rows;
for (final updatedRow in updatedRows) { for (final updatedRow in updatedRows) {
final rowOrder = updatedRow.rowInfo; final rowId = updatedRow.rowId;
final rowId = updatedRow.rowInfo.rowId;
final index = newRows.indexWhere((row) => row.rowId == rowId); final index = newRows.indexWhere((row) => row.rowId == rowId);
if (index != -1) { if (index != -1) {
_rowByRowId[rowId] = updatedRow.row; _rowByRowId[rowId] = updatedRow.row;
newRows.removeAt(index); newRows.removeAt(index);
newRows.insert(index, buildGridRow(rowOrder)); newRows.insert(index, buildGridRow(rowId, updatedRow.row.height.toDouble()));
updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId); updatedIndexs[rowId] = UpdatedIndex(index: index, rowId: rowId);
} }
} }
@ -226,13 +225,13 @@ class GridRowCacheService {
} }
} }
GridRow buildGridRow(BlockRowInfo rowInfo) { GridRow buildGridRow(String rowId, double rowHeight) {
return GridRow( return GridRow(
gridId: gridId, gridId: gridId,
blockId: block.id, blockId: block.id,
fields: _delegate.fields, fields: _delegate.fields,
rowId: rowInfo.rowId, rowId: rowId,
height: rowInfo.height.toDouble(), height: rowHeight,
); );
} }
} }

View File

@ -104,39 +104,54 @@ impl std::convert::From<Vec<GridBlock>> for RepeatedGridBlock {
} }
#[derive(Debug, Clone, Default, ProtoBuf)] #[derive(Debug, Clone, Default, ProtoBuf)]
pub struct IndexRowOrder { pub struct InsertedRow {
#[pb(index = 1)] #[pb(index = 1)]
pub row_info: BlockRowInfo, pub block_id: String,
#[pb(index = 2, one_of)] #[pb(index = 2)]
pub row_id: String,
#[pb(index = 3)]
pub height: i32,
#[pb(index = 4, one_of)]
pub index: Option<i32>, pub index: Option<i32>,
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf)]
pub struct UpdatedRowOrder { pub struct UpdatedRow {
#[pb(index = 1)] #[pb(index = 1)]
pub row_info: BlockRowInfo, pub block_id: String,
#[pb(index = 2)] #[pb(index = 2)]
pub row_id: String,
#[pb(index = 3)]
pub row: Row, pub row: Row,
} }
impl UpdatedRowOrder { impl UpdatedRow {
pub fn new(row_rev: &RowRevision, row: Row) -> Self { pub fn new(row_rev: &RowRevision, row: Row) -> Self {
Self { Self {
row_info: BlockRowInfo::from(row_rev), row_id: row_rev.id.clone(),
block_id: row_rev.block_id.clone(),
row, row,
} }
} }
} }
impl std::convert::From<BlockRowInfo> for IndexRowOrder { impl std::convert::From<BlockRowInfo> for InsertedRow {
fn from(row_info: BlockRowInfo) -> Self { fn from(row_info: BlockRowInfo) -> Self {
Self { row_info, index: None } Self {
row_id: row_info.row_id,
block_id: row_info.block_id,
height: row_info.height,
index: None,
}
} }
} }
impl std::convert::From<&RowRevision> for IndexRowOrder { impl std::convert::From<&RowRevision> for InsertedRow {
fn from(row: &RowRevision) -> Self { fn from(row: &RowRevision) -> Self {
let row_order = BlockRowInfo::from(row); let row_order = BlockRowInfo::from(row);
Self::from(row_order) Self::from(row_order)
@ -144,21 +159,21 @@ impl std::convert::From<&RowRevision> for IndexRowOrder {
} }
#[derive(Debug, Default, ProtoBuf)] #[derive(Debug, Default, ProtoBuf)]
pub struct GridRowsChangeset { pub struct GridBlockChangeset {
#[pb(index = 1)] #[pb(index = 1)]
pub block_id: String, pub block_id: String,
#[pb(index = 2)] #[pb(index = 2)]
pub inserted_rows: Vec<IndexRowOrder>, pub inserted_rows: Vec<InsertedRow>,
#[pb(index = 3)] #[pb(index = 3)]
pub deleted_rows: Vec<GridRowId>, pub deleted_rows: Vec<GridRowId>,
#[pb(index = 4)] #[pb(index = 4)]
pub updated_rows: Vec<UpdatedRowOrder>, pub updated_rows: Vec<UpdatedRow>,
} }
impl GridRowsChangeset { impl GridBlockChangeset {
pub fn insert(block_id: &str, inserted_rows: Vec<IndexRowOrder>) -> Self { pub fn insert(block_id: &str, inserted_rows: Vec<InsertedRow>) -> Self {
Self { Self {
block_id: block_id.to_owned(), block_id: block_id.to_owned(),
inserted_rows, inserted_rows,
@ -176,7 +191,7 @@ impl GridRowsChangeset {
} }
} }
pub fn update(block_id: &str, updated_rows: Vec<UpdatedRowOrder>) -> Self { pub fn update(block_id: &str, updated_rows: Vec<UpdatedRow>) -> Self {
Self { Self {
block_id: block_id.to_owned(), block_id: block_id.to_owned(),
inserted_rows: vec![], inserted_rows: vec![],

View File

@ -1,5 +1,5 @@
use crate::dart_notification::{send_dart_notification, GridNotification}; use crate::dart_notification::{send_dart_notification, GridNotification};
use crate::entities::{BlockRowInfo, CellChangeset, GridRowId, GridRowsChangeset, IndexRowOrder, Row, UpdatedRowOrder}; use crate::entities::{BlockRowInfo, CellChangeset, GridBlockChangeset, GridRowId, InsertedRow, Row, UpdatedRow};
use crate::manager::GridUser; use crate::manager::GridUser;
use crate::services::block_revision_editor::GridBlockRevisionEditor; use crate::services::block_revision_editor::GridBlockRevisionEditor;
use crate::services::persistence::block_index::BlockIndexCache; use crate::services::persistence::block_index::BlockIndexCache;
@ -71,12 +71,12 @@ impl GridBlockManager {
let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?; let _ = self.persistence.insert(&row_rev.block_id, &row_rev.id)?;
let editor = self.get_editor(&row_rev.block_id).await?; let editor = self.get_editor(&row_rev.block_id).await?;
let mut index_row_order = IndexRowOrder::from(&row_rev); let mut index_row_order = InsertedRow::from(&row_rev);
let (row_count, row_index) = editor.create_row(row_rev, start_row_id).await?; let (row_count, row_index) = editor.create_row(row_rev, start_row_id).await?;
index_row_order.index = row_index; index_row_order.index = row_index;
let _ = self let _ = self
.notify_did_update_block(block_id, GridRowsChangeset::insert(block_id, vec![index_row_order])) .notify_did_update_block(block_id, GridBlockChangeset::insert(block_id, vec![index_row_order]))
.await?; .await?;
Ok(row_count) Ok(row_count)
} }
@ -92,7 +92,7 @@ impl GridBlockManager {
let mut row_count = 0; let mut row_count = 0;
for row in row_revs { for row in row_revs {
let _ = self.persistence.insert(&row.block_id, &row.id)?; let _ = self.persistence.insert(&row.block_id, &row.id)?;
let mut row_order = IndexRowOrder::from(&row); let mut row_order = InsertedRow::from(&row);
let (count, index) = editor.create_row(row, None).await?; let (count, index) = editor.create_row(row, None).await?;
row_count = count; row_count = count;
row_order.index = index; row_order.index = index;
@ -101,7 +101,7 @@ impl GridBlockManager {
changesets.push(GridBlockMetaRevisionChangeset::from_row_count(&block_id, row_count)); changesets.push(GridBlockMetaRevisionChangeset::from_row_count(&block_id, row_count));
let _ = self let _ = self
.notify_did_update_block(&block_id, GridRowsChangeset::insert(&block_id, inserted_row_orders)) .notify_did_update_block(&block_id, GridBlockChangeset::insert(&block_id, inserted_row_orders))
.await?; .await?;
} }
@ -118,8 +118,8 @@ impl GridBlockManager {
None => tracing::error!("Internal error: can't find the row with id: {}", changeset.row_id), None => tracing::error!("Internal error: can't find the row with id: {}", changeset.row_id),
Some(row_rev) => { Some(row_rev) => {
if let Some(row) = row_builder(row_rev.clone()) { if let Some(row) = row_builder(row_rev.clone()) {
let row_order = UpdatedRowOrder::new(&row_rev, row); let row_order = UpdatedRow::new(&row_rev, row);
let block_order_changeset = GridRowsChangeset::update(&editor.block_id, vec![row_order]); let block_order_changeset = GridBlockChangeset::update(&editor.block_id, vec![row_order]);
let _ = self let _ = self
.notify_did_update_block(&editor.block_id, block_order_changeset) .notify_did_update_block(&editor.block_id, block_order_changeset)
.await?; .await?;
@ -144,7 +144,7 @@ impl GridBlockManager {
row_id: row_info.row_id, row_id: row_info.row_id,
}; };
let _ = self let _ = self
.notify_did_update_block(&block_id, GridRowsChangeset::delete(&block_id, vec![row_identifier])) .notify_did_update_block(&block_id, GridBlockChangeset::delete(&block_id, vec![row_identifier]))
.await?; .await?;
} }
} }
@ -179,18 +179,19 @@ impl GridBlockManager {
match editor.get_row_revs(Some(vec![Cow::Borrowed(row_id)])).await?.pop() { match editor.get_row_revs(Some(vec![Cow::Borrowed(row_id)])).await?.pop() {
None => {} None => {}
Some(row_rev) => { Some(row_rev) => {
let row_info = BlockRowInfo::from(&row_rev); let insert_row = InsertedRow {
let insert_row = IndexRowOrder { block_id: row_rev.block_id.clone(),
row_info: row_info.clone(), row_id: row_rev.id.clone(),
index: Some(to as i32), index: Some(to as i32),
height: row_rev.height,
}; };
let deleted_row = GridRowId { let deleted_row = GridRowId {
grid_id: self.grid_id.clone(), grid_id: self.grid_id.clone(),
block_id: row_info.block_id, block_id: row_rev.block_id.clone(),
row_id: row_info.row_id, row_id: row_rev.id.clone(),
}; };
let notified_changeset = GridRowsChangeset { let notified_changeset = GridBlockChangeset {
block_id: editor.block_id.clone(), block_id: editor.block_id.clone(),
inserted_rows: vec![insert_row], inserted_rows: vec![insert_row],
deleted_rows: vec![deleted_row], deleted_rows: vec![deleted_row],
@ -257,7 +258,7 @@ impl GridBlockManager {
Ok(snapshots) Ok(snapshots)
} }
async fn notify_did_update_block(&self, block_id: &str, changeset: GridRowsChangeset) -> FlowyResult<()> { async fn notify_did_update_block(&self, block_id: &str, changeset: GridBlockChangeset) -> FlowyResult<()> {
send_dart_notification(block_id, GridNotification::DidUpdateGridBlock) send_dart_notification(block_id, GridNotification::DidUpdateGridBlock)
.payload(changeset) .payload(changeset)
.send(); .send();

View File

@ -1,5 +1,7 @@
use crate::dart_notification::{send_dart_notification, GridNotification};
use crate::entities::{ use crate::entities::{
FieldType, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridSelectOptionFilter, GridTextFilter, FieldType, GridBlockChangeset, GridCheckboxFilter, GridDateFilter, GridNumberFilter, GridRowId,
GridSelectOptionFilter, GridTextFilter, InsertedRow,
}; };
use crate::services::block_manager::GridBlockManager; use crate::services::block_manager::GridBlockManager;
use crate::services::grid_editor_task::GridServiceTaskScheduler; use crate::services::grid_editor_task::GridServiceTaskScheduler;
@ -51,20 +53,43 @@ impl GridFilterService {
.map(|field_rev| (field_rev.id.clone(), field_rev)) .map(|field_rev| (field_rev.id.clone(), field_rev))
.collect::<HashMap<String, Arc<FieldRevision>>>(); .collect::<HashMap<String, Arc<FieldRevision>>>();
let mut show_rows = vec![]; let mut changesets = vec![];
let mut hide_rows = vec![]; for (index, block) in task_context.blocks.into_iter().enumerate() {
for block in task_context.blocks { let mut inserted_rows = vec![];
let mut deleted_rows = vec![];
block.row_revs.iter().for_each(|row_rev| { block.row_revs.iter().for_each(|row_rev| {
let result = filter_row(row_rev, &self.filter_cache, &self.filter_result_cache, &field_revs); let result = filter_row(
index,
if result.is_row_hidden() { row_rev,
hide_rows.push(result.row_id); &self.filter_cache,
&self.filter_result_cache,
&field_revs,
);
if result.is_visible() {
inserted_rows.push(InsertedRow {
row_id: Default::default(),
block_id: Default::default(),
height: 1,
index: Some(result.row_index),
});
} else { } else {
show_rows.push(result.row_id); deleted_rows.push(GridRowId {
grid_id: self.grid_id.clone(),
block_id: block.block_id.clone(),
row_id: result.row_id,
});
} }
}); });
let changeset = GridBlockChangeset {
block_id: block.block_id,
inserted_rows,
deleted_rows,
updated_rows: vec![],
};
changesets.push(changeset);
} }
self.notify(hide_rows, show_rows).await; self.notify(changesets).await;
Ok(()) Ok(())
} }
@ -101,21 +126,23 @@ impl GridFilterService {
} }
} }
async fn notify(&self, _hide_rows: Vec<String>, _show_rows: Vec<String>) { async fn notify(&self, changesets: Vec<GridBlockChangeset>) {
// let notification = GridNotification {}; for changeset in changesets {
// send_dart_notification(grid_id, GridNotification::DidUpdateGridBlock) send_dart_notification(&self.grid_id, GridNotification::DidUpdateGridBlock)
// .payload(notification) .payload(changeset)
// .send(); .send();
}
} }
} }
fn filter_row( fn filter_row(
index: usize,
row_rev: &Arc<RowRevision>, row_rev: &Arc<RowRevision>,
_filter_cache: &Arc<RwLock<FilterCache>>, _filter_cache: &Arc<RwLock<FilterCache>>,
_filter_result_cache: &Arc<RwLock<FilterResultCache>>, _filter_result_cache: &Arc<RwLock<FilterResultCache>>,
_field_revs: &HashMap<FieldId, Arc<FieldRevision>>, _field_revs: &HashMap<FieldId, Arc<FieldRevision>>,
) -> FilterResult { ) -> FilterResult {
let filter_result = FilterResult::new(row_rev); let filter_result = FilterResult::new(index as i32, row_rev);
row_rev.cells.iter().for_each(|(_k, cell_rev)| { row_rev.cells.iter().for_each(|(_k, cell_rev)| {
let _cell_rev: &CellRevision = cell_rev; let _cell_rev: &CellRevision = cell_rev;
}); });
@ -167,13 +194,14 @@ impl FilterResultCache {
#[derive(Default)] #[derive(Default)]
struct FilterResult { struct FilterResult {
row_id: String, row_id: String,
#[allow(dead_code)] row_index: i32,
cell_by_field_id: HashMap<String, bool>, cell_by_field_id: HashMap<String, bool>,
} }
impl FilterResult { impl FilterResult {
fn new(row_rev: &RowRevision) -> Self { fn new(index: i32, row_rev: &RowRevision) -> Self {
Self { Self {
row_index: index,
row_id: row_rev.id.clone(), row_id: row_rev.id.clone(),
cell_by_field_id: row_rev.cells.iter().map(|(k, _)| (k.clone(), true)).collect(), cell_by_field_id: row_rev.cells.iter().map(|(k, _)| (k.clone(), true)).collect(),
} }
@ -184,7 +212,7 @@ impl FilterResult {
self.cell_by_field_id.insert(cell_id.to_owned(), exist); self.cell_by_field_id.insert(cell_id.to_owned(), exist);
} }
fn is_row_hidden(&self) -> bool { fn is_visible(&self) -> bool {
todo!() todo!()
} }
} }