Merge pull request #1180 from AppFlowy-IO/refactor/text_type_option_test

refactor: text type option test
This commit is contained in:
Nathan.fooo 2022-09-27 15:49:11 +08:00 committed by GitHub
commit e44b0a4bb8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 99 deletions

View File

@ -210,7 +210,7 @@ impl ViewController {
let index = views
.iter()
.position(|view| view.id == view_id)
.and_then(|index| Some(index as i32));
.map(|index| index as i32);
Ok(DeletedViewPB {
view_id: view_id.clone(),
index,

View File

@ -29,9 +29,16 @@ pub trait CellDisplayable<CD> {
// CD: Short for CellData. This type is the type return by apply_changeset function.
// CS: Short for Changeset. Parse the string into specific Changeset type.
pub trait CellDataOperation<CD, CS> {
/// The cell_data is able to parse into the specific data if CD impl the FromCellData trait.
/// For example:
/// URLCellData, DateCellData. etc.
/// Decode the cell data into `CD` that is certain type of data.
///
/// Each `CD` type represents as a specific field type data. For example:
/// FieldType::URL => URLCellData
/// FieldType::Date=> DateCellData
///
/// `decoded_field_type`: the field type of the cell data
///
/// Returns the error if the cell data can't be parsed into `CD`.
///
fn decode_cell_data(
&self,
cell_data: CellData<CD>,
@ -82,7 +89,7 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData, Error = FlowyError> + Debug>
Ok(any_cell_data) => {
let AnyCellData { data, field_type } = any_cell_data;
let to_field_type = field_rev.ty.into();
match try_decode_cell_data(data.into(), field_rev, &field_type, &to_field_type) {
match try_decode_cell_data(data.into(), &field_type, &to_field_type, field_rev) {
Ok(cell_bytes) => cell_bytes,
Err(e) => {
tracing::error!("Decode cell data failed, {:?}", e);
@ -99,37 +106,42 @@ pub fn decode_any_cell_data<T: TryInto<AnyCellData, Error = FlowyError> + Debug>
}
}
/// Use the `to_field_type`'s TypeOption to parse the cell data into `from_field_type`'s data.
///
/// Each `FieldType` has its corresponding `TypeOption` that implements the `CellDisplayable`
/// and `CellDataOperation` traits.
///
pub fn try_decode_cell_data(
cell_data: CellData<String>,
from_field_type: &FieldType,
to_field_type: &FieldType,
field_rev: &FieldRevision,
s_field_type: &FieldType,
t_field_type: &FieldType,
) -> FlowyResult<CellBytes> {
let cell_data = cell_data.try_into_inner()?;
let get_cell_data = || {
let field_type: FieldTypeRevision = t_field_type.into();
let data = match t_field_type {
let field_type: FieldTypeRevision = to_field_type.into();
let data = match to_field_type {
FieldType::RichText => field_rev
.get_type_option::<RichTextTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::Number => field_rev
.get_type_option::<NumberTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::DateTime => field_rev
.get_type_option::<DateTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::SingleSelect => field_rev
.get_type_option::<SingleSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::MultiSelect => field_rev
.get_type_option::<MultiSelectTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::Checkbox => field_rev
.get_type_option::<CheckboxTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
FieldType::URL => field_rev
.get_type_option::<URLTypeOptionPB>(field_type)?
.decode_cell_data(cell_data.into(), s_field_type, field_rev),
.decode_cell_data(cell_data.into(), from_field_type, field_rev),
};
Some(data)
};
@ -224,6 +236,12 @@ where
}
}
impl std::convert::From<usize> for CellData<String> {
fn from(n: usize) -> Self {
CellData(Some(n.to_string()))
}
}
impl<T> std::convert::From<T> for CellData<T> {
fn from(val: T) -> Self {
CellData(Some(val))

View File

@ -1,3 +1,5 @@
#![allow(clippy::module_inception)]
mod text_tests;
mod text_type_option;
pub use text_type_option::*;

View File

@ -0,0 +1,49 @@
#[cfg(test)]
mod tests {
use crate::entities::FieldType;
use crate::services::cell::CellDataOperation;
use crate::services::field::FieldBuilder;
use crate::services::field::*;
// Test parser the cell data which field's type is FieldType::Date to cell data
// which field's type is FieldType::Text
#[test]
fn date_type_to_text_type() {
let type_option = RichTextTypeOptionPB::default();
let field_type = FieldType::DateTime;
let field_rev = FieldBuilder::from_field_type(&field_type).build();
assert_eq!(
type_option
.decode_cell_data(1647251762.into(), &field_type, &field_rev)
.unwrap()
.parser::<DateCellDataParser>()
.unwrap()
.date,
"Mar 14,2022".to_owned()
);
}
// Test parser the cell data which field's type is FieldType::SingleSelect to cell data
// which field's type is FieldType::Text
#[test]
fn single_select_to_text_type() {
let type_option = RichTextTypeOptionPB::default();
let field_type = FieldType::SingleSelect;
let done_option = SelectOptionPB::new("Done");
let option_id = done_option.id.clone();
let single_select = SingleSelectTypeOptionBuilder::default().add_option(done_option.clone());
let field_rev = FieldBuilder::new(single_select).build();
assert_eq!(
type_option
.decode_cell_data(option_id.into(), &field_type, &field_rev)
.unwrap()
.parser::<SelectOptionCellDataParser>()
.unwrap()
.select_options,
vec![done_option],
);
}
}

View File

@ -58,7 +58,7 @@ impl CellDataOperation<String, String> for RichTextTypeOptionPB {
|| decoded_field_type.is_multi_select()
|| decoded_field_type.is_number()
{
try_decode_cell_data(cell_data, field_rev, decoded_field_type, decoded_field_type)
try_decode_cell_data(cell_data, decoded_field_type, decoded_field_type, field_rev)
} else {
self.display_data(cell_data, decoded_field_type, field_rev)
}
@ -104,85 +104,3 @@ impl CellBytesParser for TextCellDataParser {
}
}
}
#[cfg(test)]
mod tests {
use crate::entities::FieldType;
use crate::services::cell::CellDataOperation;
use crate::services::field::FieldBuilder;
use crate::services::field::*;
#[test]
fn text_description_test() {
let type_option = RichTextTypeOptionPB::default();
// date
let field_type = FieldType::DateTime;
let date_time_field_rev = FieldBuilder::from_field_type(&field_type).build();
assert_eq!(
type_option
.decode_cell_data(1647251762.to_string().into(), &field_type, &date_time_field_rev)
.unwrap()
.parser::<DateCellDataParser>()
.unwrap()
.date,
"Mar 14,2022".to_owned()
);
// Single select
let done_option = SelectOptionPB::new("Done");
let done_option_id = done_option.id.clone();
let single_select = SingleSelectTypeOptionBuilder::default().add_option(done_option.clone());
let single_select_field_rev = FieldBuilder::new(single_select).build();
assert_eq!(
type_option
.decode_cell_data(
done_option_id.into(),
&FieldType::SingleSelect,
&single_select_field_rev
)
.unwrap()
.parser::<SelectOptionCellDataParser>()
.unwrap()
.select_options,
vec![done_option],
);
// Multiple select
let google_option = SelectOptionPB::new("Google");
let facebook_option = SelectOptionPB::new("Facebook");
let ids = vec![google_option.id.clone(), facebook_option.id.clone()].join(SELECTION_IDS_SEPARATOR);
let cell_data_changeset = SelectOptionCellChangeset::from_insert(&ids).to_str();
let multi_select = MultiSelectTypeOptionBuilder::default()
.add_option(google_option.clone())
.add_option(facebook_option.clone());
let multi_select_field_rev = FieldBuilder::new(multi_select).build();
let multi_type_option = MultiSelectTypeOptionPB::from(&multi_select_field_rev);
let cell_data = multi_type_option
.apply_changeset(cell_data_changeset.into(), None)
.unwrap();
assert_eq!(
type_option
.decode_cell_data(cell_data.into(), &FieldType::MultiSelect, &multi_select_field_rev)
.unwrap()
.parser::<SelectOptionCellDataParser>()
.unwrap()
.select_options,
vec![google_option, facebook_option]
);
//Number
let number = NumberTypeOptionBuilder::default().set_format(NumberFormat::USD);
let number_field_rev = FieldBuilder::new(number).build();
assert_eq!(
type_option
.decode_cell_data("18443".to_owned().into(), &FieldType::Number, &number_field_rev)
.unwrap()
.to_string(),
"$18,443".to_owned()
);
}
}