chore: update test

This commit is contained in:
appflowy 2022-06-23 23:06:03 +08:00
parent ead305ddda
commit a08590bcba
11 changed files with 236 additions and 170 deletions

View File

@ -1,3 +1,4 @@
use crate::grid::field_util::make_date_cell_string;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid::services::field::{MultiSelectTypeOption, SelectOptionCellContentChangeset, SingleSelectTypeOption}; use flowy_grid::services::field::{MultiSelectTypeOption, SelectOptionCellContentChangeset, SingleSelectTypeOption};

View File

@ -1,3 +1,4 @@
use crate::grid::field_util::*;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use flowy_grid::services::field::{SelectOption, SingleSelectTypeOption}; use flowy_grid::services::field::{SelectOption, SingleSelectTypeOption};

View File

@ -0,0 +1,84 @@
use flowy_grid::services::field::*;
use flowy_grid::services::grid_editor::{GridPadBuilder, GridRevisionEditor};
use flowy_grid::services::row::CreateRowRevisionPayload;
use flowy_grid::services::setting::GridSettingChangesetBuilder;
use flowy_grid_data_model::entities::*;
use flowy_grid_data_model::revision::*;
use flowy_sync::client_grid::GridBuilder;
pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
let field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())
.name("Name")
.visibility(true)
.build();
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<RichTextTypeOption>(&field_rev.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();
let field = Field {
id: field_rev.id,
name: field_rev.name,
desc: field_rev.desc,
field_type: field_rev.field_type,
frozen: field_rev.frozen,
visibility: field_rev.visibility,
width: field_rev.width,
is_primary: false,
};
let params = InsertFieldParams {
grid_id: grid_id.to_owned(),
field,
type_option_data,
start_field_id: None,
};
(params, cloned_field_rev)
}
pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
let single_select = SingleSelectTypeOptionBuilder::default()
.option(SelectOption::new("Done"))
.option(SelectOption::new("Progress"));
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<SingleSelectTypeOption>(&field_rev.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();
let field = Field {
id: field_rev.id,
name: field_rev.name,
desc: field_rev.desc,
field_type: field_rev.field_type,
frozen: field_rev.frozen,
visibility: field_rev.visibility,
width: field_rev.width,
is_primary: false,
};
let params = InsertFieldParams {
grid_id: grid_id.to_owned(),
field,
type_option_data,
start_field_id: None,
};
(params, cloned_field_rev)
}
// The grid will contains all existing field types and there are three empty rows in this grid.
pub fn make_date_cell_string(s: &str) -> String {
serde_json::to_string(&DateCellContentChangeset {
date: Some(s.to_string()),
time: None,
})
.unwrap()
}

View File

@ -0,0 +1,46 @@
use crate::grid::script::EditorScript::*;
use crate::grid::script::*;
use flowy_grid_data_model::entities::{
CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, TextFilterCondition,
};
#[tokio::test]
async fn grid_setting_create_text_filter_test() {
let test = GridEditorTest::new().await;
let field_rev = test.text_field();
let payload = CreateGridFilterPayload::new(field_rev, TextFilterCondition::TextIsEmpty, Some("abc".to_owned()));
let scripts = vec![InsertGridTableFilter { payload }, AssertTableFilterCount { count: 1 }];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
#[should_panic]
async fn grid_setting_create_text_filter_panic_test() {
let test = GridEditorTest::new().await;
let field_rev = test.text_field();
// 100 is not a valid condition, so this test should be panic.
let payload = CreateGridFilterPayload::new(field_rev, 100, Some("abc".to_owned()));
let scripts = vec![InsertGridTableFilter { payload }];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn grid_setting_delete_text_filter_test() {
let mut test = GridEditorTest::new().await;
let field_rev = test.text_field();
let payload = CreateGridFilterPayload::new(field_rev, 100, Some("abc".to_owned()));
let scripts = vec![InsertGridTableFilter { payload }, AssertTableFilterCount { count: 1 }];
test.run_scripts(scripts).await;
let filter = test.grid_filters().await.pop().unwrap();
test.run_scripts(vec![
DeleteGridTableFilter { filter_id: filter.id },
AssertTableFilterCount { count: 0 },
])
.await;
}
#[tokio::test]
async fn grid_setting_sort_test() {}

View File

@ -1,6 +1,8 @@
mod block_test; mod block_test;
mod cell_test; mod cell_test;
mod field_test; mod field_test;
mod field_util;
mod filter_test;
mod row_test; mod row_test;
mod row_util;
mod script; mod script;
mod setting_test;

View File

@ -1,23 +1,26 @@
use crate::grid::field_util::*;
use crate::grid::row_util::GridRowTestBuilder;
use crate::grid::script::EditorScript::*; use crate::grid::script::EditorScript::*;
use crate::grid::script::*; use crate::grid::script::*;
use chrono::NaiveDateTime; use chrono::NaiveDateTime;
use flowy_grid::services::field::{ use flowy_grid::services::field::{
DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR, DateCellData, MultiSelectTypeOption, SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
}; };
use flowy_grid::services::row::{decode_cell_data_from_type_option_cell_data, CreateRowRevisionBuilder}; use flowy_grid::services::row::{
decode_cell_data_from_type_option_cell_data, CreateRowRevisionBuilder, CreateRowRevisionPayload,
};
use flowy_grid_data_model::entities::FieldType; use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::RowMetaChangeset; use flowy_grid_data_model::revision::{FieldRevision, RowMetaChangeset};
#[tokio::test] #[tokio::test]
async fn grid_create_row_count_test() { async fn grid_create_row_count_test() {
let test = GridEditorTest::new().await; let test = GridEditorTest::new().await;
let create_row_context = CreateRowRevisionBuilder::new(&test.field_revs).build();
let scripts = vec![ let scripts = vec![
AssertRowCount(3), AssertRowCount(3),
CreateEmptyRow, CreateEmptyRow,
CreateEmptyRow, CreateEmptyRow,
CreateRow { CreateRow {
context: create_row_context, payload: GridRowTestBuilder::new(&test).build(),
}, },
AssertRowCount(6), AssertRowCount(6),
]; ];
@ -27,15 +30,15 @@ async fn grid_create_row_count_test() {
#[tokio::test] #[tokio::test]
async fn grid_update_row() { async fn grid_update_row() {
let mut test = GridEditorTest::new().await; let mut test = GridEditorTest::new().await;
let context = CreateRowRevisionBuilder::new(&test.field_revs).build(); let payload = GridRowTestBuilder::new(&test).build();
let changeset = RowMetaChangeset { let changeset = RowMetaChangeset {
row_id: context.row_id.clone(), row_id: payload.row_id.clone(),
height: None, height: None,
visibility: None, visibility: None,
cell_by_field_id: Default::default(), cell_by_field_id: Default::default(),
}; };
let scripts = vec![AssertRowCount(3), CreateRow { context }, UpdateRow { changeset }]; let scripts = vec![AssertRowCount(3), CreateRow { payload }, UpdateRow { changeset }];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
let expected_row = (&*test.row_revs.last().cloned().unwrap()).clone(); let expected_row = (&*test.row_revs.last().cloned().unwrap()).clone();
@ -46,13 +49,13 @@ async fn grid_update_row() {
#[tokio::test] #[tokio::test]
async fn grid_delete_row() { async fn grid_delete_row() {
let mut test = GridEditorTest::new().await; let mut test = GridEditorTest::new().await;
let context_1 = CreateRowRevisionBuilder::new(&test.field_revs).build(); let payload1 = GridRowTestBuilder::new(&test).build();
let context_2 = CreateRowRevisionBuilder::new(&test.field_revs).build(); let payload2 = GridRowTestBuilder::new(&test).build();
let row_ids = vec![context_1.row_id.clone(), context_2.row_id.clone()]; let row_ids = vec![payload1.row_id.clone(), payload2.row_id.clone()];
let scripts = vec![ let scripts = vec![
AssertRowCount(3), AssertRowCount(3),
CreateRow { context: context_1 }, CreateRow { payload: payload1 },
CreateRow { context: context_2 }, CreateRow { payload: payload2 },
AssertBlockCount(1), AssertBlockCount(1),
AssertBlock { AssertBlock {
block_index: 0, block_index: 0,
@ -110,7 +113,7 @@ async fn grid_row_add_cells_test() {
} }
} }
let context = builder.build(); let context = builder.build();
let scripts = vec![CreateRow { context }, AssertGridRevisionPad]; let scripts = vec![CreateRow { payload: context }, AssertGridRevisionPad];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
} }
@ -142,6 +145,6 @@ async fn grid_row_add_date_cell_test() {
.date, .date,
"2022/03/16", "2022/03/16",
); );
let scripts = vec![CreateRow { context }]; let scripts = vec![CreateRow { payload: context }];
test.run_scripts(scripts).await; test.run_scripts(scripts).await;
} }

View File

@ -0,0 +1,32 @@
use crate::grid::script::GridEditorTest;
use flowy_grid::services::row::{CreateRowRevisionBuilder, CreateRowRevisionPayload};
use flowy_grid_data_model::entities::FieldType;
use flowy_grid_data_model::revision::FieldRevision;
use strum::EnumCount;
pub struct GridRowTestBuilder<'a> {
test: &'a GridEditorTest,
inner_builder: CreateRowRevisionBuilder<'a>,
}
impl<'a> GridRowTestBuilder<'a> {
pub fn new(test: &'a GridEditorTest) -> Self {
assert_eq!(test.field_revs.len(), FieldType::COUNT);
let inner_builder = CreateRowRevisionBuilder::new(&test.field_revs);
Self { test, inner_builder }
}
pub fn update_text_cell(&mut self) -> Self {
let text_field = self
.test
.field_revs
.iter()
.find(|field_rev| field_rev.field_type == FieldType::RichText);
// self.inner_builder
}
pub fn build(self) -> CreateRowRevisionPayload {
self.inner_builder.build()
}
}

View File

@ -48,7 +48,7 @@ pub enum EditorScript {
}, },
CreateEmptyRow, CreateEmptyRow,
CreateRow { CreateRow {
context: CreateRowRevisionPayload, payload: CreateRowRevisionPayload,
}, },
UpdateRow { UpdateRow {
changeset: RowMetaChangeset, changeset: RowMetaChangeset,
@ -98,7 +98,7 @@ impl GridEditorTest {
pub async fn new() -> Self { pub async fn new() -> Self {
let sdk = FlowySDKTest::default(); let sdk = FlowySDKTest::default();
let _ = sdk.init_user().await; let _ = sdk.init_user().await;
let build_context = make_test_grid(); let build_context = make_all_field_test_grid();
let view_data: Bytes = build_context.into(); let view_data: Bytes = build_context.into();
let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await; let test = ViewTest::new_grid_view(&sdk, view_data.to_vec()).await;
let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap(); let editor = sdk.grid_manager.open_grid(&test.view.id).await.unwrap();
@ -199,7 +199,7 @@ impl GridEditorTest {
self.row_revs = self.get_row_revs().await; self.row_revs = self.get_row_revs().await;
self.grid_block_revs = self.editor.get_block_metas().await.unwrap(); self.grid_block_revs = self.editor.get_block_metas().await.unwrap();
} }
EditorScript::CreateRow { context } => { EditorScript::CreateRow { payload: context } => {
let row_orders = self.editor.insert_rows(vec![context]).await.unwrap(); let row_orders = self.editor.insert_rows(vec![context]).await.unwrap();
for row_order in row_orders { for row_order in row_orders {
self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order); self.row_order_by_row_id.insert(row_order.row_id.clone(), row_order);
@ -307,74 +307,7 @@ impl GridEditorTest {
} }
} }
pub fn create_text_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) { fn make_all_field_test_grid() -> BuildGridContext {
let field_rev = FieldBuilder::new(RichTextTypeOptionBuilder::default())
.name("Name")
.visibility(true)
.build();
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<RichTextTypeOption>(&field_rev.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();
let field = Field {
id: field_rev.id,
name: field_rev.name,
desc: field_rev.desc,
field_type: field_rev.field_type,
frozen: field_rev.frozen,
visibility: field_rev.visibility,
width: field_rev.width,
is_primary: false,
};
let params = InsertFieldParams {
grid_id: grid_id.to_owned(),
field,
type_option_data,
start_field_id: None,
};
(params, cloned_field_rev)
}
pub fn create_single_select_field(grid_id: &str) -> (InsertFieldParams, FieldRevision) {
let single_select = SingleSelectTypeOptionBuilder::default()
.option(SelectOption::new("Done"))
.option(SelectOption::new("Progress"));
let field_rev = FieldBuilder::new(single_select).name("Name").visibility(true).build();
let cloned_field_rev = field_rev.clone();
let type_option_data = field_rev
.get_type_option_entry::<SingleSelectTypeOption>(&field_rev.field_type)
.unwrap()
.protobuf_bytes()
.to_vec();
let field = Field {
id: field_rev.id,
name: field_rev.name,
desc: field_rev.desc,
field_type: field_rev.field_type,
frozen: field_rev.frozen,
visibility: field_rev.visibility,
width: field_rev.width,
is_primary: false,
};
let params = InsertFieldParams {
grid_id: grid_id.to_owned(),
field,
type_option_data,
start_field_id: None,
};
(params, cloned_field_rev)
}
fn make_test_grid() -> BuildGridContext {
let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default()) let text_field = FieldBuilder::new(RichTextTypeOptionBuilder::default())
.name("Name") .name("Name")
.visibility(true) .visibility(true)
@ -429,11 +362,3 @@ fn make_test_grid() -> BuildGridContext {
.add_empty_row() .add_empty_row()
.build() .build()
} }
pub fn make_date_cell_string(s: &str) -> String {
serde_json::to_string(&DateCellContentChangeset {
date: Some(s.to_string()),
time: None,
})
.unwrap()
}

View File

@ -1,72 +0,0 @@
use crate::grid::script::EditorScript::*;
use crate::grid::script::*;
use flowy_grid_data_model::entities::{
CreateGridFilterParams, CreateGridFilterPayload, GridLayoutType, GridSettingChangesetParams, TextFilterCondition,
};
#[tokio::test]
async fn grid_setting_create_text_filter_test() {
let test = GridEditorTest::new().await;
let field_rev = test.text_field();
let condition = TextFilterCondition::TextIsEmpty as i32;
let scripts = vec![
InsertGridTableFilter {
payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition,
content: Some("abc".to_owned()),
},
},
AssertTableFilterCount { count: 1 },
];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
#[should_panic]
async fn grid_setting_create_text_filter_panic_test() {
let test = GridEditorTest::new().await;
let field_rev = test.text_field();
let scripts = vec![InsertGridTableFilter {
payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition: 20, // Invalid condition type
content: Some("abc".to_owned()),
},
}];
GridEditorTest::new().await.run_scripts(scripts).await;
}
#[tokio::test]
async fn grid_setting_delete_text_filter_test() {
let mut test = GridEditorTest::new().await;
let field_rev = test.text_field();
let condition = TextFilterCondition::TextIsEmpty as i32;
let scripts = vec![
InsertGridTableFilter {
payload: CreateGridFilterPayload {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition,
content: Some("abc".to_owned()),
},
},
AssertTableFilterCount { count: 1 },
];
test.run_scripts(scripts).await;
let filter = test.grid_filters().await.pop().unwrap();
test.run_scripts(vec![
DeleteGridTableFilter { filter_id: filter.id },
AssertTableFilterCount { count: 0 },
])
.await;
}
#[tokio::test]
async fn grid_setting_sort_test() {}

View File

@ -3,7 +3,7 @@ use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
use flowy_error_code::ErrorCode; use flowy_error_code::ErrorCode;
use crate::entities::FieldType; use crate::entities::FieldType;
use crate::revision::GridFilterRevision; use crate::revision::{FieldRevision, GridFilterRevision};
use std::convert::TryInto; use std::convert::TryInto;
#[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)] #[derive(Eq, PartialEq, ProtoBuf, Debug, Default, Clone)]
@ -53,6 +53,18 @@ pub struct CreateGridFilterPayload {
pub content: Option<String>, pub content: Option<String>,
} }
impl CreateGridFilterPayload {
#[allow(dead_code)]
pub fn new<T: Into<i32>>(field_rev: &FieldRevision, condition: T, content: Option<String>) -> Self {
Self {
field_id: field_rev.id.clone(),
field_type: field_rev.field_type.clone(),
condition: condition.into(),
content,
}
}
}
pub struct CreateGridFilterParams { pub struct CreateGridFilterParams {
pub field_id: String, pub field_id: String,
pub field_type: FieldType, pub field_type: FieldType,
@ -113,6 +125,11 @@ pub enum TextFilterCondition {
TextIsEmpty = 6, TextIsEmpty = 6,
TextIsNotEmpty = 7, TextIsNotEmpty = 7,
} }
impl std::convert::Into<i32> for TextFilterCondition {
fn into(self) -> i32 {
self as i32
}
}
impl std::default::Default for TextFilterCondition { impl std::default::Default for TextFilterCondition {
fn default() -> Self { fn default() -> Self {
@ -173,6 +190,11 @@ impl std::default::Default for NumberFilterCondition {
} }
} }
impl std::convert::Into<i32> for NumberFilterCondition {
fn into(self) -> i32 {
self as i32
}
}
impl std::convert::TryFrom<u8> for NumberFilterCondition { impl std::convert::TryFrom<u8> for NumberFilterCondition {
type Error = ErrorCode; type Error = ErrorCode;
@ -218,6 +240,12 @@ pub enum SelectOptionCondition {
OptionIsNotEmpty = 3, OptionIsNotEmpty = 3,
} }
impl std::convert::Into<i32> for SelectOptionCondition {
fn into(self) -> i32 {
self as i32
}
}
impl std::default::Default for SelectOptionCondition { impl std::default::Default for SelectOptionCondition {
fn default() -> Self { fn default() -> Self {
SelectOptionCondition::OptionIs SelectOptionCondition::OptionIs

View File

@ -359,7 +359,12 @@ impl GridRevisionPad {
is_changed = Some(()) is_changed = Some(())
} }
if let Some(delete_filter_id) = changeset.delete_filter {
match grid_rev.setting.filter.get_mut(&layout_rev) {
Some(filters) => filters.retain(|filter| filter.id != delete_filter_id),
None => {}
}
}
if let Some(params) = changeset.insert_group { if let Some(params) = changeset.insert_group {
let rev = GridGroupRevision { let rev = GridGroupRevision {
id: gen_grid_group_id(), id: gen_grid_group_id(),
@ -376,7 +381,12 @@ impl GridRevisionPad {
is_changed = Some(()) is_changed = Some(())
} }
if let Some(delete_group_id) = changeset.delete_group {
match grid_rev.setting.group.get_mut(&layout_rev) {
Some(groups) => groups.retain(|group| group.id != delete_group_id),
None => {}
}
}
if let Some(sort) = changeset.insert_sort { if let Some(sort) = changeset.insert_sort {
let rev = GridSortRevision { let rev = GridSortRevision {
id: gen_grid_sort_id(), id: gen_grid_sort_id(),
@ -386,12 +396,18 @@ impl GridRevisionPad {
grid_rev grid_rev
.setting .setting
.sort .sort
.entry(layout_rev) .entry(layout_rev.clone())
.or_insert_with(std::vec::Vec::new) .or_insert_with(std::vec::Vec::new)
.push(rev); .push(rev);
is_changed = Some(()) is_changed = Some(())
} }
if let Some(delete_sort_id) = changeset.delete_sort {
match grid_rev.setting.sort.get_mut(&layout_rev) {
Some(sorts) => sorts.retain(|sort| sort.id != delete_sort_id),
None => {}
}
}
Ok(is_changed) Ok(is_changed)
}) })
} }